diff --git a/.changelog/14497.txt b/.changelog/14497.txt new file mode 100644 index 00000000000..4b233f0acb0 --- /dev/null +++ b/.changelog/14497.txt @@ -0,0 +1,3 @@ +```release-note:bug +helpers: Fixed a bug where random stagger func did not protect against negative inputs +``` diff --git a/helper/cluster.go b/helper/cluster.go index e3fda8b2332..1abca148160 100644 --- a/helper/cluster.go +++ b/helper/cluster.go @@ -1,4 +1,3 @@ -// These functions are coming from consul/lib/cluster.go package helper import ( @@ -13,11 +12,11 @@ const ( ) // RandomStagger returns an interval between 0 and the duration -func RandomStagger(intv time.Duration) time.Duration { - if intv == 0 { +func RandomStagger(interval time.Duration) time.Duration { + if interval <= 0 { return 0 } - return time.Duration(uint64(rand.Int63()) % uint64(intv)) + return time.Duration(uint64(rand.Int63()) % uint64(interval)) } // RateScaledInterval is used to choose an interval to perform an action in diff --git a/helper/cluster_test.go b/helper/cluster_test.go new file mode 100644 index 00000000000..028db0b467f --- /dev/null +++ b/helper/cluster_test.go @@ -0,0 +1,29 @@ +package helper + +import ( + "testing" + "time" + + "github.com/shoenig/test/must" +) + +func TestCluster_RandomStagger(t *testing.T) { + cases := []struct { + name string + input time.Duration + }{ + {name: "positive", input: 1 * time.Second}, + {name: "negative", input: -1 * time.Second}, + {name: "zero", input: 0}, + } + + abs := func(d time.Duration) time.Duration { + return Max(d, -d) + } + + for _, tc := range cases { + result := RandomStagger(tc.input) + must.GreaterEq(t, result, 0) + must.LessEq(t, result, abs(tc.input)) + } +}