Skip to content

Commit e3ea024

Browse files
e2e tests: improve e2e tests and make test-e2e target
- Ensure that kind is installed and running before run the tests. Otherwise it will fail since we need to load the Manager(Operator) image - Add logic to skip the installation of CertManager and/or Prometheus via envvars. - Ensure that the promethues and certmanager are installed in the suite test instead of beafore each test - Ensure that the image is build and load in the suite instead instead for each test - Add more comments to clarify the purpose of the tests - Add TODO(user) to clarify that is expected action for the users to suplement and/or customize their e2e tests according to their needs
1 parent fb432c4 commit e3ea024

File tree

24 files changed

+864
-384
lines changed

24 files changed

+864
-384
lines changed

docs/book/src/cronjob-tutorial/testdata/project/Makefile

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,21 @@ vet: ## Run go vet against code.
6767
test: manifests generate fmt vet envtest ## Run tests.
6868
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out
6969

70-
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
71-
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
72-
test-e2e:
70+
# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'.
71+
# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally.
72+
# Prometheus and CertManager are installed by default; skip with:
73+
# - PROMETHEUS_INSTALL_SKIP=true
74+
# - CERT_MANAGER_INSTALL_SKIP=true
75+
.PHONY: test-e2e
76+
test-e2e: ## Run the e2e tests. Expected an isolated environment using Kind.
77+
@command -v kind >/dev/null 2>&1 || { \
78+
echo "Kind is not installed. Please install Kind manually."; \
79+
exit 1; \
80+
}
81+
@kind get clusters | grep -q 'kind' || { \
82+
echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \
83+
exit 1; \
84+
}
7385
go test ./test/e2e/ -v -ginkgo.v
7486

7587
.PHONY: lint

docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_suite_test.go

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,71 @@ package e2e
1818

1919
import (
2020
"fmt"
21+
"os"
22+
"os/exec"
2123
"testing"
2224

2325
. "github.com/onsi/ginkgo/v2"
2426
. "github.com/onsi/gomega"
27+
28+
"tutorial.kubebuilder.io/project/test/utils"
29+
)
30+
31+
var (
32+
// Optional Environment Variables:
33+
// - PROMETHEUS_INSTALL_SKIP=true: Skips Prometheus Operator installation during test setup.
34+
// - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup.
35+
// These variables are useful if Prometheus or CertManager is already installed, avoiding
36+
// re-installation and conflicts.
37+
skipPrometheusInstall = os.Getenv("PROMETHEUS_INSTALL_SKIP") == "true"
38+
skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true"
39+
40+
// projectImage is the name of the image which will be build and loaded
41+
// with the code source changes to be tested.
42+
projectImage = "example.com/project:v0.0.1"
2543
)
2644

27-
// Run e2e tests using the Ginkgo runner.
45+
// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated,
46+
// temporary environment to validate project changes with the the purposed to be used in CI jobs.
47+
// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs
48+
// CertManager and Prometheus.
2849
func TestE2E(t *testing.T) {
2950
RegisterFailHandler(Fail)
30-
_, _ = fmt.Fprintf(GinkgoWriter, "Starting project suite\n")
51+
_, _ = fmt.Fprintf(GinkgoWriter, "Starting project integration test suite\n")
3152
RunSpecs(t, "e2e suite")
3253
}
54+
55+
var _ = BeforeSuite(func() {
56+
By("building the manager(Operator) image")
57+
cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage))
58+
_, err := utils.Run(cmd)
59+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image")
60+
61+
// TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is
62+
// built and available before running the tests. Also, remove the following block.
63+
By("loading the manager(Operator) image on Kind")
64+
err = utils.LoadImageToKindClusterWithName(projectImage)
65+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind")
66+
67+
// Setup Prometheus and CertManager before the suite if not skipped
68+
if !skipPrometheusInstall {
69+
_, _ = fmt.Fprintf(GinkgoWriter, "Installing Prometheus Operator...\n")
70+
Expect(utils.InstallPrometheusOperator()).To(Succeed(), "Failed to install Prometheus Operator")
71+
}
72+
if !skipCertManagerInstall {
73+
_, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n")
74+
Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager")
75+
}
76+
})
77+
78+
var _ = AfterSuite(func() {
79+
// Teardown Prometheus and CertManager after the suite if not skipped
80+
if !skipPrometheusInstall {
81+
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling Prometheus Operator...\n")
82+
utils.UninstallPrometheusOperator()
83+
}
84+
if !skipCertManagerInstall {
85+
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n")
86+
utils.UninstallCertManager()
87+
}
88+
})

docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_test.go

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,63 +29,52 @@ import (
2929

3030
const namespace = "project-system"
3131

32+
// Define a set of end-to-end (e2e) tests to validate the behavior of the controller.
3233
var _ = Describe("controller", Ordered, func() {
34+
// Before running the tests, set up the environment by creating the namespace,
35+
// installing CRDs, and deploying the controller.
3336
BeforeAll(func() {
34-
By("installing prometheus operator")
35-
Expect(utils.InstallPrometheusOperator()).To(Succeed())
36-
37-
By("installing the cert-manager")
38-
Expect(utils.InstallCertManager()).To(Succeed())
39-
4037
By("creating manager namespace")
4138
cmd := exec.Command("kubectl", "create", "ns", namespace)
42-
_, _ = utils.Run(cmd)
39+
_, err := utils.Run(cmd)
40+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to create namespace")
41+
42+
By("installing CRDs")
43+
cmd = exec.Command("make", "install")
44+
_, err = utils.Run(cmd)
45+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to install CRDs")
46+
47+
By("deploying the controller-manager")
48+
cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectImage))
49+
_, err = utils.Run(cmd)
50+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to deploy the controller-manager")
4351
})
4452

53+
// After all tests have been executed, clean up by undeploying the controller, uninstalling CRDs,
54+
// and deleting the namespace.
4555
AfterAll(func() {
46-
By("uninstalling the Prometheus manager bundle")
47-
utils.UninstallPrometheusOperator()
56+
By("undeploying the controller-manager")
57+
cmd := exec.Command("make", "undeploy")
58+
_, _ = utils.Run(cmd)
4859

49-
By("uninstalling the cert-manager bundle")
50-
utils.UninstallCertManager()
60+
By("uninstalling CRDs")
61+
cmd = exec.Command("make", "uninstall")
62+
_, _ = utils.Run(cmd)
5163

5264
By("removing manager namespace")
53-
cmd := exec.Command("kubectl", "delete", "ns", namespace)
65+
cmd = exec.Command("kubectl", "delete", "ns", namespace)
5466
_, _ = utils.Run(cmd)
5567
})
5668

69+
// The Context block contains the actual tests that validate the operator's behavior.
5770
Context("Operator", func() {
5871
It("should run successfully", func() {
5972
var controllerPodName string
60-
var err error
61-
62-
// projectimage stores the name of the image used in the example
63-
var projectimage = "example.com/project:v0.0.1"
64-
65-
By("building the manager(Operator) image")
66-
cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectimage))
67-
_, err = utils.Run(cmd)
68-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
69-
70-
By("loading the the manager(Operator) image on Kind")
71-
err = utils.LoadImageToKindClusterWithName(projectimage)
72-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
73-
74-
By("installing CRDs")
75-
cmd = exec.Command("make", "install")
76-
_, err = utils.Run(cmd)
77-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
78-
79-
By("deploying the controller-manager")
80-
cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectimage))
81-
_, err = utils.Run(cmd)
82-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
8373

8474
By("validating that the controller-manager pod is running as expected")
8575
verifyControllerUp := func() error {
86-
// Get pod name
87-
88-
cmd = exec.Command("kubectl", "get",
76+
// Get the name of the controller-manager pod
77+
cmd := exec.Command("kubectl", "get",
8978
"pods", "-l", "control-plane=controller-manager",
9079
"-o", "go-template={{ range .items }}"+
9180
"{{ if not .metadata.deletionTimestamp }}"+
@@ -95,28 +84,31 @@ var _ = Describe("controller", Ordered, func() {
9584
)
9685

9786
podOutput, err := utils.Run(cmd)
98-
ExpectWithOffset(2, err).NotTo(HaveOccurred())
87+
ExpectWithOffset(2, err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information")
9988
podNames := utils.GetNonEmptyLines(string(podOutput))
10089
if len(podNames) != 1 {
101-
return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames))
90+
return fmt.Errorf("expected 1 controller pod running, but got %d", len(podNames))
10291
}
10392
controllerPodName = podNames[0]
10493
ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager"))
10594

106-
// Validate pod status
95+
// Validate the pod's status
10796
cmd = exec.Command("kubectl", "get",
10897
"pods", controllerPodName, "-o", "jsonpath={.status.phase}",
10998
"-n", namespace,
11099
)
111100
status, err := utils.Run(cmd)
112-
ExpectWithOffset(2, err).NotTo(HaveOccurred())
101+
ExpectWithOffset(2, err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod status")
113102
if string(status) != "Running" {
114103
return fmt.Errorf("controller pod in %s status", status)
115104
}
116105
return nil
117106
}
107+
// Repeatedly check if the controller-manager pod is running until it succeeds or times out.
118108
EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed())
119-
120109
})
110+
111+
// TODO(user): Customize the e2e test suite to include
112+
// additional scenarios specific to your project.
121113
})
122114
})

