Skip to content

Commit

Permalink
Merge pull request #343 from brycekahle/bryce.kahle/filter-to-leaves
Browse files Browse the repository at this point in the history
rerun-fails: prevent extra runs when a sub-test fails
  • Loading branch information
dnephin committed Jul 30, 2023
2 parents 40adf53 + bf91082 commit b806793
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 5 deletions.
44 changes: 39 additions & 5 deletions testjson/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ func (n TestName) Name() string {
return string(n)
}

func (n TestName) Parent() string {
idx := strings.LastIndex(string(n), "/")
if idx < 0 {
return ""
}
return string(n)[:idx]
}

func (p *Package) removeOutput(id int) {
delete(p.output, id)

Expand Down Expand Up @@ -538,15 +546,41 @@ func (e *Execution) Failed() []TestCase {
return failed
}

// FilterFailedUnique filters a slice of failed TestCases by removing root test
// case that have failed subtests.
// FilterFailedUnique filters a slice of failed TestCases to remove any parent
// tests that have failed subtests. The parent test will always be run when
// running any of its subtests.
func FilterFailedUnique(tcs []TestCase) []TestCase {
var result []TestCase
sort.Slice(tcs, func(i, j int) bool {
a, b := tcs[i], tcs[j]
if a.Package != b.Package {
return a.Package < b.Package
}
return len(a.Test.Name()) > len(b.Test.Name())
})

var result []TestCase //nolint:prealloc
var parents = make(map[string]map[string]bool)
for _, tc := range tcs {
if !tc.hasSubTestFailed {
result = append(result, tc)
if _, exists := parents[tc.Package]; !exists {
parents[tc.Package] = make(map[string]bool)
}
if parent := tc.Test.Parent(); parent != "" {
parents[tc.Package][parent] = true
}
if _, exists := parents[tc.Package][tc.Test.Name()]; exists {
continue // tc is a parent of a failing subtest
}
result = append(result, tc)
}

// Restore the original order of test cases
sort.Slice(result, func(i, j int) bool {
a, b := result[i], result[j]
if a.Package != b.Package {
return a.Package < b.Package
}
return a.ID < b.ID
})
return result
}

Expand Down
48 changes: 48 additions & 0 deletions testjson/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,51 @@ func (s *captureHandler) Err(text string) error {
s.errs = append(s.errs, text)
return nil
}

func TestFilterFailedUnique_MultipleNested(t *testing.T) {
source := []byte(`{"Package": "pkg", "Action": "run"}
{"Package": "pkg", "Test": "TestParent", "Action": "run"}
{"Package": "pkg", "Test": "TestParent/TestNested", "Action": "run"}
{"Package": "pkg", "Test": "TestParent/TestNested/TestOne", "Action": "run"}
{"Package": "pkg", "Test": "TestParent/TestNested/TestOne", "Action": "fail"}
{"Package": "pkg", "Test": "TestParent/TestNested/TestOnePrefix", "Action": "run"}
{"Package": "pkg", "Test": "TestParent/TestNested/TestOnePrefix", "Action": "fail"}
{"Package": "pkg", "Test": "TestParent/TestNested", "Action": "fail"}
{"Package": "pkg", "Test": "TestParent", "Action": "fail"}
{"Package": "pkg", "Test": "TestTop", "Action": "run"}
{"Package": "pkg", "Test": "TestTop", "Action": "fail"}
{"Package": "pkg", "Test": "TestTopPrefix", "Action": "run"}
{"Package": "pkg", "Test": "TestTopPrefix", "Action": "fail"}
{"Package": "pkg", "Action": "fail"}
{"Package": "pkg2", "Action": "run"}
{"Package": "pkg2", "Test": "TestParent", "Action": "run"}
{"Package": "pkg2", "Test": "TestParent/TestNested", "Action": "run"}
{"Package": "pkg2", "Test": "TestParent/TestNested", "Action": "fail"}
{"Package": "pkg2", "Test": "TestParent/TestNestedPrefix", "Action": "run"}
{"Package": "pkg2", "Test": "TestParent/TestNestedPrefix", "Action": "fail"}
{"Package": "pkg2", "Test": "TestParent", "Action": "fail"}
{"Package": "pkg2", "Test": "TestParentPrefix", "Action": "run"}
{"Package": "pkg2", "Test": "TestParentPrefix", "Action": "fail"}
{"Package": "pkg2", "Action": "fail"}`)

handler := &captureHandler{}
cfg := ScanConfig{
Stdout: bytes.NewReader(source),
Handler: handler,
}
exec, err := ScanTestOutput(cfg)
assert.NilError(t, err)
actual := FilterFailedUnique(exec.Failed())

expected := []TestCase{
{ID: 3, Package: "pkg", Test: TestName("TestParent/TestNested/TestOne")},
{ID: 4, Package: "pkg", Test: TestName("TestParent/TestNested/TestOnePrefix")},
{ID: 5, Package: "pkg", Test: TestName("TestTop")},
{ID: 6, Package: "pkg", Test: TestName("TestTopPrefix")},
{ID: 2, Package: "pkg2", Test: TestName("TestParent/TestNested")},
{ID: 3, Package: "pkg2", Test: TestName("TestParent/TestNestedPrefix")},
{ID: 4, Package: "pkg2", Test: TestName("TestParentPrefix")},
}
cmpTestCase := cmp.AllowUnexported(TestCase{})
assert.DeepEqual(t, expected, actual, cmpTestCase)
}

0 comments on commit b806793

Please sign in to comment.