aboutsummaryrefslogtreecommitdiffstats
path: root/prog/rand_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2019-01-03 12:12:55 +0100
committerDmitry Vyukov <dvyukov@google.com>2019-01-03 12:23:57 +0100
commitadddc5fd46167e2c22cdc6a7d0d7b73cc418dc6f (patch)
tree26672d15766cc1e668761b74c29c64143e42ada2 /prog/rand_test.go
parent66fcd29b60c566b3d7b7cc75550a4b96e355164d (diff)
prog: remove several sources of non-determinism
Non-determinism is bad: - it leads to flaky coverage reports - it makes test failures non-reproducible Remove 4 sources of non-determinism related to maps: - file name generation - string generation - resource generation - hints generation All a test that ensures all main operations are fully deterministic.
Diffstat (limited to 'prog/rand_test.go')
-rw-r--r--prog/rand_test.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/prog/rand_test.go b/prog/rand_test.go
index 1771a0052..d96d96260 100644
--- a/prog/rand_test.go
+++ b/prog/rand_test.go
@@ -24,3 +24,49 @@ func TestNotEscaping(t *testing.T) {
}
}
}
+
+func TestDeterminism(t *testing.T) {
+ target, rs, iters := initTest(t)
+ iters /= 10 // takes too long
+ for i := 0; i < iters; i++ {
+ seed := rs.Int63()
+ rs1 := rand.NewSource(seed)
+ p1 := generateProg(t, target, rs1)
+ rs2 := rand.NewSource(seed)
+ p2 := generateProg(t, target, rs2)
+ ps1 := string(p1.Serialize())
+ ps2 := string(p2.Serialize())
+ r1 := rs1.Int63()
+ r2 := rs2.Int63()
+ if r1 != r2 || ps1 != ps2 {
+ t.Errorf("seed=%v\nprog 1 (%v):\n%v\nprog 2 (%v):\n%v", seed, r1, ps1, r2, ps2)
+ }
+ }
+}
+
+func generateProg(t *testing.T, target *Target, rs rand.Source) *Prog {
+ p := target.Generate(rs, 5, nil)
+ p.Mutate(rs, 10, nil, nil)
+ for i, c := range p.Calls {
+ comps := make(CompMap)
+ for v := range extractValues(c) {
+ comps.AddComp(v, v+1)
+ comps.AddComp(v, v+10)
+ }
+ p.MutateWithHints(i, comps, func(p1 *Prog) {
+ p = p1.Clone()
+ })
+ }
+ for _, crash := range []bool{false, true} {
+ p, _ = Minimize(p, -1, crash, func(*Prog, int) bool {
+ return rs.Int63()%10 == 0
+ })
+ }
+ data := p.Serialize()
+ var err error
+ p, err = target.Deserialize(data, NonStrict)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return p
+}