package common import ( "sync" "testing" "time" "github.com/stretchr/testify/assert" ) func TestDefaultTicker(t *testing.T) { ticker := defaultTickerMaker(time.Millisecond * 10) <-ticker.Chan() ticker.Stop() } func TestRepeatTimer(t *testing.T) { ch := make(chan time.Time, 100) mtx := new(sync.Mutex) // tick() fires from start to end // (exclusive) in milliseconds with incr. // It locks on mtx, so subsequent calls // run in series. tick := func(startMs, endMs, incrMs time.Duration) { mtx.Lock() go func() { for tMs := startMs; tMs < endMs; tMs += incrMs { lt := time.Time{} lt = lt.Add(tMs * time.Millisecond) ch <- lt } mtx.Unlock() }() } // tock consumes Ticker.Chan() events and checks them against the ms in "timesMs". tock := func(t *testing.T, rt *RepeatTimer, timesMs []int64) { // Check against timesMs. for _, timeMs := range timesMs { tyme := <-rt.Chan() sinceMs := tyme.Sub(time.Time{}) / time.Millisecond assert.Equal(t, timeMs, int64(sinceMs)) } // TODO detect number of running // goroutines to ensure that // no other times will fire. // See https://github.com/tendermint/tmlibs/issues/120. time.Sleep(time.Millisecond * 100) done := true select { case <-rt.Chan(): done = false default: } assert.True(t, done) } tm := NewLogicalTickerMaker(ch) rt := NewRepeatTimerWithTickerMaker("bar", time.Second, tm) /* NOTE: Useful for debugging deadlocks... go func() { time.Sleep(time.Second * 3) trace := make([]byte, 102400) count := runtime.Stack(trace, true) fmt.Printf("Stack of %d bytes: %s\n", count, trace) }() */ tick(0, 1000, 10) tock(t, rt, []int64{}) tick(1000, 2000, 10) tock(t, rt, []int64{1000}) tick(2005, 5000, 10) tock(t, rt, []int64{2005, 3005, 4005}) tick(5001, 5999, 1) // Read 5005 instead of 5001 because // it's 1 second greater than 4005. tock(t, rt, []int64{5005}) tick(6000, 7005, 1) tock(t, rt, []int64{6005}) tick(7033, 8032, 1) tock(t, rt, []int64{7033}) // After a reset, nothing happens // until two ticks are received. rt.Reset() tock(t, rt, []int64{}) tick(8040, 8041, 1) tock(t, rt, []int64{}) tick(9555, 9556, 1) tock(t, rt, []int64{9555}) // After a stop, nothing more is sent. rt.Stop() tock(t, rt, []int64{}) // Another stop panics. assert.Panics(t, func() { rt.Stop() }) }