github.com/jeffjen/go-libkv@v0.0.0-20151212051932-5df59a45a168/timer/timer_test.go (about) 1 package timer 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 "time" 8 ) 9 10 type Expire struct { 11 iden int 12 wg *sync.WaitGroup 13 } 14 15 func (e Expire) Done(jobId int64) { 16 fmt.Printf("triggered expired [%d] - [%d] - [%s]\n", e.iden, jobId, time.Now()) 17 e.wg.Done() 18 } 19 20 func TestSchedTimer(t *testing.T) { 21 exp := NewTimer() 22 23 exp.Tic() 24 defer exp.Toc() // schedule expire worker 25 26 var ( 27 wg sync.WaitGroup 28 29 cases = []time.Duration{ 30 300 * time.Millisecond, 31 5 * time.Second, 32 1 * time.Second, 33 } 34 35 end = make(chan struct{}) 36 ) 37 38 wg.Add(len(cases)) 39 go func() { 40 wg.Wait() 41 close(end) 42 }() 43 44 now := time.Now() 45 fmt.Printf("begin TestSchedTimer %v\n", now) 46 47 for idx, c := range cases { 48 exp.Sched(now.Add(c), Expire{idx, &wg}) 49 } 50 51 select { 52 case <-end: 53 return 54 case <-time.After(1 * time.Minute): 55 t.Errorf("Unable to complete test") 56 } 57 } 58 59 func TestBurstSched(t *testing.T) { 60 exp := NewTimer() 61 62 exp.Tic() 63 defer exp.Toc() // schedule expire worker 64 65 var ( 66 wg sync.WaitGroup 67 68 schedNumHandler = 10000 69 70 end = make(chan struct{}) 71 ) 72 73 wg.Add(schedNumHandler) 74 go func() { 75 wg.Wait() 76 close(end) 77 }() 78 79 now := time.Now() 80 fmt.Printf("begin TestBurstSched %v\n", now) 81 82 for idx := 0; idx < schedNumHandler; idx += 1 { 83 exp.SchedFunc(now.Add(1*time.Millisecond), func(jobId int64) { 84 wg.Done() 85 }) 86 } 87 88 select { 89 case <-end: 90 return 91 case <-time.After(time.Duration(schedNumHandler) * time.Millisecond): 92 t.Errorf("Unable to complete test") 93 } 94 } 95 96 func TestCancel(t *testing.T) { 97 exp := NewTimer() 98 99 exp.Tic() 100 defer exp.Toc() // schedule expire worker 101 102 now := time.Now() 103 fmt.Printf("begin TestCancel %v\n", now) 104 105 resp := make(chan int, 1) 106 107 iden := exp.SchedFunc(now.Add(10*time.Second), func(id int64) { 108 fmt.Printf("work order [%d;%d] triggered at %v\n", 1, id, time.Now()) 109 resp <- 1 110 }) 111 112 exp.SchedFunc(now.Add(2*time.Second), func(id int64) { 113 fmt.Printf("work order [%d;%d] triggered at %v\n", 2, id, time.Now()) 114 resp <- 2 115 }) 116 117 woe := time.After(10 * time.Second) 118 for { 119 select { 120 case v := <-resp: 121 if v != 2 { 122 t.Errorf("Failed to cancel work %d", v) 123 } else { 124 exp.Cancel(iden) // cancel the first one 125 } 126 case <-woe: 127 return 128 } 129 } 130 } 131 132 func TestUpdate(t *testing.T) { 133 exp := NewTimer() 134 135 exp.Tic() 136 defer exp.Toc() // schedule expire worker 137 138 now := time.Now() 139 fmt.Printf("begin TestUpdate %v\n", now) 140 141 resp := make(chan int, 1) 142 143 iden := exp.SchedFunc(now.Add(10*time.Second), func(jobId int64) { 144 resp <- 1 145 }) 146 147 trigger := time.After(2 * time.Second) 148 woe := time.After(5 * time.Second) 149 for { 150 select { 151 case <-resp: 152 return 153 case <-trigger: 154 exp.Update(iden, time.Now().Add(1*time.Second)) 155 case <-woe: 156 t.Errorf("Failed to update scheduled work") 157 } 158 } 159 } 160 161 func TestRepeat(t *testing.T) { 162 exp := NewTimer() 163 164 exp.Tic() 165 defer exp.Toc() // schedule expire worker 166 167 now := time.Now() 168 fmt.Printf("begin TestRepeat %v\n", now) 169 170 resp := make(chan int, 1) 171 172 iden := exp.RepeatFunc(1*time.Second, 1, func(jobId int64) { 173 resp <- 1 174 }) 175 176 history, counter := 0, 0 177 178 pre := time.After(5 * time.Second) 179 end := time.After(10 * time.Second) 180 for { 181 select { 182 case <-resp: 183 counter += 1 184 case <-pre: 185 exp.Cancel(iden) 186 if counter == 0 { 187 t.Errorf("Failed to repeat scheduled work") 188 } else { 189 fmt.Printf("work order repated %d times\n", counter) 190 } 191 history = counter 192 case <-end: 193 if history != counter { 194 t.Errorf("Failed to cancel repeat work") 195 } 196 return 197 } 198 } 199 } 200 201 func TestRepeatRateLimit(t *testing.T) { 202 exp := NewTimer() 203 204 exp.Tic() 205 defer exp.Toc() // schedule expire worker 206 207 now := time.Now() 208 fmt.Printf("begin TestRepeatRateLimit %v\n", now) 209 210 resp := make(chan int, 1) 211 212 iden := exp.RepeatFunc(1*time.Millisecond, 5, func(jobId int64) { 213 <-time.After(1 * time.Second) 214 resp <- 1 215 }) 216 217 counter := 0 218 219 end := time.After(5 * time.Second) 220 for { 221 select { 222 case <-resp: 223 counter += 1 224 case <-end: 225 exp.Cancel(iden) 226 fmt.Printf("Handler invoked: %d times\n", counter) 227 return 228 } 229 } 230 } 231 232 func BenchmarkSchedFunc(b *testing.B) { 233 exp := NewTimer() 234 235 exp.Tic() 236 defer exp.Toc() // schedule expire worker 237 238 const N = 10000 239 240 handle := func(jobId int64) {} 241 242 future := time.Now().Add(1 * time.Hour) 243 244 for idx := 0; idx < N; idx++ { 245 exp.SchedFunc(future, handle) 246 } 247 }