From 665c8a2234ddc0438c80a790eb4e445446ab25c3 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Thu, 15 Jan 2026 08:35:00 -0500 Subject: [PATCH] jobrunaggregator: treat informing tests as always passing Tests with lifecycle="informing" in the JUnit XML do not impact aggregation results. This change parses the lifecycle attribute and treats informing tests as always passing in the pass/fail calculation. Co-Authored-By: Claude Opus 4.5 --- pkg/jobrunaggregator/jobrunaggregatoranalyzer/junit.go | 6 ++++++ pkg/jobrunaggregator/jobrunaggregatoranalyzer/pass_fail.go | 5 +++++ pkg/jobrunaggregator/jobrunaggregatorlib/junit.go | 3 +++ pkg/junit/testdata/zz_fixture_TestCensorTestSuite.yaml | 6 ++++++ pkg/junit/types.go | 4 ++++ 5 files changed, 24 insertions(+) diff --git a/pkg/jobrunaggregator/jobrunaggregatoranalyzer/junit.go b/pkg/jobrunaggregator/jobrunaggregatoranalyzer/junit.go index d437d2c0f1a..29b5c28610b 100644 --- a/pkg/jobrunaggregator/jobrunaggregatoranalyzer/junit.go +++ b/pkg/jobrunaggregator/jobrunaggregatoranalyzer/junit.go @@ -193,6 +193,12 @@ func aggregateTestCase(testSuiteName string, combined *junit.TestCase, jobGCSBuc } } + // Store lifecycle from the test case - informing tests will be treated as always passing + // in the pass/fail calculation + if toAdd.Lifecycle != "" { + currDetails.Lifecycle = toAdd.Lifecycle + } + switch { case toAdd.FailureOutput != nil: humanURL := jobrunaggregatorapi.GetHumanURLForLocation(path.Join(jobGCSBucketRoot, toAddJobRunID), "test-platform-results") diff --git a/pkg/jobrunaggregator/jobrunaggregatoranalyzer/pass_fail.go b/pkg/jobrunaggregator/jobrunaggregatoranalyzer/pass_fail.go index 50c3370d316..e5bf3a17a98 100644 --- a/pkg/jobrunaggregator/jobrunaggregatoranalyzer/pass_fail.go +++ b/pkg/jobrunaggregator/jobrunaggregatoranalyzer/pass_fail.go @@ -549,6 +549,11 @@ func (a *weeklyAverageFromTenDays) innerCheckPercentileDisruptionWithGrace( } func (a *weeklyAverageFromTenDays) CheckFailed(ctx context.Context, jobName string, suiteNames []string, testCaseDetails *jobrunaggregatorlib.TestCaseDetails) (testCaseStatus, string, error) { + // Informing tests do not impact aggregation, so treat them as always passing + if testCaseDetails.Lifecycle == "informing" { + reason := fmt.Sprintf("always passing %q: informing test does not impact aggregation\n", testCaseDetails.Name) + return testCasePassed, reason, nil + } if reason := testShouldAlwaysPass(jobName, testCaseDetails.Name, testCaseDetails.TestSuiteName); len(reason) > 0 { reason := fmt.Sprintf("always passing %q: %v\n", testCaseDetails.Name, reason) return testCasePassed, reason, nil diff --git a/pkg/jobrunaggregator/jobrunaggregatorlib/junit.go b/pkg/jobrunaggregator/jobrunaggregatorlib/junit.go index 1b77abfa337..ea39c105f3f 100644 --- a/pkg/jobrunaggregator/jobrunaggregatorlib/junit.go +++ b/pkg/jobrunaggregator/jobrunaggregatorlib/junit.go @@ -8,6 +8,9 @@ type TestCaseDetails struct { TestSuiteName string // Summary is filled in during the pass/fail calculation Summary string + // Lifecycle indicates whether the test is blocking or informing. + // Informing tests do not impact aggregation. + Lifecycle string Passes []TestCasePass Failures []TestCaseFailure diff --git a/pkg/junit/testdata/zz_fixture_TestCensorTestSuite.yaml b/pkg/junit/testdata/zz_fixture_TestCensorTestSuite.yaml index 3b378e19c67..15a56c22bed 100644 --- a/pkg/junit/testdata/zz_fixture_TestCensorTestSuite.yaml +++ b/pkg/junit/testdata/zz_fixture_TestCensorTestSuite.yaml @@ -26,6 +26,7 @@ Children: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow very nested XXXXXX SkipMessage: Message: skipped due to very nested XXXXXX @@ -45,6 +46,7 @@ Children: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow also very nested XXXXXX SkipMessage: Message: also skipped due to very nested XXXXXX @@ -84,6 +86,7 @@ Children: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow nested XXXXXX SkipMessage: Message: skipped due to nested XXXXXX @@ -103,6 +106,7 @@ Children: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow also nested XXXXXX SkipMessage: Message: also skipped due to nested XXXXXX @@ -142,6 +146,7 @@ TestCases: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow XXXXXX SkipMessage: Message: skipped due to XXXXXX @@ -161,6 +166,7 @@ TestCases: XMLName: Local: "" Space: "" + Lifecycle: "" Name: somehow also XXXXXX SkipMessage: Message: also skipped due to XXXXXX diff --git a/pkg/junit/types.go b/pkg/junit/types.go index eefc647f0fd..af174efecd9 100644 --- a/pkg/junit/types.go +++ b/pkg/junit/types.go @@ -68,6 +68,10 @@ type TestCase struct { // Duration is the time taken in seconds to run the test Duration float64 `xml:"time,attr"` + // Lifecycle indicates whether the test is blocking or informing. + // Informing tests do not impact aggregation. + Lifecycle string `xml:"lifecycle,attr,omitempty"` + // SkipMessage holds the reason why the test was skipped SkipMessage *SkipMessage `xml:"skipped"`