...
1
16
17 package testing
18
19 import (
20 "testing"
21 "time"
22
23 "k8s.io/utils/clock"
24 )
25
26 type SettablePassiveClock interface {
27 clock.PassiveClock
28 SetTime(time.Time)
29 }
30
31 func exercisePassiveClock(t *testing.T, pc SettablePassiveClock) {
32 t1 := time.Now()
33 t2 := t1.Add(time.Hour)
34 pc.SetTime(t1)
35 tx := pc.Now()
36 if tx != t1 {
37 t.Errorf("SetTime(%#+v); Now() => %#+v", t1, tx)
38 }
39 dx := pc.Since(t1)
40 if dx != 0 {
41 t.Errorf("Since() => %v", dx)
42 }
43 pc.SetTime(t2)
44 dx = pc.Since(t1)
45 if dx != time.Hour {
46 t.Errorf("Since() => %v", dx)
47 }
48 tx = pc.Now()
49 if tx != t2 {
50 t.Errorf("Now() => %#+v", tx)
51 }
52 }
53
54 func TestFakePassiveClock(t *testing.T) {
55 startTime := time.Now()
56 tc := NewFakePassiveClock(startTime)
57 exercisePassiveClock(t, tc)
58 }
59
60 func TestFakeClock(t *testing.T) {
61 startTime := time.Now()
62 tc := NewFakeClock(startTime)
63 exercisePassiveClock(t, tc)
64 tc.SetTime(startTime)
65 tc.Step(time.Second)
66 now := tc.Now()
67 if now.Sub(startTime) != time.Second {
68 t.Errorf("input: %s now=%s gap=%s expected=%s", startTime, now, now.Sub(startTime), time.Second)
69 }
70 }
71
72 func TestFakeClockSleep(t *testing.T) {
73 startTime := time.Now()
74 tc := NewFakeClock(startTime)
75 tc.Sleep(time.Duration(1) * time.Hour)
76 now := tc.Now()
77 if now.Sub(startTime) != time.Hour {
78 t.Errorf("Fake sleep failed, expected time to advance by one hour, instead, its %v", now.Sub(startTime))
79 }
80 }
81
82 func TestFakeAfter(t *testing.T) {
83 tc := NewFakeClock(time.Now())
84 if tc.HasWaiters() {
85 t.Errorf("unexpected waiter?")
86 }
87 oneSec := tc.After(time.Second)
88 if !tc.HasWaiters() {
89 t.Errorf("unexpected lack of waiter?")
90 }
91
92 oneOhOneSec := tc.After(time.Second + time.Millisecond)
93 twoSec := tc.After(2 * time.Second)
94 select {
95 case <-oneSec:
96 t.Errorf("unexpected channel read")
97 case <-oneOhOneSec:
98 t.Errorf("unexpected channel read")
99 case <-twoSec:
100 t.Errorf("unexpected channel read")
101 default:
102 }
103
104 tc.Step(999 * time.Millisecond)
105 select {
106 case <-oneSec:
107 t.Errorf("unexpected channel read")
108 case <-oneOhOneSec:
109 t.Errorf("unexpected channel read")
110 case <-twoSec:
111 t.Errorf("unexpected channel read")
112 default:
113 }
114
115 tc.Step(time.Millisecond)
116 select {
117 case <-oneSec:
118
119 case <-oneOhOneSec:
120 t.Errorf("unexpected channel read")
121 case <-twoSec:
122 t.Errorf("unexpected channel read")
123 default:
124 t.Errorf("unexpected non-channel read")
125 }
126 tc.Step(time.Millisecond)
127 select {
128 case <-oneSec:
129
130 t.Errorf("unexpected channel read")
131 case <-oneOhOneSec:
132
133 case <-twoSec:
134 t.Errorf("unexpected channel read")
135 default:
136 t.Errorf("unexpected non-channel read")
137 }
138 }
139
140 func TestFakeAfterFunc(t *testing.T) {
141 tc := NewFakeClock(time.Now())
142 if tc.HasWaiters() {
143 t.Errorf("unexpected waiter?")
144 }
145 expectOneSecTimerFire := false
146 oneSecTimerFire := 0
147 tc.AfterFunc(time.Second, func() {
148 if !expectOneSecTimerFire {
149 t.Errorf("oneSecTimer func fired")
150 } else {
151 oneSecTimerFire++
152 }
153 })
154 if !tc.HasWaiters() {
155 t.Errorf("unexpected lack of waiter?")
156 }
157
158 expectOneOhOneSecTimerFire := false
159 oneOhOneSecTimerFire := 0
160 tc.AfterFunc(time.Second+time.Millisecond, func() {
161 if !expectOneOhOneSecTimerFire {
162 t.Errorf("oneOhOneSecTimer func fired")
163 } else {
164 oneOhOneSecTimerFire++
165 }
166 })
167
168 expectTwoSecTimerFire := false
169 twoSecTimerFire := 0
170 twoSecTimer := tc.AfterFunc(2*time.Second, func() {
171 if !expectTwoSecTimerFire {
172 t.Errorf("twoSecTimer func fired")
173 } else {
174 twoSecTimerFire++
175 }
176 })
177
178 tc.Step(999 * time.Millisecond)
179
180 expectOneSecTimerFire = true
181 tc.Step(time.Millisecond)
182 if oneSecTimerFire != 1 {
183 t.Errorf("expected oneSecTimerFire=1, got %d", oneSecTimerFire)
184 }
185 expectOneSecTimerFire = false
186
187 expectOneOhOneSecTimerFire = true
188 tc.Step(time.Millisecond)
189 if oneOhOneSecTimerFire != 1 {
190
191 t.Errorf("expected oneOhOneSecTimerFire=1, got %d", oneOhOneSecTimerFire)
192 }
193 expectOneOhOneSecTimerFire = false
194
195
196 twoSecTimer.Stop()
197 tc.Step(time.Second)
198 }
199
200 func TestFakeTick(t *testing.T) {
201 tc := NewFakeClock(time.Now())
202 if tc.HasWaiters() {
203 t.Errorf("unexpected waiter?")
204 }
205 oneSec := tc.Tick(time.Second)
206 if !tc.HasWaiters() {
207 t.Errorf("unexpected lack of waiter?")
208 }
209
210 oneOhOneSec := tc.Tick(time.Second + time.Millisecond)
211 twoSec := tc.Tick(2 * time.Second)
212 select {
213 case <-oneSec:
214 t.Errorf("unexpected channel read")
215 case <-oneOhOneSec:
216 t.Errorf("unexpected channel read")
217 case <-twoSec:
218 t.Errorf("unexpected channel read")
219 default:
220 }
221
222 tc.Step(999 * time.Millisecond)
223 select {
224 case <-oneSec:
225 t.Errorf("unexpected channel read")
226 case <-oneOhOneSec:
227 t.Errorf("unexpected channel read")
228 case <-twoSec:
229 t.Errorf("unexpected channel read")
230 default:
231 }
232
233 tc.Step(time.Millisecond)
234 select {
235 case <-oneSec:
236
237 case <-oneOhOneSec:
238 t.Errorf("unexpected channel read")
239 case <-twoSec:
240 t.Errorf("unexpected channel read")
241 default:
242 t.Errorf("unexpected non-channel read")
243 }
244 tc.Step(time.Millisecond)
245 select {
246 case <-oneSec:
247
248 t.Errorf("unexpected channel read")
249 case <-oneOhOneSec:
250
251 case <-twoSec:
252 t.Errorf("unexpected channel read")
253 default:
254 t.Errorf("unexpected non-channel read")
255 }
256
257 tc.Step(time.Second)
258 tc.Step(time.Second)
259 tc.Step(time.Second)
260 tc.Step(time.Second)
261
262
263 accumulatedTicks := 0
264 drained := false
265 for !drained {
266 select {
267 case <-oneSec:
268 accumulatedTicks++
269 default:
270 drained = true
271 }
272 }
273 if accumulatedTicks != 1 {
274 t.Errorf("unexpected number of accumulated ticks: %d", accumulatedTicks)
275 }
276 }
277
278 func TestFakeStop(t *testing.T) {
279 tc := NewFakeClock(time.Now())
280 timer := tc.NewTimer(time.Second)
281 if !tc.HasWaiters() {
282 t.Errorf("expected a waiter to be present, but it is not")
283 }
284 timer.Stop()
285 if tc.HasWaiters() {
286 t.Errorf("expected existing waiter to be cleaned up, but it is still present")
287 }
288 }
289
290
291
292
293 func TestFakeStopDrain(t *testing.T) {
294 start := time.Time{}
295 tc := NewFakeClock(start)
296 timer := tc.NewTimer(time.Second)
297 tc.Step(1 * time.Second)
298
299 if timer.Stop() {
300 t.Errorf("stop should report the timer had triggered")
301 }
302 if readTime := assertReadTime(t, timer.C()); !readTime.Equal(start.Add(1 * time.Second)) {
303 t.Errorf("timer should have ticked after 1 second, got %v", readTime)
304 }
305
306 timer.Reset(time.Second)
307 if !tc.HasWaiters() {
308 t.Errorf("expected a waiter to be present, but it is not")
309 }
310 select {
311 case <-timer.C():
312 t.Fatal("got time early on clock; haven't stepped yet")
313 default:
314 }
315 tc.Step(1 * time.Second)
316 if readTime := assertReadTime(t, timer.C()); !readTime.Equal(start.Add(2 * time.Second)) {
317 t.Errorf("timer should have ticked again after reset + 1 more second, got %v", readTime)
318 }
319 }
320
321 func TestTimerNegative(t *testing.T) {
322 tc := NewFakeClock(time.Now())
323 timer := tc.NewTimer(-1 * time.Second)
324 if !tc.HasWaiters() {
325 t.Errorf("expected a waiter to be present, but it is not")
326 }
327
328 tc.Step(0)
329 tick := assertReadTime(t, timer.C())
330 if tick != tc.Now() {
331 t.Errorf("expected -1s to turn into now: %v != %v", tick, tc.Now())
332 }
333 }
334
335 func TestTickNegative(t *testing.T) {
336
337
338 tc := NewFakeClock(time.Now())
339 if tick := tc.Tick(-1 * time.Second); tick != nil {
340 t.Errorf("expected negative tick to be nil: %v", tick)
341 }
342 if tick := tc.Tick(0); tick != nil {
343 t.Errorf("expected negative tick to be nil: %v", tick)
344 }
345 }
346
347
348
349 func assertReadTime(t testing.TB, c <-chan time.Time) time.Time {
350 type helper interface {
351 Helper()
352 }
353 if h, ok := t.(helper); ok {
354 h.Helper()
355 }
356 select {
357 case ti, ok := <-c:
358 if !ok {
359 t.Fatalf("expected to read time from channel, but it was closed")
360 }
361 return ti
362 default:
363 t.Fatalf("expected to read time from channel, but couldn't")
364 }
365 panic("unreachable")
366 }
367
View as plain text