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.

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