You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.0 KiB

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