Skip to content

Commit e14f683

Browse files
committed
metamorphic: support --initial-state with --try-to-reduce
1 parent ac01b42 commit e14f683

File tree

3 files changed

+51
-27
lines changed

3 files changed

+51
-27
lines changed

internal/metamorphic/meta_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func runTestMeta(t *testing.T, addtlOptions ...option) {
7676
}
7777
testRootDir, runSubdirs := runOnceFlags.ParseCompare()
7878
if runOnceFlags.TryToReduce {
79-
tryToReduceCompare(t, runOnceFlags.Dir, testRootDir, runSubdirs, runOnceFlags.ReduceAttempts)
79+
tryToReduceCompare(t, runOnceFlags.Dir, testRootDir, runSubdirs, runOnceFlags.InitialStatePath, runOnceFlags.ReduceAttempts)
8080
return
8181
}
8282
metamorphic.Compare(t, testRootDir, runOnceFlags.Seed, runSubdirs, onceOpts...)
@@ -90,7 +90,7 @@ func runTestMeta(t *testing.T, addtlOptions ...option) {
9090
onceOpts = append(onceOpts, opt)
9191
}
9292
if runOnceFlags.TryToReduce {
93-
tryToReduce(t, runOnceFlags.Dir, runOnceFlags.RunDir, runOnceFlags.ReduceAttempts)
93+
tryToReduce(t, runOnceFlags.Dir, runOnceFlags.RunDir, runOnceFlags.InitialStatePath, runOnceFlags.ReduceAttempts)
9494
return
9595
}
9696
metamorphic.RunOnce(t, runOnceFlags.RunDir, runOnceFlags.Seed,

internal/metamorphic/reduce_test.go

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"os"
1313
"os/exec"
1414
"path/filepath"
15+
"strconv"
1516
"strings"
1617
"testing"
1718
"time"
@@ -32,10 +33,12 @@ import (
3233
//
3334
// The test will save the smallest reproduction found and print out the relevant
3435
// information.
35-
func tryToReduce(t *testing.T, testStateDir string, runDir string, reduceAttempts int) {
36+
func tryToReduce(
37+
t *testing.T, testStateDir string, runDir string, initialStatePath string, reduceAttempts int,
38+
) {
3639
testRootDir := filepath.Dir(runDir)
3740
runSubdir := filepath.Base(runDir)
38-
r := makeReducer(t, testStateDir, testRootDir, []string{runSubdir}, reduceAttempts)
41+
r := makeReducer(t, testStateDir, testRootDir, []string{runSubdir}, initialStatePath, reduceAttempts)
3942
r.Run(t)
4043
}
4144

@@ -52,19 +55,26 @@ func tryToReduce(t *testing.T, testStateDir string, runDir string, reduceAttempt
5255
// The test will save the smallest reproduction found and print out the relevant
5356
// information.
5457
func tryToReduceCompare(
55-
t *testing.T, testStateDir string, testRootDir string, runSubdirs []string, reduceAttempts int,
58+
t *testing.T,
59+
testStateDir string,
60+
testRootDir string,
61+
runSubdirs []string,
62+
initialStatePath string,
63+
reduceAttempts int,
5664
) {
57-
r := makeReducer(t, testStateDir, testRootDir, runSubdirs, reduceAttempts)
65+
r := makeReducer(t, testStateDir, testRootDir, runSubdirs, initialStatePath, reduceAttempts)
5866
r.Run(t)
5967
}
6068

6169
// reducer is a helper that starts with a reproduction of a RunOnce failure and
6270
// tries to reduce the number of operations.
6371
type reducer struct {
6472
// testRootDir is the directory of the test, which contains the "ops" file.
65-
testRootDir string
66-
configs []testConfig
67-
reduceAttempts int
73+
testRootDir string
74+
configs []testConfig
75+
// initialStatePath stores the --initial-state value, if set.
76+
initialStatePath string
77+
reduceAttempts int
6878

6979
ops []string
7080

@@ -84,7 +94,12 @@ type testConfig struct {
8494
}
8595

8696
func makeReducer(
87-
t *testing.T, testStateDir string, testRootDir string, runSubdirs []string, reduceAttempts int,
97+
t *testing.T,
98+
testStateDir string,
99+
testRootDir string,
100+
runSubdirs []string,
101+
initialStatePath string,
102+
reduceAttempts int,
88103
) *reducer {
89104
// All run dirs should have the same parent path.
90105
opsData, err := os.ReadFile(filepath.Join(testRootDir, "ops"))
@@ -105,11 +120,12 @@ func makeReducer(
105120
t.Logf("Starting with %d operations", len(ops))
106121

107122
return &reducer{
108-
testRootDir: testRootDir,
109-
configs: tc,
110-
ops: ops,
111-
reduceAttempts: reduceAttempts,
112-
testStateDir: testStateDir,
123+
testRootDir: testRootDir,
124+
configs: tc,
125+
initialStatePath: initialStatePath,
126+
ops: ops,
127+
reduceAttempts: reduceAttempts,
128+
testStateDir: testStateDir,
113129
}
114130
}
115131

@@ -144,15 +160,16 @@ func (r *reducer) try(t *testing.T, ops []string) bool {
144160
"--keep",
145161
}
146162

147-
var runFlags []string
148163
if len(runSubdirs) == 1 {
149164
// RunOnce mode.
150-
runFlags = []string{"--run-dir", filepath.Join(testRootDir, runSubdirs[0])}
165+
args = append(args, "--run-dir", filepath.Join(testRootDir, runSubdirs[0]))
151166
} else {
152167
// Compare mode.
153-
runFlags = []string{"--compare", filepath.Join(testRootDir, fmt.Sprintf("{%s}", strings.Join(runSubdirs, ",")))}
168+
args = append(args, "--compare", filepath.Join(testRootDir, fmt.Sprintf("{%s}", strings.Join(runSubdirs, ","))))
169+
}
170+
if r.initialStatePath != "" {
171+
args = append(args, "--initial-state", r.initialStatePath)
154172
}
155-
args = append(args, runFlags...)
156173

157174
var output bytes.Buffer
158175
cmd := exec.CommandContext(context.Background(), os.Args[0], args...)
@@ -188,7 +205,7 @@ func (r *reducer) try(t *testing.T, ops []string) bool {
188205
t.Logf(" Diagram: %s", diagramPath)
189206
}
190207

191-
t.Logf(` go test ./internal/metamorphic -tags invariants -run "%s$" -v %s %q`, t.Name(), runFlags[0], runFlags[1])
208+
t.Logf(" go test ./internal/metamorphic -tags invariants %s", shellJoin(cmd.Args[1:]))
192209
if r.lastSavedDir != "" {
193210
require.NoError(t, os.RemoveAll(r.lastSavedDir))
194211
}
@@ -238,3 +255,16 @@ func randomSubset(t *testing.T, ops []string, removeProbability float64) []strin
238255
}
239256
return res
240257
}
258+
259+
func shellJoin(args []string) string {
260+
quoted := make([]string, len(args))
261+
for i, a := range args {
262+
// Quote if the word has bytes that the shell would interpret.
263+
if strings.ContainsAny(a, " \t\n\"'\\$`*?[]{}<>|&;()") {
264+
quoted[i] = strconv.Quote(a)
265+
} else {
266+
quoted[i] = a
267+
}
268+
}
269+
return strings.Join(quoted, " ")
270+
}

metamorphic/history.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,7 @@ func CompareHistories(t TestingT, paths []string) (i int, diff string) {
183183
for i := 1; i < len(paths); i++ {
184184
lines := readHistory(t, paths[i])
185185
lines = reorderHistory(lines)
186-
diff := difflib.UnifiedDiff{
187-
A: base,
188-
B: lines,
189-
Context: 5,
190-
}
191-
text, err := difflib.GetUnifiedDiffString(diff)
192-
require.NoError(t, err)
186+
text := lineByLineDiff(base, lines)
193187
if text != "" {
194188
return i, text
195189
}

0 commit comments

Comments
 (0)