github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/timer_test.go (about) 1 package f_test 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/angenalZZZ/gofunc/f" 9 ) 10 11 func ExampleTimer_Start() { 12 tw := f.NewTimer(time.Millisecond, 20) 13 tw.Start() 14 defer tw.Stop() 15 16 exitC := make(chan time.Time, 1) 17 tw.AfterFunc(time.Second, func() { 18 fmt.Println("The timer fires") 19 exitC <- time.Now().UTC() 20 }) 21 22 <-exitC 23 24 // Output: 25 // The timer fires 26 } 27 28 func ExampleTimer_Stop() { 29 tw := f.NewTimer(time.Millisecond, 20) 30 tw.Start() 31 defer tw.Stop() 32 33 t := tw.AfterFunc(time.Second, func() { 34 fmt.Println("The timer fires") 35 }) 36 37 <-time.After(900 * time.Millisecond) 38 // Stop the timer before it fires 39 t.Stop() 40 41 // Output: 42 // 43 } 44 45 func TestTimerBucket_Flush(t *testing.T) { 46 b := f.NewTimerBucket() 47 48 b.Add(&f.TimerElement{}) 49 b.Add(&f.TimerElement{}) 50 l1 := b.Timers.Len() 51 if l1 != 2 { 52 t.Fatalf("Got (%+v) != Want (%+v)", l1, 2) 53 } 54 55 b.Flush(func(*f.TimerElement) {}) 56 l2 := b.Timers.Len() 57 if l2 != 0 { 58 t.Fatalf("Got (%+v) != Want (%+v)", l2, 0) 59 } 60 } 61 62 func TestTimer_AfterFunc(t *testing.T) { 63 tw := f.NewTimer(time.Millisecond, 20) 64 tw.Start() 65 defer tw.Stop() 66 67 durations := []time.Duration{ 68 1 * time.Millisecond, 69 5 * time.Millisecond, 70 10 * time.Millisecond, 71 50 * time.Millisecond, 72 100 * time.Millisecond, 73 500 * time.Millisecond, 74 1 * time.Second, 75 } 76 for _, d := range durations { 77 t.Run("", func(t *testing.T) { 78 exitC := make(chan time.Time) 79 80 start := time.Now().UTC() 81 tw.AfterFunc(d, func() { 82 exitC <- time.Now().UTC() 83 }) 84 85 got := (<-exitC).Truncate(time.Millisecond) 86 min := start.Add(d).Truncate(time.Millisecond) 87 88 err := 5 * time.Millisecond 89 if got.Before(min) || got.After(min.Add(err)) { 90 t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", d, min, min.Add(err), got) 91 } 92 }) 93 } 94 } 95 96 type anTimerScheduler struct { 97 intervals []time.Duration 98 current int 99 } 100 101 func (s *anTimerScheduler) Next(prev time.Time) time.Time { 102 if s.current >= len(s.intervals) { 103 return time.Time{} 104 } 105 next := prev.Add(s.intervals[s.current]) 106 s.current++ 107 return next 108 } 109 110 func TestTimer_ScheduleFunc(t *testing.T) { 111 tw := f.NewTimer(time.Millisecond, 20) 112 tw.Start() 113 defer tw.Stop() 114 115 s := &anTimerScheduler{intervals: []time.Duration{ 116 1 * time.Millisecond, // start + 1ms 117 4 * time.Millisecond, // start + 5ms 118 5 * time.Millisecond, // start + 10ms 119 40 * time.Millisecond, // start + 50ms 120 50 * time.Millisecond, // start + 100ms 121 400 * time.Millisecond, // start + 500ms 122 500 * time.Millisecond, // start + 1s 123 }} 124 125 exitC := make(chan time.Time, len(s.intervals)) 126 127 start := time.Now().UTC() 128 tw.ScheduleFunc(s, func() { 129 exitC <- time.Now().UTC() 130 }) 131 132 accum := time.Duration(0) 133 for _, d := range s.intervals { 134 got := (<-exitC).Truncate(time.Millisecond) 135 accum += d 136 min := start.Add(accum).Truncate(time.Millisecond) 137 138 err := 5 * time.Millisecond 139 if got.Before(min) || got.After(min.Add(err)) { 140 t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", accum, min, min.Add(err), got) 141 } 142 } 143 }