github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/util/retry_test.go (about) 1 package util 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/pkg/errors" 8 . "github.com/smartystreets/goconvey/convey" 9 ) 10 11 const TestRetries = 5 12 const TestSleep = 10 * time.Millisecond 13 const TriesTillPass = 2 14 15 func TestRetriesUsedUp(t *testing.T) { 16 Convey("When retrying a function that never succeeds", t, func() { 17 18 failingFunc := func() error { 19 return RetriableError{errors.New("something went wrong")} 20 } 21 22 start := time.Now() 23 retryFail, err := Retry(failingFunc, TestRetries, TestSleep) 24 end := time.Now() 25 26 Convey("calling it with Retry should return an error", func() { 27 So(err, ShouldNotBeNil) 28 }) 29 Convey("the 'retried till failure' flag should be true", func() { 30 So(retryFail, ShouldBeTrue) 31 }) 32 Convey("Time spent doing Retry() should be total time sleeping", func() { 33 So(end, ShouldHappenOnOrAfter, start.Add((TestRetries-1)*TestSleep)) 34 }) 35 }) 36 } 37 38 func TestRetryUntilSuccess(t *testing.T) { 39 Convey("When retrying a function that succeeds after 3 tries", t, func() { 40 41 tryCounter := TriesTillPass 42 retryPassingFunc := func() error { 43 tryCounter-- 44 if tryCounter <= 0 { 45 return nil 46 } 47 return RetriableError{errors.New("something went wrong")} 48 } 49 50 start := time.Now() 51 retryFail, err := Retry(retryPassingFunc, TestRetries, TestSleep) 52 end := time.Now() 53 54 Convey("calling it with Retry should not return any error", func() { 55 So(err, ShouldBeNil) 56 }) 57 Convey("the 'retried till failure' flag should be false", func() { 58 So(retryFail, ShouldBeFalse) 59 }) 60 Convey("time spent should be retry sleep * attempts needed to pass", func() { 61 backoff := getBackoff(TestSleep, TestRetries) 62 63 So(end, ShouldHappenOnOrAfter, start.Add((TriesTillPass-1)*TestSleep)) 64 So(end, ShouldHappenBefore, start.Add(backoff.Max)) 65 }) 66 67 }) 68 } 69 70 func TestNonRetriableFailure(t *testing.T) { 71 Convey("When retrying a func that returns non-retriable err", t, func() { 72 failingFuncNoRetry := func() error { 73 return errors.New("something went wrong") 74 } 75 76 retryFail, err := Retry(failingFuncNoRetry, TestRetries, TestSleep) 77 78 Convey("calling it with Retry should return an error", func() { 79 So(err, ShouldNotBeNil) 80 }) 81 Convey("the 'retried till failure' flag should be false", func() { 82 So(retryFail, ShouldBeFalse) 83 }) 84 }) 85 }