docs/book/src/getting-started/testdata/project/Makefile

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,21 @@ vet: ## Run go vet against code.
6363
test: manifests generate fmt vet envtest ## Run tests.
6464
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out
6565

66-
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
67-
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
68-
test-e2e:
66+
# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'.
67+
# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally.
68+
# Prometheus and CertManager are installed by default; skip with:
69+
# - PROMETHEUS_INSTALL_SKIP=true
70+
# - CERT_MANAGER_INSTALL_SKIP=true
71+
.PHONY: test-e2e
72+
test-e2e: ## Run the e2e tests. Expected an isolated environment using Kind.
73+
@command -v kind >/dev/null 2>&1 || { \
74+
echo "Kind is not installed. Please install Kind manually."; \
75+
exit 1; \
76+
}
77+
@kind get clusters | grep -q 'kind' || { \
78+
echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \
79+
exit 1; \
80+
}
6981
go test ./test/e2e/ -v -ginkgo.v
7082

7183
.PHONY: lint

docs/book/src/getting-started/testdata/project/test/e2e/e2e_suite_test.go

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,71 @@ package e2e
1818

1919
import (
2020
"fmt"
21+
"os"
22+
"os/exec"
2123
"testing"
2224

2325
. "github.com/onsi/ginkgo/v2"
2426
. "github.com/onsi/gomega"
27+
28+
"example.com/memcached/test/utils"
29+
)
30+
31+
var (
32+
// Optional Environment Variables:
33+
// - PROMETHEUS_INSTALL_SKIP=true: Skips Prometheus Operator installation during test setup.
34+
// - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup.
35+
// These variables are useful if Prometheus or CertManager is already installed, avoiding
36+
// re-installation and conflicts.
37+
skipPrometheusInstall = os.Getenv("PROMETHEUS_INSTALL_SKIP") == "true"
38+
skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true"
39+
40+
// projectImage is the name of the image which will be build and loaded
41+
// with the code source changes to be tested.
42+
projectImage = "example.com/project:v0.0.1"
2543
)
2644

27-
// Run e2e tests using the Ginkgo runner.
45+
// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated,
46+
// temporary environment to validate project changes with the the purposed to be used in CI jobs.
47+
// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs
48+
// CertManager and Prometheus.
2849
func TestE2E(t *testing.T) {
2950
RegisterFailHandler(Fail)
30-
_, _ = fmt.Fprintf(GinkgoWriter, "Starting project suite\n")
51+
_, _ = fmt.Fprintf(GinkgoWriter, "Starting project integration test suite\n")
3152
RunSpecs(t, "e2e suite")
3253
}
54+
55+
var _ = BeforeSuite(func() {
56+
By("building the manager(Operator) image")
57+
cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage))
58+
_, err := utils.Run(cmd)
59+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image")
60+
61+
// TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is
62+
// built and available before running the tests. Also, remove the following block.
63+
By("loading the manager(Operator) image on Kind")
64+
err = utils.LoadImageToKindClusterWithName(projectImage)
65+
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind")
66+
67+
// Setup Prometheus and CertManager before the suite if not skipped
68+
if !skipPrometheusInstall {
69+
_, _ = fmt.Fprintf(GinkgoWriter, "Installing Prometheus Operator...\n")
70+
Expect(utils.InstallPrometheusOperator()).To(Succeed(), "Failed to install Prometheus Operator")
71+
}
72+
if !skipCertManagerInstall {
73+
_, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n")
74+
Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager")
75+
}
76+
})
77+
78+
var _ = AfterSuite(func() {
79+
// Teardown Prometheus and CertManager after the suite if not skipped
80+
if !skipPrometheusInstall {
81+
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling Prometheus Operator...\n")
82+
utils.UninstallPrometheusOperator()
83+
}
84+
if !skipCertManagerInstall {
85+
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n")
86+
utils.UninstallCertManager()
87+
}
88+
})

0 commit comments

Comments
 (0)