From 3e4f27bdcc4a69ccbe5fd7f9c1ad62bb40283e1c Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 11 Aug 2022 10:34:00 +0200 Subject: prog: fix Rotator determinism Currently Rotator.Select produces non-deterministic results because it relies on map iteration order. Fix that. --- prog/rotation.go | 7 +++++++ prog/rotation_test.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) 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) + } +} -- cgit mrf-deployment