-
Notifications
You must be signed in to change notification settings - Fork 1.6k
📖 add e2e test to validate webhook conversion between versions in the tutorials #5069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,6 +26,7 @@ import ( | |||||||||||||||||||||||||
| "os/exec" | ||||||||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||||||||
| "time" | ||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| . "github.com/onsi/ginkgo/v2" | ||||||||||||||||||||||||||
| . "github.com/onsi/gomega" | ||||||||||||||||||||||||||
|
|
@@ -97,6 +98,12 @@ var _ = Describe("Manager", Ordered, func() { | |||||||||||||||||||||||||
| // After each test, check for failures and collect logs, events, | ||||||||||||||||||||||||||
| // and pod descriptions for debugging. | ||||||||||||||||||||||||||
| AfterEach(func() { | ||||||||||||||||||||||||||
| By("Cleaning up test CronJob resources") | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "delete", "-f", "config/samples/batch_v1_cronjob.yaml", "-n", namespace, "--ignore-not-found=true") | ||||||||||||||||||||||||||
| _, _ = utils.Run(cmd) | ||||||||||||||||||||||||||
| cmd = exec.Command("kubectl", "delete", "-f", "config/samples/batch_v2_cronjob.yaml", "-n", namespace, "--ignore-not-found=true") | ||||||||||||||||||||||||||
| _, _ = utils.Run(cmd) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| specReport := CurrentSpecReport() | ||||||||||||||||||||||||||
| if specReport.Failed() { | ||||||||||||||||||||||||||
| By("Fetching controller manager pod logs") | ||||||||||||||||||||||||||
|
|
@@ -331,6 +338,79 @@ var _ = Describe("Manager", Ordered, func() { | |||||||||||||||||||||||||
| // fmt.Sprintf(`controller_runtime_reconcile_total{controller="%s",result="success"} 1`, | ||||||||||||||||||||||||||
| // strings.ToLower(<Kind>), | ||||||||||||||||||||||||||
| // )) | ||||||||||||||||||||||||||
| It("should successfully convert between v1 and v2 versions", func() { | ||||||||||||||||||||||||||
| By("waiting for the webhook service to be ready") | ||||||||||||||||||||||||||
| Eventually(func(g Gomega) { | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "get", "endpoints", "-n", namespace, | ||||||||||||||||||||||||||
| "-l", "control-plane=controller-manager", | ||||||||||||||||||||||||||
| "-o", "jsonpath={.items[0].subsets[0].addresses[0].ip}") | ||||||||||||||||||||||||||
| output, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| g.Expect(err).NotTo(HaveOccurred(), "Failed to get webhook service endpoints") | ||||||||||||||||||||||||||
| g.Expect(strings.TrimSpace(output)).NotTo(BeEmpty(), "Webhook endpoint should have an IP") | ||||||||||||||||||||||||||
| }, time.Minute, time.Second).Should(Succeed()) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| By("creating a v1 CronJob with a specific schedule") | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "apply", "-f", "config/samples/batch_v1_cronjob.yaml", "-n", namespace) | ||||||||||||||||||||||||||
| _, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| Expect(err).NotTo(HaveOccurred(), "Failed to create v1 CronJob") | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| By("waiting for the v1 CronJob to be created") | ||||||||||||||||||||||||||
| Eventually(func(g Gomega) { | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "get", "cronjob.batch.tutorial.kubebuilder.io", "cronjob-sample", "-n", namespace) | ||||||||||||||||||||||||||
| output, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||
| // Log controller logs on failure for debugging | ||||||||||||||||||||||||||
| logCmd := exec.Command("kubectl", "logs", "-l", "control-plane=controller-manager", "-n", namespace, "--tail=50") | ||||||||||||||||||||||||||
| logs, _ := utils.Run(logCmd) | ||||||||||||||||||||||||||
| _, _ = fmt.Fprintf(GinkgoWriter, "Controller logs when CronJob not found:\n%s\n", logs) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| g.Expect(err).NotTo(HaveOccurred(), "v1 CronJob should exist, output: "+output) | ||||||||||||||||||||||||||
| }, time.Minute, time.Second).Should(Succeed()) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| By("fetching the v1 CronJob and verifying the schedule format") | ||||||||||||||||||||||||||
| cmd = exec.Command("kubectl", "get", "cronjob.v1.batch.tutorial.kubebuilder.io", "cronjob-sample", | ||||||||||||||||||||||||||
| "-n", namespace, "-o", "jsonpath={.spec.schedule}") | ||||||||||||||||||||||||||
| v1Schedule, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| Expect(err).NotTo(HaveOccurred(), "Failed to get v1 CronJob schedule") | ||||||||||||||||||||||||||
| Expect(strings.TrimSpace(v1Schedule)).To(Equal("*/1 * * * *"), | ||||||||||||||||||||||||||
| "v1 schedule should be in cron format") | ||||||||||||||||||||||||||
|
Comment on lines
+371
to
+376
|
||||||||||||||||||||||||||
| cmd = exec.Command("kubectl", "get", "cronjob.v1.batch.tutorial.kubebuilder.io", "cronjob-sample", | |
| "-n", namespace, "-o", "jsonpath={.spec.schedule}") | |
| v1Schedule, err := utils.Run(cmd) | |
| Expect(err).NotTo(HaveOccurred(), "Failed to get v1 CronJob schedule") | |
| Expect(strings.TrimSpace(v1Schedule)).To(Equal("*/1 * * * *"), | |
| "v1 schedule should be in cron format") | |
| cmd = exec.Command("kubectl", "get", "cronjob.v1.batch.tutorial.kubebuilder.io", "cronjob-sample", | |
| "-n", namespace, "-o", "jsonpath={.spec.schedule}") | |
| v1Schedule, err := utils.Run(cmd) | |
| Expect(err).NotTo(HaveOccurred(), "Failed to get v1 CronJob schedule") | |
| Expect(strings.TrimSpace(v1Schedule)).To(Equal("*/1 * * * *"), | |
| "v1 schedule should be in cron format") |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -111,6 +111,7 @@ func (sp *Sample) UpdateTutorial() { | |||||||||||||||||||||||||
| sp.updateConversionFiles() | ||||||||||||||||||||||||||
| sp.updateSampleV2() | ||||||||||||||||||||||||||
| sp.updateMain() | ||||||||||||||||||||||||||
| sp.updateE2EWebhookConversion() | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| func (sp *Sample) updateCronjobV1DueForce() { | ||||||||||||||||||||||||||
|
|
@@ -790,3 +791,119 @@ func (sp *Sample) CodeGen() { | |||||||||||||||||||||||||
| err = sp.ctx.EditHelmPlugin() | ||||||||||||||||||||||||||
| hackutils.CheckError("Failed to enable helm plugin", err) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const webhookConversionE2ETest = ` | ||||||||||||||||||||||||||
| It("should successfully convert between v1 and v2 versions", func() { | ||||||||||||||||||||||||||
| By("waiting for the webhook service to be ready") | ||||||||||||||||||||||||||
| Eventually(func(g Gomega) { | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "get", "endpoints", "-n", namespace, | ||||||||||||||||||||||||||
| "-l", "control-plane=controller-manager", | ||||||||||||||||||||||||||
| "-o", "jsonpath={.items[0].subsets[0].addresses[0].ip}") | ||||||||||||||||||||||||||
| output, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| g.Expect(err).NotTo(HaveOccurred(), "Failed to get webhook service endpoints") | ||||||||||||||||||||||||||
| g.Expect(strings.TrimSpace(output)).NotTo(BeEmpty(), "Webhook endpoint should have an IP") | ||||||||||||||||||||||||||
| }, time.Minute, time.Second).Should(Succeed()) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| By("creating a v1 CronJob with a specific schedule") | ||||||||||||||||||||||||||
| cmd := exec.Command("kubectl", "apply", "-f", "config/samples/batch_v1_cronjob.yaml", "-n", namespace) | ||||||||||||||||||||||||||
| _, err := utils.Run(cmd) | ||||||||||||||||||||||||||
| Expect(err).NotTo(HaveOccurred(), "Failed to create v1 CronJob") | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| By("waiting for the v1 CronJob to be created") | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
| By("waiting for the v1 CronJob to be created") | |
| By("waiting for the v1 CronJob to be created") |
Copilot
AI
Oct 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation in the generated test template: lines 826-831 use an extra level of indentation. The code following the By statement should be indented with three tabs, matching the pattern used in other By blocks.
| cmd = exec.Command("kubectl", "get", "cronjob.v1.batch.tutorial.kubebuilder.io", "cronjob-sample", | |
| "-n", namespace, "-o", "jsonpath={.spec.schedule}") | |
| v1Schedule, err := utils.Run(cmd) | |
| Expect(err).NotTo(HaveOccurred(), "Failed to get v1 CronJob schedule") | |
| Expect(strings.TrimSpace(v1Schedule)).To(Equal("*/1 * * * *"), | |
| "v1 schedule should be in cron format") | |
| cmd = exec.Command("kubectl", "get", "cronjob.v1.batch.tutorial.kubebuilder.io", "cronjob-sample", | |
| "-n", namespace, "-o", "jsonpath={.spec.schedule}") | |
| v1Schedule, err := utils.Run(cmd) | |
| Expect(err).NotTo(HaveOccurred(), "Failed to get v1 CronJob schedule") | |
| Expect(strings.TrimSpace(v1Schedule)).To(Equal("*/1 * * * *"), | |
| "v1 schedule should be in cron format") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation: this
Bystatement uses tabs instead of the expected tab+spaces pattern. It should be indented with three tabs to align with the surrounding code within theItblock.