blob: 9908e220f041817e640eab099d1f5a79789b8709 [file] [log] [blame]
Christopher Wedgwood1e664282010-02-04 13:09:02 -08001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package time_test
6
7import (
Russ Coxeb692922011-11-01 22:05:34 -04008 "errors"
Andrew Gerrandd54c4ec2011-03-30 11:40:00 +11009 "fmt"
Dmitriy Vyukovdc6726b2011-11-14 21:59:48 +030010 "runtime"
Roger Peppee2d15952010-12-06 14:19:30 -050011 "sort"
Dmitriy Vyukovdc6726b2011-11-14 21:59:48 +030012 "sync/atomic"
Russ Cox965845a2011-11-02 15:54:16 -040013 "testing"
Christopher Wedgwood1e664282010-02-04 13:09:02 -080014 . "time"
15)
16
17func TestSleep(t *testing.T) {
Russ Coxefe3d352011-11-30 11:59:44 -050018 const delay = 100 * Millisecond
Christopher Wedgwood1e664282010-02-04 13:09:02 -080019 go func() {
20 Sleep(delay / 2)
Russ Cox75d337e2011-08-26 15:15:23 -040021 Interrupt()
Christopher Wedgwood1e664282010-02-04 13:09:02 -080022 }()
Russ Coxefe3d352011-11-30 11:59:44 -050023 start := Now()
Christopher Wedgwood1e664282010-02-04 13:09:02 -080024 Sleep(delay)
Russ Coxefe3d352011-11-30 11:59:44 -050025 duration := Now().Sub(start)
Christopher Wedgwood1e664282010-02-04 13:09:02 -080026 if duration < delay {
Russ Coxefe3d352011-11-30 11:59:44 -050027 t.Fatalf("Sleep(%s) slept for only %s", delay, duration)
Christopher Wedgwood1e664282010-02-04 13:09:02 -080028 }
29}
Andrew Gerrand1e66a212010-10-11 13:45:26 +110030
Roger Peppe212e0742011-01-10 11:51:38 -080031// Test the basic function calling behavior. Correct queueing
32// behavior is tested elsewhere, since After and AfterFunc share
33// the same code.
34func TestAfterFunc(t *testing.T) {
35 i := 10
36 c := make(chan bool)
37 var f func()
38 f = func() {
39 i--
40 if i >= 0 {
41 AfterFunc(0, f)
David Symonds2949f3b2011-12-08 15:42:44 +110042 Sleep(1 * Second)
Roger Peppe212e0742011-01-10 11:51:38 -080043 } else {
44 c <- true
45 }
46 }
47
48 AfterFunc(0, f)
49 <-c
50}
51
Dmitriy Vyukovdc6726b2011-11-14 21:59:48 +030052func TestAfterStress(t *testing.T) {
53 stop := uint32(0)
54 go func() {
55 for atomic.LoadUint32(&stop) == 0 {
56 runtime.GC()
Alex Brainmane0aa26a2013-01-18 15:31:01 +110057 // Yield so that the OS can wake up the timer thread,
58 // so that it can generate channel sends for the main goroutine,
59 // which will eventually set stop = 1 for us.
60 Sleep(Nanosecond)
Dmitriy Vyukovdc6726b2011-11-14 21:59:48 +030061 }
62 }()
63 c := Tick(1)
64 for i := 0; i < 100; i++ {
65 <-c
66 }
67 atomic.StoreUint32(&stop, 1)
68}
69
Roger Peppe212e0742011-01-10 11:51:38 -080070func BenchmarkAfterFunc(b *testing.B) {
71 i := b.N
72 c := make(chan bool)
73 var f func()
74 f = func() {
75 i--
76 if i >= 0 {
77 AfterFunc(0, f)
78 } else {
79 c <- true
80 }
81 }
82
83 AfterFunc(0, f)
84 <-c
85}
86
Roger Peppe2ae953b2011-01-25 12:25:48 -080087func BenchmarkAfter(b *testing.B) {
88 for i := 0; i < b.N; i++ {
89 <-After(1)
90 }
91}
92
93func BenchmarkStop(b *testing.B) {
94 for i := 0; i < b.N; i++ {
David Symonds2949f3b2011-12-08 15:42:44 +110095 NewTimer(1 * Second).Stop()
Roger Peppe2ae953b2011-01-25 12:25:48 -080096 }
97}
98
Andrew Gerrand1e66a212010-10-11 13:45:26 +110099func TestAfter(t *testing.T) {
Russ Coxefe3d352011-11-30 11:59:44 -0500100 const delay = 100 * Millisecond
101 start := Now()
Andrew Gerrand1e66a212010-10-11 13:45:26 +1100102 end := <-After(delay)
Russ Coxefe3d352011-11-30 11:59:44 -0500103 if duration := Now().Sub(start); duration < delay {
104 t.Fatalf("After(%s) slept for only %d ns", delay, duration)
Andrew Gerrand1e66a212010-10-11 13:45:26 +1100105 }
Russ Coxefe3d352011-11-30 11:59:44 -0500106 if min := start.Add(delay); end.Before(min) {
107 t.Fatalf("After(%s) expect >= %s, got %s", delay, min, end)
Andrew Gerrand1e66a212010-10-11 13:45:26 +1100108 }
109}
Roger Peppee2d15952010-12-06 14:19:30 -0500110
111func TestAfterTick(t *testing.T) {
Rémy Oudompheng2a6e6992012-02-14 22:13:19 +0100112 const Count = 10
113 Delta := 100 * Millisecond
114 if testing.Short() {
115 Delta = 10 * Millisecond
116 }
Russ Coxefe3d352011-11-30 11:59:44 -0500117 t0 := Now()
Roger Peppee2d15952010-12-06 14:19:30 -0500118 for i := 0; i < Count; i++ {
119 <-After(Delta)
120 }
Russ Coxefe3d352011-11-30 11:59:44 -0500121 t1 := Now()
122 d := t1.Sub(t0)
123 target := Delta * Count
Brad Fitzpatrick8c529052012-02-29 13:14:05 -0800124 if d < target*9/10 {
125 t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target)
126 }
127 if !testing.Short() && d > target*30/10 {
128 t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target)
Roger Peppee2d15952010-12-06 14:19:30 -0500129 }
130}
131
Roger Peppe2ae953b2011-01-25 12:25:48 -0800132func TestAfterStop(t *testing.T) {
David Symonds2949f3b2011-12-08 15:42:44 +1100133 AfterFunc(100*Millisecond, func() {})
134 t0 := NewTimer(50 * Millisecond)
Roger Peppe2ae953b2011-01-25 12:25:48 -0800135 c1 := make(chan bool, 1)
David Symonds2949f3b2011-12-08 15:42:44 +1100136 t1 := AfterFunc(150*Millisecond, func() { c1 <- true })
137 c2 := After(200 * Millisecond)
Roger Peppe2ae953b2011-01-25 12:25:48 -0800138 if !t0.Stop() {
139 t.Fatalf("failed to stop event 0")
140 }
141 if !t1.Stop() {
142 t.Fatalf("failed to stop event 1")
143 }
144 <-c2
Russ Coxf4e76d82011-01-31 18:36:28 -0500145 select {
146 case <-t0.C:
147 t.Fatalf("event 0 was not stopped")
148 case <-c1:
149 t.Fatalf("event 1 was not stopped")
150 default:
Roger Peppe2ae953b2011-01-25 12:25:48 -0800151 }
152 if t1.Stop() {
153 t.Fatalf("Stop returned true twice")
154 }
155}
156
Andrew Gerrandd54c4ec2011-03-30 11:40:00 +1100157func TestAfterQueuing(t *testing.T) {
158 // This test flakes out on some systems,
159 // so we'll try it a few times before declaring it a failure.
160 const attempts = 3
Russ Coxeb692922011-11-01 22:05:34 -0400161 err := errors.New("!=nil")
Andrew Gerrandd54c4ec2011-03-30 11:40:00 +1100162 for i := 0; i < attempts && err != nil; i++ {
163 if err = testAfterQueuing(t); err != nil {
164 t.Logf("attempt %v failed: %v", i, err)
165 }
166 }
167 if err != nil {
168 t.Fatal(err)
169 }
170}
171
Roger Peppee2d15952010-12-06 14:19:30 -0500172var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8, 0}
173
174type afterResult struct {
175 slot int
Russ Coxefe3d352011-11-30 11:59:44 -0500176 t Time
Roger Peppee2d15952010-12-06 14:19:30 -0500177}
178
Russ Coxefe3d352011-11-30 11:59:44 -0500179func await(slot int, result chan<- afterResult, ac <-chan Time) {
Roger Peppee2d15952010-12-06 14:19:30 -0500180 result <- afterResult{slot, <-ac}
181}
182
Russ Coxeb692922011-11-01 22:05:34 -0400183func testAfterQueuing(t *testing.T) error {
Rémy Oudompheng2a6e6992012-02-14 22:13:19 +0100184 Delta := 100 * Millisecond
185 if testing.Short() {
186 Delta = 20 * Millisecond
187 }
Roger Peppee2d15952010-12-06 14:19:30 -0500188 // make the result channel buffered because we don't want
189 // to depend on channel queueing semantics that might
190 // possibly change in the future.
191 result := make(chan afterResult, len(slots))
192
Russ Coxefe3d352011-11-30 11:59:44 -0500193 t0 := Now()
Roger Peppee2d15952010-12-06 14:19:30 -0500194 for _, slot := range slots {
Russ Coxefe3d352011-11-30 11:59:44 -0500195 go await(slot, result, After(Duration(slot)*Delta))
Roger Peppee2d15952010-12-06 14:19:30 -0500196 }
Andrew Gerrand5bcbcab32011-07-08 10:52:50 +1000197 sort.Ints(slots)
Roger Peppee2d15952010-12-06 14:19:30 -0500198 for _, slot := range slots {
199 r := <-result
200 if r.slot != slot {
Russ Coxefe3d352011-11-30 11:59:44 -0500201 return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
Roger Peppee2d15952010-12-06 14:19:30 -0500202 }
Russ Coxefe3d352011-11-30 11:59:44 -0500203 dt := r.t.Sub(t0)
204 target := Duration(slot) * Delta
Russ Coxfc7b9fc2011-12-12 18:33:47 -0500205 if dt < target-Delta/2 || dt > target+Delta*10 {
206 return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-Delta/2, target+Delta*10)
Roger Peppee2d15952010-12-06 14:19:30 -0500207 }
208 }
Andrew Gerrandd54c4ec2011-03-30 11:40:00 +1100209 return nil
Roger Peppee2d15952010-12-06 14:19:30 -0500210}
Dmitriy Vyukova899a462011-11-25 14:13:10 +0300211
212func TestTimerStopStress(t *testing.T) {
213 if testing.Short() {
214 return
215 }
216 for i := 0; i < 100; i++ {
217 go func(i int) {
David Symonds2949f3b2011-12-08 15:42:44 +1100218 timer := AfterFunc(2*Second, func() {
Dmitriy Vyukova899a462011-11-25 14:13:10 +0300219 t.Fatalf("timer %d was not stopped", i)
220 })
David Symonds2949f3b2011-12-08 15:42:44 +1100221 Sleep(1 * Second)
Dmitriy Vyukova899a462011-11-25 14:13:10 +0300222 timer.Stop()
223 }(i)
224 }
David Symonds2949f3b2011-12-08 15:42:44 +1100225 Sleep(3 * Second)
Dmitriy Vyukova899a462011-11-25 14:13:10 +0300226}
Dmitriy Vyukova0efca82012-05-29 22:30:56 +0400227
228func TestSleepZeroDeadlock(t *testing.T) {
229 // Sleep(0) used to hang, the sequence of events was as follows.
230 // Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
231 // Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
232 // After the GC nobody wakes up the goroutine from Gwaiting status.
233 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
234 c := make(chan bool)
235 go func() {
236 for i := 0; i < 100; i++ {
237 runtime.GC()
238 }
239 c <- true
240 }()
241 for i := 0; i < 100; i++ {
242 Sleep(0)
243 tmp := make(chan bool, 1)
244 tmp <- true
245 <-tmp
246 }
247 <-c
248}
Volker Dobler44ff17e2013-01-17 14:41:53 +1100249
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800250func testReset(d Duration) error {
251 t0 := NewTimer(2 * d)
252 Sleep(d)
253 if t0.Reset(3*d) != true {
254 return errors.New("resetting unfired timer returned false")
Volker Dobler44ff17e2013-01-17 14:41:53 +1100255 }
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800256 Sleep(2 * d)
Volker Dobler44ff17e2013-01-17 14:41:53 +1100257 select {
258 case <-t0.C:
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800259 return errors.New("timer fired early")
Volker Dobler44ff17e2013-01-17 14:41:53 +1100260 default:
261 }
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800262 Sleep(2 * d)
Volker Dobler44ff17e2013-01-17 14:41:53 +1100263 select {
264 case <-t0.C:
265 default:
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800266 return errors.New("reset timer did not fire")
Volker Dobler44ff17e2013-01-17 14:41:53 +1100267 }
268
269 if t0.Reset(50*Millisecond) != false {
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800270 return errors.New("resetting expired timer returned true")
Volker Dobler44ff17e2013-01-17 14:41:53 +1100271 }
Brad Fitzpatrick86a8d592013-01-22 17:25:58 -0800272 return nil
273}
274
275func TestReset(t *testing.T) {
276 // We try to run this test with increasingly larger multiples
277 // until one works so slow, loaded hardware isn't as flaky,
278 // but without slowing down fast machines unnecessarily.
279 const unit = 25 * Millisecond
280 tries := []Duration{
281 1 * unit,
282 3 * unit,
283 7 * unit,
284 15 * unit,
285 }
286 var err error
287 for _, d := range tries {
288 err = testReset(d)
289 if err == nil {
290 t.Logf("passed using duration %v", d)
291 return
292 }
293 }
294 t.Error(err)
Volker Dobler44ff17e2013-01-17 14:41:53 +1100295}
Andrew Gerrand89cf67e2013-02-26 09:23:58 +1100296
297// Test that sleeping for an interval so large it overflows does not
298// result in a short sleep duration.
299func TestOverflowSleep(t *testing.T) {
300 const timeout = 25 * Millisecond
301 const big = Duration(int64(1<<63 - 1))
302 select {
303 case <-After(big):
304 t.Fatalf("big timeout fired")
305 case <-After(timeout):
306 // OK
307 }
308 const neg = Duration(-1 << 63)
309 select {
310 case <-After(neg):
311 // OK
312 case <-After(timeout):
313 t.Fatalf("negative timeout didn't fire")
314 }
315}