github.com/supragya/TendermintConnector@v0.0.0-20210619045051-113e32b84fb1/_deprecated_chains/cosmos/libs/common/repeat_timer_test.go (about) 1 package common 2 3 import ( 4 "sync" 5 "testing" 6 "time" 7 8 "github.com/fortytw2/leaktest" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func TestDefaultTicker(t *testing.T) { 13 ticker := defaultTickerMaker(time.Millisecond * 10) 14 <-ticker.Chan() 15 ticker.Stop() 16 } 17 18 func TestRepeatTimer(t *testing.T) { 19 20 ch := make(chan time.Time, 100) 21 mtx := new(sync.Mutex) 22 23 // tick() fires from start to end 24 // (exclusive) in milliseconds with incr. 25 // It locks on mtx, so subsequent calls 26 // run in series. 27 tick := func(startMs, endMs, incrMs time.Duration) { 28 mtx.Lock() 29 go func() { 30 for tMs := startMs; tMs < endMs; tMs += incrMs { 31 lt := time.Time{} 32 lt = lt.Add(tMs * time.Millisecond) 33 ch <- lt 34 } 35 mtx.Unlock() 36 }() 37 } 38 39 // tock consumes Ticker.Chan() events and checks them against the ms in "timesMs". 40 tock := func(t *testing.T, rt *RepeatTimer, timesMs []int64) { 41 42 // Check against timesMs. 43 for _, timeMs := range timesMs { 44 tyme := <-rt.Chan() 45 sinceMs := tyme.Sub(time.Time{}) / time.Millisecond 46 assert.Equal(t, timeMs, int64(sinceMs)) 47 } 48 49 // goroutines to ensure that 50 // no other times will fire. 51 // See https://github.com/tendermint/tendermint/libs/issues/120. 52 time.Sleep(time.Millisecond * 100) 53 done := true 54 select { 55 case <-rt.Chan(): 56 done = false 57 default: 58 } 59 assert.True(t, done) 60 } 61 62 tm := NewLogicalTickerMaker(ch) 63 rt := NewRepeatTimerWithTickerMaker("bar", time.Second, tm) 64 65 /* NOTE: Useful for debugging deadlocks... 66 go func() { 67 time.Sleep(time.Second * 3) 68 trace := make([]byte, 102400) 69 count := runtime.Stack(trace, true) 70 fmt.Printf("Stack of %d bytes: %s\n", count, trace) 71 }() 72 */ 73 74 tick(0, 1000, 10) 75 tock(t, rt, []int64{}) 76 tick(1000, 2000, 10) 77 tock(t, rt, []int64{1000}) 78 tick(2005, 5000, 10) 79 tock(t, rt, []int64{2005, 3005, 4005}) 80 tick(5001, 5999, 1) 81 // Read 5005 instead of 5001 because 82 // it's 1 second greater than 4005. 83 tock(t, rt, []int64{5005}) 84 tick(6000, 7005, 1) 85 tock(t, rt, []int64{6005}) 86 tick(7033, 8032, 1) 87 tock(t, rt, []int64{7033}) 88 89 // After a reset, nothing happens 90 // until two ticks are received. 91 rt.Reset() 92 tock(t, rt, []int64{}) 93 tick(8040, 8041, 1) 94 tock(t, rt, []int64{}) 95 tick(9555, 9556, 1) 96 tock(t, rt, []int64{9555}) 97 98 // After a stop, nothing more is sent. 99 rt.Stop() 100 tock(t, rt, []int64{}) 101 102 // Another stop panics. 103 assert.Panics(t, func() { rt.Stop() }) 104 } 105 106 func TestRepeatTimerReset(t *testing.T) { 107 // check that we are not leaking any go-routines 108 defer leaktest.Check(t)() 109 110 timer := NewRepeatTimer("test", 20*time.Millisecond) 111 defer timer.Stop() 112 113 // test we don't receive tick before duration ms. 114 select { 115 case <-timer.Chan(): 116 t.Fatal("did not expect to receive tick") 117 default: 118 } 119 120 timer.Reset() 121 122 // test we receive tick after Reset is called 123 select { 124 case <-timer.Chan(): 125 // all good 126 case <-time.After(40 * time.Millisecond): 127 t.Fatal("expected to receive tick after reset") 128 } 129 130 // just random calls 131 for i := 0; i < 100; i++ { 132 time.Sleep(time.Duration(RandIntn(40)) * time.Millisecond) 133 timer.Reset() 134 } 135 }