]>
Commit | Line | Data |
---|---|---|
7a938933 ILT |
1 | // 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 | ||
5 | package time_test | |
6 | ||
7 | import ( | |
5a8ea165 ILT |
8 | "fmt" |
9 | "runtime" | |
7a938933 ILT |
10 | "testing" |
11 | . "time" | |
12 | ) | |
13 | ||
14 | func TestTicker(t *testing.T) { | |
5a8ea165 ILT |
15 | // We want to test that a ticker takes as much time as expected. |
16 | // Since we don't want the test to run for too long, we don't | |
17 | // want to use lengthy times. This makes the test inherently flaky. | |
18 | // So only report an error if it fails five times in a row. | |
19 | ||
20 | count := 10 | |
21 | delta := 20 * Millisecond | |
22 | ||
23 | // On Darwin ARM64 the tick frequency seems limited. Issue 35692. | |
cfcbb422 | 24 | if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" { |
f75af8c1 ILT |
25 | // The following test will run ticker count/2 times then reset |
26 | // the ticker to double the duration for the rest of count/2. | |
27 | // Since tick frequency is limited on Darwin ARM64, use even | |
28 | // number to give the ticks more time to let the test pass. | |
29 | // See CL 220638. | |
30 | count = 6 | |
5a8ea165 | 31 | delta = 100 * Millisecond |
7a938933 | 32 | } |
5a8ea165 ILT |
33 | |
34 | var errs []string | |
35 | logErrs := func() { | |
36 | for _, e := range errs { | |
37 | t.Log(e) | |
38 | } | |
7a938933 | 39 | } |
5a8ea165 ILT |
40 | |
41 | for i := 0; i < 5; i++ { | |
42 | ticker := NewTicker(delta) | |
43 | t0 := Now() | |
f75af8c1 ILT |
44 | for i := 0; i < count/2; i++ { |
45 | <-ticker.C | |
46 | } | |
47 | ticker.Reset(delta * 2) | |
48 | for i := count / 2; i < count; i++ { | |
5a8ea165 ILT |
49 | <-ticker.C |
50 | } | |
51 | ticker.Stop() | |
52 | t1 := Now() | |
53 | dt := t1.Sub(t0) | |
f75af8c1 | 54 | target := 3 * delta * Duration(count/2) |
c5b21c3f | 55 | slop := target * 3 / 10 |
5a8ea165 | 56 | if dt < target-slop || dt > target+slop { |
c5b21c3f ILT |
57 | errs = append(errs, fmt.Sprintf("%d %s ticks then %d %s ticks took %s, expected [%s,%s]", count/2, delta, count/2, delta*2, dt, target-slop, target+slop)) |
58 | if dt > target+slop { | |
59 | // System may be overloaded; sleep a bit | |
60 | // in the hopes it will recover. | |
61 | Sleep(Second / 2) | |
62 | } | |
5a8ea165 ILT |
63 | continue |
64 | } | |
65 | // Now test that the ticker stopped. | |
66 | Sleep(2 * delta) | |
67 | select { | |
68 | case <-ticker.C: | |
69 | errs = append(errs, "Ticker did not shut down") | |
70 | continue | |
71 | default: | |
72 | // ok | |
73 | } | |
74 | ||
75 | // Test passed, so all done. | |
76 | if len(errs) > 0 { | |
77 | t.Logf("saw %d errors, ignoring to avoid flakiness", len(errs)) | |
78 | logErrs() | |
79 | } | |
80 | ||
81 | return | |
7a938933 | 82 | } |
5a8ea165 ILT |
83 | |
84 | t.Errorf("saw %d errors", len(errs)) | |
85 | logErrs() | |
7a938933 ILT |
86 | } |
87 | ||
1a2f01ef ILT |
88 | // Issue 21874 |
89 | func TestTickerStopWithDirectInitialization(t *testing.T) { | |
90 | c := make(chan Time) | |
91 | tk := &Ticker{C: c} | |
92 | tk.Stop() | |
93 | } | |
94 | ||
22b955cc | 95 | // Test that a bug tearing down a ticker has been fixed. This routine should not deadlock. |
7a938933 | 96 | func TestTeardown(t *testing.T) { |
cbb6491d ILT |
97 | Delta := 100 * Millisecond |
98 | if testing.Short() { | |
99 | Delta = 20 * Millisecond | |
100 | } | |
7a938933 | 101 | for i := 0; i < 3; i++ { |
cbb6491d | 102 | ticker := NewTicker(Delta) |
7a938933 ILT |
103 | <-ticker.C |
104 | ticker.Stop() | |
105 | } | |
106 | } | |
5133f00e | 107 | |
bae90c98 ILT |
108 | // Test the Tick convenience wrapper. |
109 | func TestTick(t *testing.T) { | |
110 | // Test that giving a negative duration returns nil. | |
111 | if got := Tick(-1); got != nil { | |
112 | t.Errorf("Tick(-1) = %v; want nil", got) | |
113 | } | |
114 | } | |
115 | ||
116 | // Test that NewTicker panics when given a duration less than zero. | |
117 | func TestNewTickerLtZeroDuration(t *testing.T) { | |
118 | defer func() { | |
119 | if err := recover(); err == nil { | |
120 | t.Errorf("NewTicker(-1) should have panicked") | |
121 | } | |
122 | }() | |
123 | NewTicker(-1) | |
124 | } | |
125 | ||
5133f00e | 126 | func BenchmarkTicker(b *testing.B) { |
1a2f01ef ILT |
127 | benchmark(b, func(n int) { |
128 | ticker := NewTicker(Nanosecond) | |
129 | for i := 0; i < n; i++ { | |
130 | <-ticker.C | |
131 | } | |
132 | ticker.Stop() | |
133 | }) | |
5133f00e | 134 | } |
f75af8c1 ILT |
135 | |
136 | func BenchmarkTickerReset(b *testing.B) { | |
137 | benchmark(b, func(n int) { | |
138 | ticker := NewTicker(Nanosecond) | |
139 | for i := 0; i < n; i++ { | |
140 | ticker.Reset(Nanosecond * 2) | |
141 | } | |
142 | ticker.Stop() | |
143 | }) | |
144 | } | |
145 | ||
146 | func BenchmarkTickerResetNaive(b *testing.B) { | |
147 | benchmark(b, func(n int) { | |
148 | ticker := NewTicker(Nanosecond) | |
149 | for i := 0; i < n; i++ { | |
150 | ticker.Stop() | |
151 | ticker = NewTicker(Nanosecond * 2) | |
152 | } | |
153 | ticker.Stop() | |
154 | }) | |
155 | } |