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  }