aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-08-11 10:34:00 +0200
committerDmitry Vyukov <dvyukov@google.com>2022-08-11 14:40:25 +0200
commit3e4f27bdcc4a69ccbe5fd7f9c1ad62bb40283e1c (patch)
tree7eca20345089138c9b495fcfed28be6c4316e937 /prog
parent787ed7e0bfb3cf1da3025aff0c7770717a993667 (diff)
prog: fix Rotator determinism
Currently Rotator.Select produces non-deterministic results because it relies on map iteration order. Fix that.
Diffstat (limited to 'prog')
-rw-r--r--prog/rotation.go7
-rw-r--r--prog/rotation_test.go16
2 files changed, 23 insertions, 0 deletions
diff --git a/prog/rotation.go b/prog/rotation.go
index 5651b6e05..8a9e7d2ca 100644
--- a/prog/rotation.go
+++ b/prog/rotation.go
@@ -38,7 +38,14 @@ func MakeRotator(target *Target, calls map[*Syscall]bool, rnd *rand.Rand) *Rotat
syscallUses: make(map[*Syscall][]*ResourceDesc),
resources: make(map[*ResourceDesc]rotatorResource),
}
+ var sorted []*Syscall
for call := range calls {
+ sorted = append(sorted, call)
+ }
+ sort.Slice(sorted, func(i, j int) bool {
+ return sorted[i].Name < sorted[j].Name
+ })
+ for _, call := range sorted {
r.syscallUses[call] = append(r.syscallUses[call], call.inputResources...)
r.syscallUses[call] = append(r.syscallUses[call], call.outputResources...)
var inputs []*ResourceDesc
diff --git a/prog/rotation_test.go b/prog/rotation_test.go
index e218a5eb6..37308f95b 100644
--- a/prog/rotation_test.go
+++ b/prog/rotation_test.go
@@ -133,3 +133,19 @@ retry:
}
}
}
+
+func TestRotationDeterminism(t *testing.T) {
+ target, rs, _ := initTest(t)
+ calls := make(map[*Syscall]bool)
+ for _, call := range target.Syscalls {
+ calls[call] = true
+ }
+ seed := rs.Int63()
+ rnd0 := rand.New(rand.NewSource(seed))
+ calls0 := MakeRotator(target, calls, rnd0).Select()
+ rnd1 := rand.New(rand.NewSource(seed))
+ calls1 := MakeRotator(target, calls, rnd1).Select()
+ if diff := cmp.Diff(calls0, calls1); diff != "" {
+ t.Fatal(diff)
+ }
+}