Skip to content

Commit 537b06f

Browse files
committed
fix
1 parent bf677b0 commit 537b06f

File tree

2 files changed

+83
-18
lines changed

2 files changed

+83
-18
lines changed

tools/flakeguard/runner/runner.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (r *Runner) RunTestPackages(packages []string) (*reports.TestReport, error)
7777
}
7878

7979
// Parse initial results.
80-
results, err := r.parseTestResults(jsonFilePaths)
80+
results, err := r.parseTestResults(jsonFilePaths, "run")
8181
if err != nil {
8282
return nil, fmt.Errorf("failed to parse test results: %w", err)
8383
}
@@ -124,7 +124,7 @@ func (r *Runner) RunTestCmd(testCmd []string) (*reports.TestReport, error) {
124124
}
125125
}
126126

127-
results, err := r.parseTestResults(jsonFilePaths)
127+
results, err := r.parseTestResults(jsonFilePaths, "run")
128128
if err != nil {
129129
return nil, fmt.Errorf("failed to parse test results: %w", err)
130130
}
@@ -300,7 +300,7 @@ func (e entry) String() string {
300300
// panics and failures at that point.
301301
// Subtests add more complexity, as panics in subtests are only reported in their parent's output,
302302
// and cannot be accurately attributed to the subtest that caused them.
303-
func (r *Runner) parseTestResults(filePaths []string) ([]reports.TestResult, error) {
303+
func (r *Runner) parseTestResults(filePaths []string, runPrefix string) ([]reports.TestResult, error) {
304304
// If the option is enabled, transform each JSON output file before parsing.
305305
if r.IgnoreParentFailuresOnSubtests {
306306
transformedPaths, err := r.transformTestOutputFiles(filePaths)
@@ -326,7 +326,7 @@ func (r *Runner) parseTestResults(filePaths []string) ([]reports.TestResult, err
326326
// Process each file
327327
for _, filePath := range filePaths {
328328
runNumber++
329-
runID := fmt.Sprintf("run%d", runNumber)
329+
runID := fmt.Sprintf("%s%d", runPrefix, runNumber)
330330
file, err := os.Open(filePath)
331331
if err != nil {
332332
return nil, fmt.Errorf("failed to open test output file: %w", err)
@@ -763,7 +763,7 @@ func (r *Runner) rerunFailedTests(results []reports.TestResult) ([]reports.TestR
763763
return nil, fmt.Errorf("error on rerunCmd for test %s: %w", fTest.TestName, err)
764764
}
765765

766-
additionalResults, err := r.parseTestResults([]string{jsonFilePath})
766+
additionalResults, err := r.parseTestResults([]string{jsonFilePath}, "rerun")
767767
if err != nil {
768768
return nil, fmt.Errorf("failed to parse rerun results: %w", err)
769769
}
@@ -796,16 +796,7 @@ func (r *Runner) buildGoTestCommandForTest(t reports.TestResult) []string {
796796
return cmd
797797
}
798798

799-
// appendUnique appends s to slice if not already present.
800-
func appendUnique(slice []string, s string) []string {
801-
for _, v := range slice {
802-
if v == s {
803-
return slice
804-
}
805-
}
806-
return append(slice, s)
807-
}
808-
799+
// mergeTestResults merges additional test results into the existing results slice.
809800
// mergeTestResults merges additional test results into the existing results slice.
810801
func mergeTestResults(mainResults *[]reports.TestResult, additional []reports.TestResult) {
811802
for _, add := range additional {
@@ -821,9 +812,21 @@ func mergeTestResults(mainResults *[]reports.TestResult, additional []reports.Te
821812
// Merge durations
822813
(*mainResults)[i].Durations = append((*mainResults)[i].Durations, add.Durations...)
823814

824-
// Because PassedOutputs and FailedOutputs are now []string:
825-
(*mainResults)[i].PassedOutputs = append((*mainResults)[i].PassedOutputs, add.PassedOutputs...)
826-
(*mainResults)[i].FailedOutputs = append((*mainResults)[i].FailedOutputs, add.FailedOutputs...)
815+
// Merge maps for PassedOutputs
816+
if (*mainResults)[i].PassedOutputs == nil {
817+
(*mainResults)[i].PassedOutputs = make(map[string][]string)
818+
}
819+
for runID, outputs := range add.PassedOutputs {
820+
(*mainResults)[i].PassedOutputs[runID] = append((*mainResults)[i].PassedOutputs[runID], outputs...)
821+
}
822+
823+
// Merge maps for FailedOutputs
824+
if (*mainResults)[i].FailedOutputs == nil {
825+
(*mainResults)[i].FailedOutputs = make(map[string][]string)
826+
}
827+
for runID, outputs := range add.FailedOutputs {
828+
(*mainResults)[i].FailedOutputs[runID] = append((*mainResults)[i].FailedOutputs[runID], outputs...)
829+
}
827830

828831
// Update pass ratio
829832
if (*mainResults)[i].Runs > 0 {

tools/flakeguard/runner/runner_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,68 @@ func TestFailedOutputs(t *testing.T) {
537537
}
538538
}
539539

540+
func TestRerunFailed(t *testing.T) {
541+
t.Parallel()
542+
543+
// Configure a runner that will rerun failed tests
544+
runner := Runner{
545+
ProjectPath: "./",
546+
Verbose: true,
547+
RunCount: 2, // Run tests twice initially
548+
RerunFailed: 3, // Rerun failing tests 3 more times
549+
SelectTests: []string{"TestFail"}, // This test is known to always fail
550+
CollectRawOutput: true,
551+
}
552+
553+
testReport, err := runner.RunTestPackages([]string{flakyTestPackagePath})
554+
require.NoError(t, err, "running tests should not produce an unexpected error")
555+
556+
// Verify we have the expected number of results
557+
require.Equal(t, 1, len(testReport.Results), "expected exactly one test result")
558+
559+
// Find the TestFail result
560+
var testFailResult *reports.TestResult
561+
for i := range testReport.Results {
562+
if testReport.Results[i].TestName == "TestFail" {
563+
testFailResult = &testReport.Results[i]
564+
break
565+
}
566+
}
567+
require.NotNil(t, testFailResult, "expected TestFail result not found in report")
568+
569+
// TestFail should have run 5 times (2 initial + 3 reruns)
570+
require.Equal(t, 5, testFailResult.Runs, "TestFail should have run 5 times (2 initial + 3 reruns)")
571+
572+
// Verify that we have outputs from failed runs
573+
require.NotEmpty(t, testFailResult.FailedOutputs, "expected failed outputs for TestFail")
574+
require.Empty(t, testFailResult.PassedOutputs, "TestFail should have no passed outputs")
575+
576+
// We should have outputs from both run and rerun prefixes
577+
hasRunOutput := false
578+
hasRerunOutput := false
579+
580+
// Check if we have outputs from both original runs and reruns
581+
for runID := range testFailResult.FailedOutputs {
582+
t.Logf("Found failed outputs for run %s", runID)
583+
if strings.HasPrefix(runID, "run") {
584+
hasRunOutput = true
585+
} else if strings.HasPrefix(runID, "rerun") {
586+
hasRerunOutput = true
587+
}
588+
}
589+
590+
require.True(t, hasRunOutput, "expected outputs from initial runs")
591+
require.True(t, hasRerunOutput, "expected outputs from reruns")
592+
593+
// Check that the PassRatio is 0 (since TestFail always fails)
594+
require.Equal(t, 0.0, testFailResult.PassRatio, "TestFail should have a pass ratio of 0.0")
595+
596+
// Verify that the test ran exactly 5 times and all were failures
597+
require.Equal(t, 5, testFailResult.Failures, "TestFail should have failed 5 times")
598+
require.Equal(t, 0, testFailResult.Successes, "TestFail should have passed 0 times")
599+
require.Equal(t, 5, testFailResult.Successes+testFailResult.Failures, "total of successes and failures should equal 5")
600+
}
601+
540602
func TestSkippedTests(t *testing.T) {
541603
t.Parallel()
542604

0 commit comments

Comments
 (0)