e2e: trim junit report for Spyglass, avoid "open stdout"

Including the full information for successful tests makes the resulting XML
file too large for the 200GB limit in Spyglass when running large jobs (like
scale testing).

The original solution from https://github.com/kubernetes/kubernetes/pull/111627
broke JUnit reporting in other test suites, in particular
test/e2e_node. Keeping the code inside the framework ensures that all test
suites continue to have the JUnit reporting.

AfterReadingAllFlags is a good place to set this up because all test suites
using the test context are expected to call it before running tests and after
parsing flags.

Removing the ReportEntries added by ginkgo.By from all test reports usually
avoids the `system-err` part in the JUnit file, which in Spyglass avoids
the extra "open stdout" button.

Co-authored-by: Patrick Ohly <patrick.ohly@intel.com>
Co-authored-by: Dave Chen <dave.chen@arm.com>
This commit is contained in:
Dave Chen 2022-08-02 23:57:30 +08:00 committed by Patrick Ohly
parent 1a916f278b
commit c299a12cf2

View File

@ -30,6 +30,7 @@ import (
"time"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/ginkgo/v2/reporters"
"github.com/onsi/ginkgo/v2/types"
restclient "k8s.io/client-go/rest"
@ -356,14 +357,6 @@ func CreateGinkgoConfig() (types.SuiteConfig, types.ReporterConfig) {
suiteConfig.RandomizeAllSpecs = true
// Turn on verbose by default to get spec names
reporterConfig.Verbose = true
// Enable JUnit output to the result directory, but only if not already specified
// via -junit-report.
if reporterConfig.JUnitReport == "" && TestContext.ReportDir != "" {
// With Ginkgo v1, we used to write one file per parallel node. Now Ginkgo v2 automatically
// merges all results into a single file for us. The 01 suffix is kept in case that users
// expect files to be called "junit_<prefix><number>.xml".
reporterConfig.JUnitReport = path.Join(TestContext.ReportDir, "junit_"+TestContext.ReportPrefix+"01.xml")
}
// Disable skipped tests unless they are explicitly requested.
if len(suiteConfig.FocusStrings) == 0 && len(suiteConfig.SkipStrings) == 0 {
suiteConfig.SkipStrings = []string{`\[Flaky\]|\[Feature:.+\]`}
@ -561,4 +554,54 @@ func AfterReadingAllFlags(t *TestContextType) {
}
os.Exit(1)
}
if TestContext.ReportDir != "" {
ginkgo.ReportAfterSuite("Kubernetes e2e JUnit report", writeJUnitReport)
}
}
// writeJUnitReport generates a JUnit file in the e2e report directory that is
// shorter than the one normally written by `ginkgo --junit-report`. This is
// needed because the full report can become too large for tools like Spyglass
// (https://github.com/kubernetes/kubernetes/issues/111510).
//
// Users who want the full report can use `--junit-report`.
func writeJUnitReport(report ginkgo.Report) {
trimmedReport := report
trimmedReport.SpecReports = nil
for _, specReport := range report.SpecReports {
// Remove details for any spec that hasn't failed. In Prow,
// the test output captured in build-log.txt has all of this
// information, so we don't need it in the XML.
if specReport.State != types.SpecStateFailed {
specReport.CapturedGinkgoWriterOutput = ""
specReport.CapturedStdOutErr = ""
}
// Remove report entries generated by ginkgo.By("doing
// something") because those are not useful (just have the
// start time) and cause Spyglass to show an additional "open
// stdout" button with a summary of the steps, which usually
// doesn't help. We don't remove all entries because other
// measurements also get reported this way.
//
// Removing the report entries is okay because message text was
// already added to the test output when ginkgo.By was called.
reportEntries := specReport.ReportEntries
specReport.ReportEntries = nil
for _, reportEntry := range reportEntries {
if reportEntry.Name != "By Step" {
specReport.ReportEntries = append(specReport.ReportEntries, reportEntry)
}
}
trimmedReport.SpecReports = append(trimmedReport.SpecReports, specReport)
}
// With Ginkgo v1, we used to write one file per parallel node. Now
// Ginkgo v2 automatically merges all results into a report for us. The
// 01 suffix is kept in case that users expect files to be called
// "junit_<prefix><number>.xml".
junitReport := path.Join(TestContext.ReportDir, "junit_"+TestContext.ReportPrefix+"01.xml")
reporters.GenerateJUnitReport(trimmedReport, junitReport)
}