Skip to content

Commit 45fe90f

Browse files
committed
helm(e2e): test helm plugin integration
this will test the usage and impact to an existing project by the kubebuilder edit command for the helm plugin. Signed-off-by: Mario Constanti <[email protected]>
1 parent 3074a10 commit 45fe90f

File tree

4 files changed

+252
-0
lines changed

4 files changed

+252
-0
lines changed

pkg/plugin/util/util_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,60 @@ var _ = Describe("Cover plugin util helpers", func() {
101101
Expect(lines).To(Equal([]string{"noemptylines"}))
102102
})
103103
})
104+
105+
Describe("HasFileContentWith", Ordered, func() {
106+
const (
107+
path = "testdata/PROJECT"
108+
content = `# Code generated by tool. DO NOT EDIT.
109+
# This file is used to track the info used to scaffold your project
110+
# and allow the plugins properly work.
111+
# More info: https://book.kubebuilder.io/reference/project-config.html
112+
domain: example.org
113+
layout:
114+
- go.kubebuilder.io/v4
115+
- helm.kubebuilder.io/v1-alpha
116+
plugins:
117+
helm.kubebuilder.io/v1-alpha: {}
118+
repo: github.com/example/repo
119+
version: "3"
120+
`
121+
)
122+
123+
BeforeAll(func() {
124+
err := os.MkdirAll("testdata", 0o755)
125+
Expect(err).NotTo(HaveOccurred())
126+
127+
if _, err = os.Stat(path); os.IsNotExist(err) {
128+
err = os.WriteFile(path, []byte(content), 0o644)
129+
Expect(err).NotTo(HaveOccurred())
130+
}
131+
})
132+
133+
AfterAll(func() {
134+
err := os.RemoveAll("testdata")
135+
Expect(err).NotTo(HaveOccurred())
136+
})
137+
138+
It("should return true when file contains the expected content", func() {
139+
content := "repo: github.com/example/repo"
140+
found, err := HasFileContentWith(path, content)
141+
Expect(err).NotTo(HaveOccurred())
142+
Expect(found).To(BeTrue())
143+
})
144+
145+
It("should return true when file contains multiline expected content", func() {
146+
content := `plugins:
147+
helm.kubebuilder.io/v1-alpha: {}`
148+
found, err := HasFileContentWith(path, content)
149+
Expect(err).NotTo(HaveOccurred())
150+
Expect(found).To(BeTrue())
151+
})
152+
153+
It("should return false when file does not contain the expected content", func() {
154+
content := "nonExistentContent"
155+
found, err := HasFileContentWith(path, content)
156+
Expect(err).NotTo(HaveOccurred())
157+
Expect(found).To(BeFalse())
158+
})
159+
})
104160
})

test/e2e/helm/e2e_suite_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
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+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package helm
15+
16+
import (
17+
"fmt"
18+
"testing"
19+
20+
. "github.com/onsi/ginkgo/v2"
21+
. "github.com/onsi/gomega"
22+
)
23+
24+
// Run e2e tests using the Ginkgo runner.
25+
func TestE2E(t *testing.T) {
26+
RegisterFailHandler(Fail)
27+
_, _ = fmt.Fprintf(GinkgoWriter, "Starting helm plugin kubebuilder suite\n")
28+
RunSpecs(t, "Kubebuilder helm plugin e2e suite")
29+
}

