forked from TrueCloudLab/rclone
test_all: fix regexp for retrying nested tests
This commit is contained in:
parent
e84790ef79
commit
df01f7a4eb
2 changed files with 212 additions and 1 deletions
|
@ -15,6 +15,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -101,6 +102,35 @@ func (r *Run) dumpOutput() {
|
||||||
log.Println("------------------------------------------------------------")
|
log.Println("------------------------------------------------------------")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This converts a slice of test names into a regexp which matches
|
||||||
|
// them.
|
||||||
|
func testsToRegexp(tests []string) string {
|
||||||
|
var split []map[string]struct{}
|
||||||
|
// Make a slice with maps of the used parts at each level
|
||||||
|
for _, test := range tests {
|
||||||
|
for i, name := range strings.Split(test, "/") {
|
||||||
|
if i >= len(split) {
|
||||||
|
split = append(split, make(map[string]struct{}))
|
||||||
|
}
|
||||||
|
split[i][name] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var out []string
|
||||||
|
for _, level := range split {
|
||||||
|
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.*?) \(`)
|
||||||
|
|
||||||
// findFailures looks for all the tests which failed
|
// findFailures looks for all the tests which failed
|
||||||
|
@ -126,7 +156,7 @@ func (r *Run) findFailures() {
|
||||||
}
|
}
|
||||||
r.failedTests = newTests
|
r.failedTests = newTests
|
||||||
if len(r.failedTests) != 0 {
|
if len(r.failedTests) != 0 {
|
||||||
r.runFlag = "^(" + strings.Join(r.failedTests, "|") + ")$"
|
r.runFlag = testsToRegexp(r.failedTests)
|
||||||
} else {
|
} else {
|
||||||
r.runFlag = ""
|
r.runFlag = ""
|
||||||
}
|
}
|
||||||
|
|
181
fstest/test_all/run_test.go
Normal file
181
fstest/test_all/run_test.go
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestsToRegexp(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
in []string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
in: []string{},
|
||||||
|
want: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"TestOne"},
|
||||||
|
want: "^TestOne$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"TestOne", "TestTwo"},
|
||||||
|
want: "^(TestOne|TestTwo)$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"TestOne", "TestTwo", "TestThree"},
|
||||||
|
want: "^(TestOne|TestThree|TestTwo)$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"TestOne/Sub1"},
|
||||||
|
want: "^TestOne$/^Sub1$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestOne/Sub1",
|
||||||
|
"TestTwo",
|
||||||
|
},
|
||||||
|
want: "^(TestOne|TestTwo)$/^Sub1$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestOne/Sub1",
|
||||||
|
"TestOne/Sub2",
|
||||||
|
"TestTwo",
|
||||||
|
},
|
||||||
|
want: "^(TestOne|TestTwo)$/^(Sub1|Sub2)$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestOne/Sub1",
|
||||||
|
"TestOne/Sub2/SubSub1",
|
||||||
|
"TestTwo",
|
||||||
|
},
|
||||||
|
want: "^(TestOne|TestTwo)$/^(Sub1|Sub2)$/^SubSub1$",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
},
|
||||||
|
want: "^TestTests$/^(A1|B|C)$/^(B1|C3)$/^C31$",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
got := testsToRegexp(test.in)
|
||||||
|
assert.Equal(t, test.want, got, fmt.Sprintf("in=%v want=%q got=%q", test.in, test.want, got))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var runRe = regexp.MustCompile(`(?m)^\s*=== RUN\s*(Test.*?)\s*$`)
|
||||||
|
|
||||||
|
// Test the regexp work with the -run flag in actually selecting the right tests
|
||||||
|
func TestTestsToRegexpLive(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
in []string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/C/C3",
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
"TestTests",
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/C",
|
||||||
|
"TestTests/C/C3",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
"TestTests/C/C3/C32",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestTests",
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/B",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C",
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
"TestTests",
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/B",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C",
|
||||||
|
// FIXME there doesn't seem to be a way to select a non-terminal test
|
||||||
|
// and all of its subtests if there is a longer path (in this case B/B1)
|
||||||
|
// "TestTests/C/C1",
|
||||||
|
// "TestTests/C/C2",
|
||||||
|
// "TestTests/C/C3",
|
||||||
|
// "TestTests/C/C3/C31",
|
||||||
|
// "TestTests/C/C3/C32",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
"TestTests",
|
||||||
|
"TestTests/A1",
|
||||||
|
"TestTests/B",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C",
|
||||||
|
"TestTests/C/C3",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
"TestTests",
|
||||||
|
"TestTests/B",
|
||||||
|
"TestTests/B/B1",
|
||||||
|
"TestTests/C",
|
||||||
|
"TestTests/C/C3",
|
||||||
|
"TestTests/C/C3/C31",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
runRegexp := testsToRegexp(test.in)
|
||||||
|
cmd := exec.Command("go", "test", "-v", "-run", runRegexp)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err)
|
||||||
|
var got []string
|
||||||
|
for _, match := range runRe.FindAllSubmatch(out, -1) {
|
||||||
|
got = append(got, string(match[1]))
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.want, got, fmt.Sprintf("in=%v want=%v got=%v, runRegexp=%q", test.in, test.want, got, runRegexp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nilTest = func(t *testing.T) {}
|
||||||
|
|
||||||
|
// Nested tests for TestTestsToRegexpLive to run
|
||||||
|
func TestTests(t *testing.T) {
|
||||||
|
t.Run("A1", nilTest)
|
||||||
|
t.Run("A2", nilTest)
|
||||||
|
t.Run("B", func(t *testing.T) {
|
||||||
|
t.Run("B1", nilTest)
|
||||||
|
t.Run("B2", nilTest)
|
||||||
|
})
|
||||||
|
t.Run("C", func(t *testing.T) {
|
||||||
|
t.Run("C1", nilTest)
|
||||||
|
t.Run("C2", nilTest)
|
||||||
|
t.Run("C3", func(t *testing.T) {
|
||||||
|
t.Run("C31", nilTest)
|
||||||
|
t.Run("C32", nilTest)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue