From 7ffaef63d18572507031496b51f327366850984c Mon Sep 17 00:00:00 2001 From: jay vyas Date: Thu, 5 Nov 2015 09:02:51 -0500 Subject: [PATCH] Backoff and Randomness additions for use in client utilities Updated String to use int, and int not to panic, and panic to test panic Format fixes. --- pkg/util/backoff.go | 7 +++++++ pkg/util/backoff_test.go | 8 ++++++++ pkg/util/rand/rand.go | 25 ++++++++++++++----------- pkg/util/rand/rand_test.go | 21 +++++++++++++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/pkg/util/backoff.go b/pkg/util/backoff.go index 173e131872c..4554ee6a545 100644 --- a/pkg/util/backoff.go +++ b/pkg/util/backoff.go @@ -70,6 +70,13 @@ func (p *Backoff) Next(id string, eventTime time.Time) { entry.lastUpdate = p.Clock.Now() } +// Reset forces clearing of all backoff data for a given key. +func (p *Backoff) Reset(id string) { + p.Lock() + defer p.Unlock() + delete(p.perItemBackoff, id) +} + // Returns True if the elapsed time since eventTime is smaller than the current backoff window func (p *Backoff) IsInBackOffSince(id string, eventTime time.Time) bool { p.Lock() diff --git a/pkg/util/backoff_test.go b/pkg/util/backoff_test.go index f2bc9771578..9035c565f45 100644 --- a/pkg/util/backoff_test.go +++ b/pkg/util/backoff_test.go @@ -46,6 +46,14 @@ func TestSlowBackoff(t *testing.T) { } b.Next(id, tc.Now()) } + + //Now confirm that the Reset cancels backoff. + b.Next(id, tc.Now()) + b.Reset(id) + if b.Get(id) != 0 { + t.Errorf("Reset didn't clear the backoff.") + } + } func TestBackoffReset(t *testing.T) { diff --git a/pkg/util/rand/rand.go b/pkg/util/rand/rand.go index 4da9f6da097..fe306506641 100644 --- a/pkg/util/rand/rand.go +++ b/pkg/util/rand/rand.go @@ -32,19 +32,12 @@ var rng = struct { rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())), } -// String generates a random alphanumeric string n characters long. This will -// panic if n is less than zero. -func String(n int) string { - if n < 0 { - panic("out-of-bounds value") - } - b := make([]rune, n) +// Intn generates an integer in range 0->max. +// By design this should panic if input is invalid, <= 0. +func Intn(max int) int { rng.Lock() defer rng.Unlock() - for i := range b { - b[i] = letters[rng.rand.Intn(numLetters)] - } - return string(b) + return rng.rand.Intn(max) } // Seed seeds the rng with the provided seed. @@ -62,3 +55,13 @@ func Perm(n int) []int { defer rng.Unlock() return rng.rand.Perm(n) } + +// String generates a random alphanumeric string n characters long. This will +// panic if n is less than zero. +func String(length int) string { + b := make([]rune, length) + for i := range b { + b[i] = letters[Intn(numLetters)] + } + return string(b) +} diff --git a/pkg/util/rand/rand_test.go b/pkg/util/rand/rand_test.go index 5ad109a3fa2..cc56e0d3d31 100644 --- a/pkg/util/rand/rand_test.go +++ b/pkg/util/rand/rand_test.go @@ -37,6 +37,27 @@ func TestString(t *testing.T) { } } +// Confirm that panic occurs on invalid input. +func TestRangePanic(t *testing.T) { + defer func() { + if err := recover(); err == nil { + t.Errorf("Panic didn't occur!") + } + }() + // Should result in an error... + Intn(0) +} + +func TestIntn(t *testing.T) { + // 0 is invalid. + for _, max := range []int{1, 2, 10, 123} { + inrange := Intn(max) + if inrange < 0 || inrange > max { + t.Errorf("%v out of range (0,%v)", inrange, max) + } + } +} + func TestPerm(t *testing.T) { Seed(5) rand.Seed(5)