Skip to content

Commit 9b54fee

Browse files
Add testdata generation for hybrid operator and sanity check to CI (#105)
* [tests] add testdata generation This commit makes the following changes: 1. Add testdata generation logic 2. Move the helm charts for unit tests in their respective repository 3. Modify main.go to build a separate binary containing the specified plugins needed to scaffold a hybrid project. * [Makefile] cleanup makefile This commit cleans up makefile to remove previous test which clones and generates hybrid sample. * [ci] Add test-sanity to CI This commit adds test-sanity to ci, so that we are sure that any changes in scaffolding is picked up. Signed-off-by: varshaprasad96 <[email protected]> * [Makefile] Add makefile target to fix lint Signed-off-by: varshaprasad96 <[email protected]>
1 parent c5ecef2 commit 9b54fee

File tree

102 files changed

+556
-995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+556
-995
lines changed

.github/workflows/ci.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Set up Go 1.x
1818
uses: actions/setup-go@v2
1919
with:
20-
go-version: ~1.16
20+
go-version: ~1.17
2121
id: go
2222

2323
- name: Check out code into the Go module directory
@@ -40,6 +40,9 @@ jobs:
4040

4141
- name: Test
4242
run: make test
43+
44+
- name: Test Sanity
45+
run: make test-sanity
4346

4447
- uses: shogo82148/actions-goveralls@v1
4548
with:

.github/workflows/deploy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Install Go
2929
uses: actions/setup-go@v2
3030
with:
31-
go-version: ~1.16
31+
go-version: ~1.17
3232

3333
- name: Create release
3434
run: |

Makefile

+14-22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ TOOLS_BIN_DIR=$(TOOLS_DIR)/bin
2525
SCRIPTS_DIR=$(TOOLS_DIR)/scripts
2626
export PATH := $(BUILD_DIR):$(TOOLS_BIN_DIR):$(SCRIPTS_DIR):$(PATH)
2727

28+
##@ Development
29+
30+
.PHONY: generate
31+
generate: build # Generate CLI docs and samples
32+
rm -rf testdata/
33+
go run ./hack/generate/samples/generate_testdata.go
34+
go generate ./...
35+
2836
.PHONY: all
2937
all: test lint build
3038

@@ -38,37 +46,21 @@ all: test lint build
3846
ENVTEST_VERSION = $(shell go list -m k8s.io/client-go | cut -d" " -f2 | sed 's/^v0\.\([[:digit:]]\+\)\.[[:digit:]]\+$$/1.\1.x/')
3947
TESTPKG ?= ./...
4048
# TODO: Modify this to use setup-envtest binary
41-
test: test-hybrid-plugin
49+
test: build
4250
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
4351
source <(setup-envtest use -p env $(ENVTEST_VERSION)) && go test -race -covermode atomic -coverprofile cover.out $(TESTPKG)
4452

45-
test-hybrid-plugin: remove-tmp build/operator-sdk
46-
mkdir -p tmp/test-hybrid-operator
47-
(cd tmp/test-hybrid-operator && \
48-
../../build/operator-sdk init --plugins hybrid --domain example.com --repo example.com/example/example-operator && \
49-
../../build/operator-sdk create api --plugins go.kubebuilder.io/v3 --group apps --version v1alpha1 --kind=MemcachedBackup --resource --controller && \
50-
../../build/operator-sdk create api --plugins helm.sdk.operatorframework.io/v1 --helm-chart=memcached --helm-chart-repo=https://charts.bitnami.com/bitnami --group apps --version v1alpha1 --kind=Memcached && \
51-
make docker-build)
53+
.PHONY: test-sanity
54+
test-sanity: generate fix ## Test repo formatting, linting, etc.
55+
go vet ./...
56+
$(SCRIPTS_DIR)/fetch golangci-lint 1.31.0 && $(TOOLS_BIN_DIR)/golangci-lint run
57+
git diff --exit-code # diff again to ensure other checks don't change repo
5258

5359
# Build manager binary
5460
.PHONY: build
5561
build:
5662
CGO_ENABLED=0 mkdir -p $(BUILD_DIR) && go build $(GO_BUILD_ARGS) -o $(BUILD_DIR) ./
5763

58-
# Incredibly fragile nad hopefully temporary build step for the SDK binary
59-
build/operator-sdk:
60-
mkdir -p tmp
61-
git clone https://github.com/operator-framework/operator-sdk.git tmp/operator-sdk-hybrid-patched
62-
cp hack/osdk.patch tmp/operator-sdk-hybrid-patched/
63-
(cd tmp/operator-sdk-hybrid-patched && git apply osdk.patch)
64-
sed -i".bak" "s|REPLACE_ME_WITH_PATH|$(shell pwd)|" tmp/operator-sdk-hybrid-patched/go.mod
65-
(cd tmp/operator-sdk-hybrid-patched && go mod tidy && make build/operator-sdk)
66-
mkdir -p build
67-
cp tmp/operator-sdk-hybrid-patched/build/operator-sdk ./build/operator-sdk
68-
69-
remove-tmp:
70-
rm -rf tmp/
71-
7264
# Run go fmt and go mod tidy, and check for clean git tree
7365
.PHONY: fix
7466
fix:
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2021 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"flag"
19+
"os"
20+
"path/filepath"
21+
22+
"github.com/operator-framework/helm-operator-plugins/hack/generate/samples/internal/hybrid"
23+
log "github.com/sirupsen/logrus"
24+
)
25+
26+
func main() {
27+
// binaryPath allow inform the binary that should be used.
28+
// By default it is helm-operator-plugins
29+
var binaryPath string
30+
31+
flag.StringVar(&binaryPath, "binaryPath", "bin/helm-operator-plugins", "Binary path that should be used")
32+
flag.Parse()
33+
34+
// Make the binary path absolute if pathed, for reproducibility and debugging purposes.
35+
if dir, _ := filepath.Split(binaryPath); dir != "" {
36+
tmp, err := filepath.Abs(binaryPath)
37+
if err != nil {
38+
log.Fatalf("Failed to make binary path %q absolute: %v", binaryPath, err)
39+
}
40+
binaryPath = tmp
41+
}
42+
43+
wd, err := os.Getwd()
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
48+
// samplesPath is the path where all samples should be generated
49+
samplesPath := filepath.Join(wd, "testdata")
50+
log.Infof("writing sample directories under %s", samplesPath)
51+
52+
log.Infof("creating Hybrid Memcached Sample")
53+
hybrid.GenerateMemcachedSamples(binaryPath, samplesPath)
54+
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2021 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package hybrid
16+
17+
import "path/filepath"
18+
19+
func GenerateMemcachedSamples(binaryPath, rootPath string) {
20+
GenerateMemcachedSample(binaryPath, filepath.Join(rootPath, "hybrid"))
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2020 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package hybrid
16+
17+
import (
18+
"os"
19+
"path/filepath"
20+
21+
log "github.com/sirupsen/logrus"
22+
23+
"github.com/operator-framework/helm-operator-plugins/hack/generate/samples/internal/pkg"
24+
)
25+
26+
// Memcached defines the Memcached Sample in Helm
27+
type Memcached struct {
28+
ctx *pkg.SampleContext
29+
}
30+
31+
// GenerateMemcachedSample will call all actions to create the directory and generate the sample
32+
// The Context to run the samples are not the same in the e2e test. In this way, note that it should NOT
33+
// be called in the e2e tests since it will call the Prepare() to set the sample context and generate the files
34+
// in the testdata directory. The e2e tests only ought to use the Run() method with the TestContext.
35+
func GenerateMemcachedSample(binaryPath, samplesPath string) {
36+
ctx, err := pkg.NewSampleContext(binaryPath, filepath.Join(samplesPath, "memcached-operator"),
37+
"GO111MODULE=on")
38+
pkg.CheckError("generating Helm memcached context", err)
39+
40+
memcached := Memcached{&ctx}
41+
memcached.Prepare()
42+
memcached.Run()
43+
}
44+
45+
// Prepare the Context for the Memcached Helm Sample
46+
// Note that sample directory will be re-created and the context data for the sample
47+
// will be set such as the domain and GVK.
48+
func (mh *Memcached) Prepare() {
49+
log.Infof("destroying directory for memcached helm samples")
50+
mh.ctx.Destroy()
51+
52+
log.Infof("creating directory")
53+
err := mh.ctx.Prepare()
54+
pkg.CheckError("creating directory", err)
55+
56+
log.Infof("setting domain and GVK")
57+
mh.ctx.Version = "v1alpha1"
58+
mh.ctx.Group = "cache"
59+
mh.ctx.Kind = "Memcached"
60+
}
61+
62+
func (mh *Memcached) Run() {
63+
// When we scaffold Helm based projects, it tries to use the discovery API of a Kubernetes
64+
// cluster to intelligently build the RBAC rules that the operator will require based on the
65+
// content of the helm chart.
66+
//
67+
// Here, we intentionally set KUBECONFIG to a broken value to ensure that operator-sdk will be
68+
// unable to reach a real cluster, and thus will generate a default RBAC rule set. This is
69+
// required to make Helm project generation idempotent because contributors and CI environments
70+
// can all have slightly different environments that can affect the content of the generated
71+
// role and cause sanity testing to fail.
72+
os.Setenv("KUBECONFIG", "broken_so_we_generate_static_default_rules")
73+
log.Infof("using init command and scaffolding the project")
74+
75+
err := mh.ctx.Init(
76+
"--plugins", "hybrid/v1-alpha",
77+
"--repo", "github.com/example/memcached-operator",
78+
)
79+
80+
pkg.CheckError("creating the project", err)
81+
82+
// TODO: Uncomment this code after helm plugin is migrated
83+
// err = mh.ctx.CreateAPI(
84+
// "--plugins", "helm.sdk.operatorframework.io/v1",
85+
// "--group", mh.ctx.Group,
86+
// "--version", mh.ctx.Version,
87+
// "--kind", mh.ctx.Kind,
88+
// )
89+
90+
// pkg.CheckError("creating helm api", err)
91+
92+
err = mh.ctx.CreateAPI(
93+
"--plugins", "base.go.kubebuilder.io/v3",
94+
"--group", mh.ctx.Group,
95+
"--version", mh.ctx.Version,
96+
"--kind", mh.ctx.Kind,
97+
"--resource", "--controller",
98+
)
99+
100+
pkg.CheckError("creating go api", err)
101+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2021 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pkg
16+
17+
import "github.com/operator-framework/helm-operator-plugins/internal/testutils"
18+
19+
// SampleContext represents the Context used to generate the samples
20+
type SampleContext struct {
21+
testutils.TestContext
22+
}
23+
24+
// NewSampleContext returns a SampleContext containing a new kubebuilder TestContext.
25+
func NewSampleContext(binary string, path string, env ...string) (s SampleContext, err error) {
26+
s.TestContext, err = testutils.NewPartialTestContext(binary, path, env...)
27+
return s, err
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2020 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pkg
16+
17+
import (
18+
"os"
19+
20+
log "github.com/sirupsen/logrus"
21+
)
22+
23+
// CheckError will exit with exit code 1 when err is not nil.
24+
func CheckError(msg string, err error) {
25+
if err != nil {
26+
log.Errorf("error %s: %s", msg, err)
27+
os.Exit(1)
28+
}
29+
}

0 commit comments

Comments
 (0)