test/e2e/helm/generate_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package helm
18+
19+
import (
20+
"path/filepath"
21+
22+
pluginutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util"
23+
24+
. "github.com/onsi/ginkgo/v2"
25+
26+
. "github.com/onsi/gomega"
27+
28+
"sigs.k8s.io/kubebuilder/v4/test/e2e/utils"
29+
)
30+
31+
var _ = Describe("kubebuilder", func() {
32+
Context("plugin helm/v1-alpha", func() {
33+
var kbc *utils.TestContext
34+
35+
BeforeEach(func() {
36+
var err error
37+
kbc, err = utils.NewTestContext(pluginutil.KubebuilderBinName, "GO111MODULE=on")
38+
Expect(err).NotTo(HaveOccurred())
39+
Expect(kbc.Prepare()).To(Succeed())
40+
})
41+
42+
AfterEach(func() {
43+
kbc.Destroy()
44+
})
45+
46+
It("should extend a runnable project with helm plugin", func() {
47+
initTheProject(kbc)
48+
generateProject(kbc)
49+
})
50+
51+
It("should extend a runnable project with helm plugin and webhooks", func() {
52+
initTheProject(kbc)
53+
generateProject(kbc)
54+
extendProjectWithWebhooks(kbc)
55+
56+
By("re-edit the project after creating webhooks")
57+
err := kbc.Edit(
58+
"--plugins", "helm.kubebuilder.io/v1-alpha", "--force",
59+
)
60+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
61+
62+
fileContainsExpr, err := pluginutil.HasFileContentWith(
63+
filepath.Join(kbc.Dir, "dist", "chart", "values.yaml"),
64+
`webhook:
65+
enable: true`)
66+
Expect(err).NotTo(HaveOccurred(), "Failed to read values.yaml file")
67+
Expect(fileContainsExpr).To(BeTrue(), "Failed to get enabled webhook value from values.yaml file")
68+
})
69+
70+
// Without --force, the webhooks should not be enabled in the values.yaml file.
71+
It("should extend a runnable project with helm plugin and webhooks but not running with --force", func() {
72+
initTheProject(kbc)
73+
generateProject(kbc)
74+
extendProjectWithWebhooks(kbc)
75+
76+
By("re-edit the project after creating webhooks without --force")
77+
err := kbc.Edit(
78+
"--plugins", "helm.kubebuilder.io/v1-alpha",
79+
)
80+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
81+
82+
fileContainsExpr, err := pluginutil.HasFileContentWith(
83+
filepath.Join(kbc.Dir, "dist", "chart", "values.yaml"),
84+
`webhook:
85+
enable: true`)
86+
Expect(err).NotTo(HaveOccurred(), "Failed to read values.yaml file")
87+
Expect(fileContainsExpr).To(BeFalse(), "Failed to get enabled webhook value from values.yaml file")
88+
})
89+
})
90+
})
91+
92+
// generateProject implements a helm/v1(-alpha) plugin project defined by a TestContext.
93+
func generateProject(kbc *utils.TestContext) {
94+
var err error
95+
96+
By("editing a project")
97+
err = kbc.Edit(
98+
"--plugins", "helm.kubebuilder.io/v1-alpha",
99+
)
100+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
101+
102+
fileContainsExpr, err := pluginutil.HasFileContentWith(
103+
filepath.Join(kbc.Dir, "PROJECT"),
104+
`helm.kubebuilder.io/v1-alpha: {}`)
105+
Expect(err).NotTo(HaveOccurred(), "Failed to read PROJECT file")
106+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find helm plugin in PROJECT file")
107+
108+
fileContainsExpr, err = pluginutil.HasFileContentWith(
109+
filepath.Join(kbc.Dir, "PROJECT"),
110+
"projectName: e2e-"+kbc.TestSuffix)
111+
Expect(err).NotTo(HaveOccurred(), "Failed to read PROJECT file")
112+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find projectName in PROJECT file")
113+
114+
fileContainsExpr, err = pluginutil.HasFileContentWith(
115+
filepath.Join(kbc.Dir, "dist", "chart", "Chart.yaml"),
116+
"name: e2e-"+kbc.TestSuffix)
117+
Expect(err).NotTo(HaveOccurred(), "Failed to read Chart.yaml file")
118+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find name in Chart.yaml file")
119+
120+
fileContainsExpr, err = pluginutil.HasFileContentWith(
121+
filepath.Join(kbc.Dir, "dist", "chart", "templates", "manager", "manager.yaml"),
122+
`metadata:
123+
name: e2e-`+kbc.TestSuffix)
124+
Expect(err).NotTo(HaveOccurred(), "Failed to read manager.yaml file")
125+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find name in helm template manager.yaml file")
126+
}
127+
128+
// extendProjectWithWebhooks is creating API and scaffolding webhooks in the project
129+
func extendProjectWithWebhooks(kbc *utils.TestContext) {
130+
By("creating API definition")
131+
err := kbc.CreateAPI(
132+
"--group", kbc.Group,
133+
"--version", kbc.Version,
134+
"--kind", kbc.Kind,
135+
"--namespaced",
136+
"--resource",
137+
"--controller",
138+
"--make=false",
139+
)
140+
Expect(err).NotTo(HaveOccurred(), "Failed to create API")
141+
142+
By("scaffolding mutating and validating webhooks")
143+
err = kbc.CreateWebhook(
144+
"--group", kbc.Group,
145+
"--version", kbc.Version,
146+
"--kind", kbc.Kind,
147+
"--defaulting",
148+
"--programmatic-validation",
149+
"--make=false",
150+
)
151+
Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook")
152+
153+
By("run make manifests")
154+
Expect(kbc.Make("manifests")).To(Succeed())
155+
}
156+
157+
// initTheProject initializes a project with the go/v4 plugin and sets the domain.
158+
func initTheProject(kbc *utils.TestContext) {
159+
By("initializing a project")
160+
err := kbc.Init(
161+
"--plugins", "go/v4",
162+
"--project-version", "3",
163+
"--domain", kbc.Domain,
164+
)
165+
Expect(err).NotTo(HaveOccurred(), "Failed to initialize project")
166+
}

test/e2e/setup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function test_cluster {
6565
kind load docker-image --name $KIND_CLUSTER busybox:1.36.1
6666

6767
go test $(dirname "$0")/grafana $flags -timeout 30m
68+
go test $(dirname "$0")/helm $flags -timeout 30m
6869
go test $(dirname "$0")/deployimage $flags -timeout 30m
6970
go test $(dirname "$0")/v4 $flags -timeout 30m
7071
go test $(dirname "$0")/alphagenerate $flags -timeout 30m

0 commit comments

Comments
 (0)