diff --git a/e2e/e2e_common.go b/e2e/e2e_common.go index 4482c876c..515b7238a 100644 --- a/e2e/e2e_common.go +++ b/e2e/e2e_common.go @@ -17,6 +17,7 @@ package e2e import ( "context" "fmt" + "os" "reflect" "strings" "time" @@ -66,6 +67,11 @@ var ( // ReportAfterEach dumps detailed state for each tracked resource then clears // the list. resourcesUnderTest []client.Object + + // specDiagnostics stores per-spec diagnostic output keyed by spec text. + // ReportAfterEach populates it on failure; ReportAfterSuite reads it to + // append diagnostics to the JUnit failure message. + specDiagnostics = map[string]string{} ) func init() { @@ -113,16 +119,16 @@ func trackResource(obj client.Object) { resourcesUnderTest = append(resourcesUnderTest, obj) } -// dumpTrackedResources writes detailed diagnostics for each tracked resource -// to GinkgoWriter. For each resource it fetches current state, marshals it as +// collectTrackedResourceDiagnostics builds a diagnostics string for each +// tracked resource. For each resource it fetches current state, marshals it as // YAML, and lists events specific to that object. It also dumps all // AWSMachineTemplates (on AWS) and all events in both namespaces. // Best-effort: panics are recovered and individual errors are logged without // aborting the dump. -func dumpTrackedResources() { +func collectTrackedResourceDiagnostics() string { defer func() { if r := recover(); r != nil { - GinkgoWriter.Printf("WARNING: dumpTrackedResources panicked: %v\n", r) + fmt.Fprintf(os.Stderr, "WARNING: collectTrackedResourceDiagnostics panicked: %v\n", r) } }() @@ -141,7 +147,7 @@ func dumpTrackedResources() { buf.WriteString("\n=== End Test Failure Diagnostics ===\n") - GinkgoWriter.Print(buf.String()) + return buf.String() } func dumpSingleResource(buf *strings.Builder, obj client.Object) { diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index 491176931..4afecd7d4 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -36,7 +36,8 @@ var _ = BeforeSuite(func() { var _ = ReportAfterEach(func(report SpecReport) { if report.Failed() { - dumpTrackedResources() + diag := collectTrackedResourceDiagnostics() + specDiagnostics[report.LeafNodeLocation.String()] = diag } resourcesUnderTest = nil @@ -58,20 +59,15 @@ var _ = ReportAfterSuite("junit with diagnostics", func(report Report) { return } - // Append GinkgoWriter output (which contains our tracked resource dump) - // to the failure description so it appears in the element of - // the JUnit XML, which is what Spyglass renders by default. for i := range report.SpecReports { sr := &report.SpecReports[i] if !sr.Failed() { continue } - if sr.CapturedGinkgoWriterOutput == "" { - continue + if diag, ok := specDiagnostics[sr.LeafNodeLocation.String()]; ok { + sr.Failure.Message += "\n\n" + diag } - - sr.Failure.Message += "\n\n" + sr.CapturedGinkgoWriterOutput } dst := filepath.Join(artifactDir, "junit_cluster_capi_operator.xml")