fix: test_all re-running too much stuff

This re-works the code which works out which tests need re-running to
be more accurate.
This commit is contained in:
Nick Craig-Wood 2024-04-14 16:50:53 +01:00
parent 88322f3eb2
commit 2cff5514aa
2 changed files with 49 additions and 31 deletions

View File

@ -100,33 +100,53 @@ func (r *Run) dumpOutput() {
log.Println("------------------------------------------------------------") log.Println("------------------------------------------------------------")
} }
// trie for storing runs
type trie map[string]trie
// turn a trie into multiple regexp matches
//
// We can't ever have a / in a regexp as it doesn't work.
func match(current trie) []string {
var names []string
var parts []string
for name, value := range current {
matchName := "^" + name + "$"
if len(value) == 0 {
names = append(names, name)
} else {
for _, part := range match(value) {
parts = append(parts, matchName+"/"+part)
}
}
}
sort.Strings(names)
if len(names) > 1 {
parts = append(parts, "^("+strings.Join(names, "|")+")$")
} else if len(names) == 1 {
parts = append(parts, "^"+names[0]+"$")
}
sort.Strings(parts)
return parts
}
// This converts a slice of test names into a regexp which matches // This converts a slice of test names into a regexp which matches
// them. // them.
func testsToRegexp(tests []string) string { func testsToRegexp(tests []string) string {
var split []map[string]struct{} var split = trie{}
// Make a slice with maps of the used parts at each level // Make a trie showing which parts are used at each level
for _, test := range tests { for _, test := range tests {
for i, name := range strings.Split(test, "/") { var parent = split
if i >= len(split) { for _, name := range strings.Split(test, "/") {
split = append(split, make(map[string]struct{})) current := parent[name]
if current == nil {
current = trie{}
parent[name] = current
} }
split[i][name] = struct{}{} parent = current
} }
} }
var out []string parts := match(split)
for _, level := range split { return strings.Join(parts, "|")
var testsInLevel = []string{}
for name := range level {
testsInLevel = append(testsInLevel, name)
}
sort.Strings(testsInLevel)
if len(testsInLevel) > 1 {
out = append(out, "^("+strings.Join(testsInLevel, "|")+")$")
} else {
out = append(out, "^"+testsInLevel[0]+"$")
}
}
return strings.Join(out, "/")
} }
var failRe = regexp.MustCompile(`(?m)^\s*--- FAIL: (Test.*?) \(`) var failRe = regexp.MustCompile(`(?m)^\s*--- FAIL: (Test.*?) \(`)

View File

@ -40,7 +40,7 @@ func TestTestsToRegexp(t *testing.T) {
"TestOne/Sub1", "TestOne/Sub1",
"TestTwo", "TestTwo",
}, },
want: "^(TestOne|TestTwo)$/^Sub1$", want: "^TestOne$/^Sub1$|^TestTwo$",
}, },
{ {
in: []string{ in: []string{
@ -48,7 +48,7 @@ func TestTestsToRegexp(t *testing.T) {
"TestOne/Sub2", "TestOne/Sub2",
"TestTwo", "TestTwo",
}, },
want: "^(TestOne|TestTwo)$/^(Sub1|Sub2)$", want: "^TestOne$/^(Sub1|Sub2)$|^TestTwo$",
}, },
{ {
in: []string{ in: []string{
@ -56,7 +56,7 @@ func TestTestsToRegexp(t *testing.T) {
"TestOne/Sub2/SubSub1", "TestOne/Sub2/SubSub1",
"TestTwo", "TestTwo",
}, },
want: "^(TestOne|TestTwo)$/^(Sub1|Sub2)$/^SubSub1$", want: "^TestOne$/^Sub1$|^TestOne$/^Sub2$/^SubSub1$|^TestTwo$",
}, },
{ {
in: []string{ in: []string{
@ -64,7 +64,7 @@ func TestTestsToRegexp(t *testing.T) {
"TestTests/B/B1", "TestTests/B/B1",
"TestTests/C/C3/C31", "TestTests/C/C3/C31",
}, },
want: "^TestTests$/^(A1|B|C)$/^(B1|C3)$/^C31$", want: "^TestTests$/^A1$|^TestTests$/^B$/^B1$|^TestTests$/^C$/^C3$/^C31$",
}, },
} { } {
got := testsToRegexp(test.in) got := testsToRegexp(test.in)
@ -108,13 +108,11 @@ func TestTestsToRegexpLive(t *testing.T) {
"TestTests/B", "TestTests/B",
"TestTests/B/B1", "TestTests/B/B1",
"TestTests/C", "TestTests/C",
// FIXME there doesn't seem to be a way to select a non-terminal test "TestTests/C/C1",
// and all of its subtests if there is a longer path (in this case B/B1) "TestTests/C/C2",
// "TestTests/C/C1", "TestTests/C/C3",
// "TestTests/C/C2", "TestTests/C/C3/C31",
// "TestTests/C/C3", "TestTests/C/C3/C32",
// "TestTests/C/C3/C31",
// "TestTests/C/C3/C32",
}, },
}, },
{ {