github.com/cenkalti/backoff/v4@v4.2.1/ticker_test.go (about) 1 package backoff 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "log" 8 "testing" 9 ) 10 11 func TestTicker(t *testing.T) { 12 const successOn = 3 13 var i = 0 14 15 // This function is successful on "successOn" calls. 16 f := func() error { 17 i++ 18 log.Printf("function is called %d. time\n", i) 19 20 if i == successOn { 21 log.Println("OK") 22 return nil 23 } 24 25 log.Println("error") 26 return errors.New("error") 27 } 28 29 b := NewExponentialBackOff() 30 ticker := NewTickerWithTimer(b, &testTimer{}) 31 32 var err error 33 for range ticker.C { 34 if err = f(); err != nil { 35 t.Log(err) 36 continue 37 } 38 39 break 40 } 41 if err != nil { 42 t.Errorf("unexpected error: %s", err.Error()) 43 } 44 if i != successOn { 45 t.Errorf("invalid number of retries: %d", i) 46 } 47 } 48 49 func TestTickerContext(t *testing.T) { 50 var i = 0 51 52 ctx, cancel := context.WithCancel(context.Background()) 53 54 // Cancel context as soon as it is created. 55 // Ticker must stop after first tick. 56 cancel() 57 58 // This function cancels context on "cancelOn" calls. 59 f := func() error { 60 i++ 61 log.Printf("function is called %d. time\n", i) 62 log.Println("error") 63 return fmt.Errorf("error (%d)", i) 64 } 65 66 b := WithContext(NewConstantBackOff(0), ctx) 67 ticker := NewTickerWithTimer(b, &testTimer{}) 68 69 var err error 70 for range ticker.C { 71 if err = f(); err != nil { 72 t.Log(err) 73 continue 74 } 75 76 ticker.Stop() 77 break 78 } 79 // Ticker is guaranteed to tick at least once. 80 if err == nil { 81 t.Errorf("error is unexpectedly nil") 82 } 83 if err.Error() != "error (1)" { 84 t.Errorf("unexpected error: %s", err) 85 } 86 if i != 1 { 87 t.Errorf("invalid number of retries: %d", i) 88 } 89 } 90 91 func TestTickerDefaultTimer(t *testing.T) { 92 b := NewExponentialBackOff() 93 ticker := NewTickerWithTimer(b, nil) 94 // ensure a timer was actually assigned, instead of remaining as nil. 95 <-ticker.C 96 }