Skip to content

Commit 333170b

Browse files
authored
Merge pull request #4175 from camilamacedo86/improve-e2e-error-failures
✨ (go/v4): e2e tests: add data collection on failures and code simplification
2 parents 95dab95 + fd683a6 commit 333170b

File tree

14 files changed

+392
-126
lines changed

14 files changed

+392
-126
lines changed

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

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const metricsServiceName = "project-controller-manager-metrics-service"
4343
const metricsRoleBindingName = "project-metrics-binding"
4444

4545
var _ = Describe("Manager", Ordered, func() {
46+
var controllerPodName string
47+
4648
// Before running the tests, set up the environment by creating the namespace,
4749
// installing CRDs, and deploying the controller.
4850
BeforeAll(func() {
@@ -82,12 +84,53 @@ var _ = Describe("Manager", Ordered, func() {
8284
_, _ = utils.Run(cmd)
8385
})
8486

87+
// After each test, check for failures and collect logs, events,
88+
// and pod descriptions for debugging.
89+
AfterEach(func() {
90+
specReport := CurrentSpecReport()
91+
if specReport.Failed() {
92+
By("Fetching controller manager pod logs")
93+
cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
94+
controllerLogs, err := utils.Run(cmd)
95+
if err == nil {
96+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Controller logs:\n %s", controllerLogs))
97+
} else {
98+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Controller logs: %s", err))
99+
}
100+
101+
By("Fetching Kubernetes events")
102+
cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp")
103+
eventsOutput, err := utils.Run(cmd)
104+
if err == nil {
105+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Kubernetes events:\n%s", eventsOutput))
106+
} else {
107+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Kubernetes events: %s", err))
108+
}
109+
110+
By("Fetching curl-metrics logs")
111+
cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
112+
metricsOutput, err := utils.Run(cmd)
113+
if err == nil {
114+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Metrics logs:\n %s", metricsOutput))
115+
} else {
116+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get curl-metrics logs: %s", err))
117+
}
118+
119+
By("Fetching controller manager pod description")
120+
cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace)
121+
podDescription, err := utils.Run(cmd)
122+
if err == nil {
123+
fmt.Println("Pod description:\n", podDescription)
124+
} else {
125+
fmt.Println("Failed to describe controller pod")
126+
}
127+
}
128+
})
129+
85130
SetDefaultEventuallyTimeout(2 * time.Minute)
86131
SetDefaultEventuallyPollingInterval(time.Second)
87132

88-
// The Context block contains the actual tests that validate the manager's behavior.
89133
Context("Manager", func() {
90-
var controllerPodName string
91134
It("should run successfully", func() {
92135
By("validating that the controller-manager pod is running as expected")
93136
verifyControllerUp := func(g Gomega) {
@@ -103,7 +146,7 @@ var _ = Describe("Manager", Ordered, func() {
103146

104147
podOutput, err := utils.Run(cmd)
105148
g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information")
106-
podNames := utils.GetNonEmptyLines(string(podOutput))
149+
podNames := utils.GetNonEmptyLines(podOutput)
107150
g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running")
108151
controllerPodName = podNames[0]
109152
g.Expect(controllerPodName).To(ContainSubstring("controller-manager"))
@@ -115,9 +158,8 @@ var _ = Describe("Manager", Ordered, func() {
115158
)
116159
output, err := utils.Run(cmd)
117160
g.Expect(err).NotTo(HaveOccurred())
118-
g.Expect(string(output)).To(BeEquivalentTo("Running"), "Incorrect controller-manager pod status")
161+
g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status")
119162
}
120-
// Repeatedly check if the controller-manager pod is running until it succeeds or times out.
121163
Eventually(verifyControllerUp).Should(Succeed())
122164
})
123165

@@ -150,7 +192,7 @@ var _ = Describe("Manager", Ordered, func() {
150192
cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace)
151193
output, err := utils.Run(cmd)
152194
g.Expect(err).NotTo(HaveOccurred())
153-
g.Expect(string(output)).To(ContainSubstring("8443"), "Metrics endpoint is not ready")
195+
g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready")
154196
}
155197
Eventually(verifyMetricsEndpointReady).Should(Succeed())
156198

@@ -159,7 +201,7 @@ var _ = Describe("Manager", Ordered, func() {
159201
cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
160202
output, err := utils.Run(cmd)
161203
g.Expect(err).NotTo(HaveOccurred())
162-
g.Expect(string(output)).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"),
204+
g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"),
163205
"Metrics server not yet started")
164206
}
165207
Eventually(verifyMetricsServerStarted).Should(Succeed())
@@ -181,7 +223,7 @@ var _ = Describe("Manager", Ordered, func() {
181223
"-n", namespace)
182224
output, err := utils.Run(cmd)
183225
g.Expect(err).NotTo(HaveOccurred())
184-
g.Expect(string(output)).To(Equal("Succeeded"), "curl pod in wrong status")
226+
g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status")
185227
}
186228
Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed())
187229

@@ -261,7 +303,6 @@ func serviceAccountToken() (string, error) {
261303
}
262304

263305
var out string
264-
var rawJson string
265306
verifyTokenCreation := func(g Gomega) {
266307
// Execute kubectl command to create the token
267308
cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf(
@@ -273,11 +314,9 @@ func serviceAccountToken() (string, error) {
273314
output, err := cmd.CombinedOutput()
274315
g.Expect(err).NotTo(HaveOccurred())
275316

276-
rawJson = string(output)
277-
278317
// Parse the JSON output to extract the token
279318
var token tokenRequest
280-
err = json.Unmarshal([]byte(rawJson), &token)
319+
err = json.Unmarshal([]byte(output), &token)
281320
g.Expect(err).NotTo(HaveOccurred())
282321

283322
out = token.Status.Token
@@ -293,9 +332,8 @@ func getMetricsOutput() string {
293332
cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
294333
metricsOutput, err := utils.Run(cmd)
295334
Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod")
296-
metricsOutputStr := string(metricsOutput)
297-
Expect(metricsOutputStr).To(ContainSubstring("< HTTP/1.1 200 OK"))
298-
return metricsOutputStr
335+
Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK"))
336+
return metricsOutput
299337
}
300338

301339
// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func warnError(err error) {
4141
}
4242

4343
// Run executes the provided command within this context
44-
func Run(cmd *exec.Cmd) ([]byte, error) {
44+
func Run(cmd *exec.Cmd) (string, error) {
4545
dir, _ := GetProjectDir()
4646
cmd.Dir = dir
4747

@@ -54,10 +54,10 @@ func Run(cmd *exec.Cmd) ([]byte, error) {
5454
_, _ = fmt.Fprintf(GinkgoWriter, "running: %s\n", command)
5555
output, err := cmd.CombinedOutput()
5656
if err != nil {
57-
return output, fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output))
57+
return string(output), fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output))
5858
}
5959

60-
return output, nil
60+
return string(output), nil
6161
}
6262

6363
// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics.

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

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const metricsServiceName = "project-controller-manager-metrics-service"
4343
const metricsRoleBindingName = "project-metrics-binding"
4444

4545
var _ = Describe("Manager", Ordered, func() {
46+
var controllerPodName string
47+
4648
// Before running the tests, set up the environment by creating the namespace,
4749
// installing CRDs, and deploying the controller.
4850
BeforeAll(func() {
@@ -82,12 +84,53 @@ var _ = Describe("Manager", Ordered, func() {
8284
_, _ = utils.Run(cmd)
8385
})
8486

87+
// After each test, check for failures and collect logs, events,
88+
// and pod descriptions for debugging.
89+
AfterEach(func() {
90+
specReport := CurrentSpecReport()
91+
if specReport.Failed() {
92+
By("Fetching controller manager pod logs")
93+
cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
94+
controllerLogs, err := utils.Run(cmd)
95+
if err == nil {
96+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Controller logs:\n %s", controllerLogs))
97+
} else {
98+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Controller logs: %s", err))
99+
}
100+
101+
By("Fetching Kubernetes events")
102+
cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp")
103+
eventsOutput, err := utils.Run(cmd)
104+
if err == nil {
105+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Kubernetes events:\n%s", eventsOutput))
106+
} else {
107+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get Kubernetes events: %s", err))
108+
}
109+
110+
By("Fetching curl-metrics logs")
111+
cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
112+
metricsOutput, err := utils.Run(cmd)
113+
if err == nil {
114+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Metrics logs:\n %s", metricsOutput))
115+
} else {
116+
_, _ = fmt.Fprintf(GinkgoWriter, fmt.Sprintf("Failed to get curl-metrics logs: %s", err))
117+
}
118+
119+
By("Fetching controller manager pod description")
120+
cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace)
121+
podDescription, err := utils.Run(cmd)
122+
if err == nil {
123+
fmt.Println("Pod description:\n", podDescription)
124+
} else {
125+
fmt.Println("Failed to describe controller pod")
126+
}
127+
}
128+
})
129+
85130
SetDefaultEventuallyTimeout(2 * time.Minute)
86131
SetDefaultEventuallyPollingInterval(time.Second)
87132

88-
// The Context block contains the actual tests that validate the manager's behavior.
89133
Context("Manager", func() {
90-
var controllerPodName string
91134
It("should run successfully", func() {
92135
By("validating that the controller-manager pod is running as expected")
93136
verifyControllerUp := func(g Gomega) {
@@ -103,7 +146,7 @@ var _ = Describe("Manager", Ordered, func() {
103146

104147
podOutput, err := utils.Run(cmd)
105148
g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information")
106-
podNames := utils.GetNonEmptyLines(string(podOutput))
149+
podNames := utils.GetNonEmptyLines(podOutput)
107150
g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running")
108151
controllerPodName = podNames[0]
109152
g.Expect(controllerPodName).To(ContainSubstring("controller-manager"))
@@ -115,9 +158,8 @@ var _ = Describe("Manager", Ordered, func() {
115158
)
116159
output, err := utils.Run(cmd)
117160
g.Expect(err).NotTo(HaveOccurred())
118-
g.Expect(string(output)).To(BeEquivalentTo("Running"), "Incorrect controller-manager pod status")
161+
g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status")
119162
}
120-
// Repeatedly check if the controller-manager pod is running until it succeeds or times out.
121163
Eventually(verifyControllerUp).Should(Succeed())
122164
})
123165

@@ -150,7 +192,7 @@ var _ = Describe("Manager", Ordered, func() {
150192
cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace)
151193
output, err := utils.Run(cmd)
152194
g.Expect(err).NotTo(HaveOccurred())
153-
g.Expect(string(output)).To(ContainSubstring("8443"), "Metrics endpoint is not ready")
195+
g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready")
154196
}
155197
Eventually(verifyMetricsEndpointReady).Should(Succeed())
156198

@@ -159,7 +201,7 @@ var _ = Describe("Manager", Ordered, func() {
159201
cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
160202
output, err := utils.Run(cmd)
161203
g.Expect(err).NotTo(HaveOccurred())
162-
g.Expect(string(output)).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"),
204+
g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"),
163205
"Metrics server not yet started")
164206
}
165207
Eventually(verifyMetricsServerStarted).Should(Succeed())
@@ -181,7 +223,7 @@ var _ = Describe("Manager", Ordered, func() {
181223
"-n", namespace)
182224
output, err := utils.Run(cmd)
183225
g.Expect(err).NotTo(HaveOccurred())
184-
g.Expect(string(output)).To(Equal("Succeeded"), "curl pod in wrong status")
226+
g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status")
185227
}
186228
Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed())
187229

@@ -223,7 +265,6 @@ func serviceAccountToken() (string, error) {
223265
}
224266

225267
var out string
226-
var rawJson string
227268
verifyTokenCreation := func(g Gomega) {
228269
// Execute kubectl command to create the token
229270
cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf(
@@ -235,11 +276,9 @@ func serviceAccountToken() (string, error) {
235276
output, err := cmd.CombinedOutput()
236277
g.Expect(err).NotTo(HaveOccurred())
237278

238-
rawJson = string(output)
239-
240279
// Parse the JSON output to extract the token
241280
var token tokenRequest
242-
err = json.Unmarshal([]byte(rawJson), &token)
281+
err = json.Unmarshal([]byte(output), &token)
243282
g.Expect(err).NotTo(HaveOccurred())
244283

245284
out = token.Status.Token
@@ -255,9 +294,8 @@ func getMetricsOutput() string {
255294
cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
256295
metricsOutput, err := utils.Run(cmd)
257296
Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod")
258-
metricsOutputStr := string(metricsOutput)
259-
Expect(metricsOutputStr).To(ContainSubstring("< HTTP/1.1 200 OK"))
260-
return metricsOutputStr
297+
Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK"))
298+
return metricsOutput
261299
}
262300

263301
// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func warnError(err error) {
4141
}
4242

4343
// Run executes the provided command within this context
44-
func Run(cmd *exec.Cmd) ([]byte, error) {
44+
func Run(cmd *exec.Cmd) (string, error) {
4545
dir, _ := GetProjectDir()
4646
cmd.Dir = dir
4747

@@ -54,10 +54,10 @@ func Run(cmd *exec.Cmd) ([]byte, error) {
5454
_, _ = fmt.Fprintf(GinkgoWriter, "running: %s\n", command)
5555
output, err := cmd.CombinedOutput()
5656
if err != nil {
57-
return output, fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output))
57+
return string(output), fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output))
5858
}
5959

60-
return output, nil
60+
return string(output), nil
6161
}
6262

6363
// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics.

0 commit comments

Comments
 (0)