...
1
16
17 package testing
18
19 import (
20 "sync"
21 "time"
22
23 "k8s.io/utils/clock"
24 )
25
26 var (
27 _ = clock.PassiveClock(&FakePassiveClock{})
28 _ = clock.WithTicker(&FakeClock{})
29 _ = clock.Clock(&IntervalClock{})
30 )
31
32
33 type FakePassiveClock struct {
34 lock sync.RWMutex
35 time time.Time
36 }
37
38
39 type FakeClock struct {
40 FakePassiveClock
41
42
43 waiters []*fakeClockWaiter
44 }
45
46 type fakeClockWaiter struct {
47 targetTime time.Time
48 stepInterval time.Duration
49 skipIfBlocked bool
50 destChan chan time.Time
51 fired bool
52 afterFunc func()
53 }
54
55
56 func NewFakePassiveClock(t time.Time) *FakePassiveClock {
57 return &FakePassiveClock{
58 time: t,
59 }
60 }
61
62
63 func NewFakeClock(t time.Time) *FakeClock {
64 return &FakeClock{
65 FakePassiveClock: *NewFakePassiveClock(t),
66 }
67 }
68
69
70 func (f *FakePassiveClock) Now() time.Time {
71 f.lock.RLock()
72 defer f.lock.RUnlock()
73 return f.time
74 }
75
76
77 func (f *FakePassiveClock) Since(ts time.Time) time.Duration {
78 f.lock.RLock()
79 defer f.lock.RUnlock()
80 return f.time.Sub(ts)
81 }
82
83
84 func (f *FakePassiveClock) SetTime(t time.Time) {
85 f.lock.Lock()
86 defer f.lock.Unlock()
87 f.time = t
88 }
89
90
91 func (f *FakeClock) After(d time.Duration) <-chan time.Time {
92 f.lock.Lock()
93 defer f.lock.Unlock()
94 stopTime := f.time.Add(d)
95 ch := make(chan time.Time, 1)
96 f.waiters = append(f.waiters, &fakeClockWaiter{
97 targetTime: stopTime,
98 destChan: ch,
99 })
100 return ch
101 }
102
103
104 func (f *FakeClock) NewTimer(d time.Duration) clock.Timer {
105 f.lock.Lock()
106 defer f.lock.Unlock()
107 stopTime := f.time.Add(d)
108 ch := make(chan time.Time, 1)
109 timer := &fakeTimer{
110 fakeClock: f,
111 waiter: fakeClockWaiter{
112 targetTime: stopTime,
113 destChan: ch,
114 },
115 }
116 f.waiters = append(f.waiters, &timer.waiter)
117 return timer
118 }
119
120
121 func (f *FakeClock) AfterFunc(d time.Duration, cb func()) clock.Timer {
122 f.lock.Lock()
123 defer f.lock.Unlock()
124 stopTime := f.time.Add(d)
125 ch := make(chan time.Time, 1)
126
127 timer := &fakeTimer{
128 fakeClock: f,
129 waiter: fakeClockWaiter{
130 targetTime: stopTime,
131 destChan: ch,
132 afterFunc: cb,
133 },
134 }
135 f.waiters = append(f.waiters, &timer.waiter)
136 return timer
137 }
138
139
140 func (f *FakeClock) Tick(d time.Duration) <-chan time.Time {
141 if d <= 0 {
142 return nil
143 }
144 f.lock.Lock()
145 defer f.lock.Unlock()
146 tickTime := f.time.Add(d)
147 ch := make(chan time.Time, 1)
148 f.waiters = append(f.waiters, &fakeClockWaiter{
149 targetTime: tickTime,
150 stepInterval: d,
151 skipIfBlocked: true,
152 destChan: ch,
153 })
154
155 return ch
156 }
157
158
159 func (f *FakeClock) NewTicker(d time.Duration) clock.Ticker {
160 f.lock.Lock()
161 defer f.lock.Unlock()
162 tickTime := f.time.Add(d)
163 ch := make(chan time.Time, 1)
164 f.waiters = append(f.waiters, &fakeClockWaiter{
165 targetTime: tickTime,
166 stepInterval: d,
167 skipIfBlocked: true,
168 destChan: ch,
169 })
170
171 return &fakeTicker{
172 c: ch,
173 }
174 }
175
176
177
178 func (f *FakeClock) Step(d time.Duration) {
179 f.lock.Lock()
180 defer f.lock.Unlock()
181 f.setTimeLocked(f.time.Add(d))
182 }
183
184
185 func (f *FakeClock) SetTime(t time.Time) {
186 f.lock.Lock()
187 defer f.lock.Unlock()
188 f.setTimeLocked(t)
189 }
190
191
192 func (f *FakeClock) setTimeLocked(t time.Time) {
193 f.time = t
194 newWaiters := make([]*fakeClockWaiter, 0, len(f.waiters))
195 for i := range f.waiters {
196 w := f.waiters[i]
197 if !w.targetTime.After(t) {
198 if w.skipIfBlocked {
199 select {
200 case w.destChan <- t:
201 w.fired = true
202 default:
203 }
204 } else {
205 w.destChan <- t
206 w.fired = true
207 }
208
209 if w.afterFunc != nil {
210 w.afterFunc()
211 }
212
213 if w.stepInterval > 0 {
214 for !w.targetTime.After(t) {
215 w.targetTime = w.targetTime.Add(w.stepInterval)
216 }
217 newWaiters = append(newWaiters, w)
218 }
219
220 } else {
221 newWaiters = append(newWaiters, f.waiters[i])
222 }
223 }
224 f.waiters = newWaiters
225 }
226
227
228
229 func (f *FakeClock) HasWaiters() bool {
230 f.lock.RLock()
231 defer f.lock.RUnlock()
232 return len(f.waiters) > 0
233 }
234
235
236 func (f *FakeClock) Sleep(d time.Duration) {
237 f.Step(d)
238 }
239
240
241
242
243
244 type IntervalClock struct {
245 Time time.Time
246 Duration time.Duration
247 }
248
249
250 func (i *IntervalClock) Now() time.Time {
251 i.Time = i.Time.Add(i.Duration)
252 return i.Time
253 }
254
255
256 func (i *IntervalClock) Since(ts time.Time) time.Duration {
257 return i.Time.Sub(ts)
258 }
259
260
261
262 func (*IntervalClock) After(d time.Duration) <-chan time.Time {
263 panic("IntervalClock doesn't implement After")
264 }
265
266
267
268 func (*IntervalClock) NewTimer(d time.Duration) clock.Timer {
269 panic("IntervalClock doesn't implement NewTimer")
270 }
271
272
273
274 func (*IntervalClock) AfterFunc(d time.Duration, f func()) clock.Timer {
275 panic("IntervalClock doesn't implement AfterFunc")
276 }
277
278
279
280 func (*IntervalClock) Tick(d time.Duration) <-chan time.Time {
281 panic("IntervalClock doesn't implement Tick")
282 }
283
284
285
286 func (*IntervalClock) NewTicker(d time.Duration) clock.Ticker {
287 panic("IntervalClock doesn't implement NewTicker")
288 }
289
290
291 func (*IntervalClock) Sleep(d time.Duration) {
292 panic("IntervalClock doesn't implement Sleep")
293 }
294
295 var _ = clock.Timer(&fakeTimer{})
296
297
298 type fakeTimer struct {
299 fakeClock *FakeClock
300 waiter fakeClockWaiter
301 }
302
303
304 func (f *fakeTimer) C() <-chan time.Time {
305 return f.waiter.destChan
306 }
307
308
309 func (f *fakeTimer) Stop() bool {
310 f.fakeClock.lock.Lock()
311 defer f.fakeClock.lock.Unlock()
312
313 newWaiters := make([]*fakeClockWaiter, 0, len(f.fakeClock.waiters))
314 for i := range f.fakeClock.waiters {
315 w := f.fakeClock.waiters[i]
316 if w != &f.waiter {
317 newWaiters = append(newWaiters, w)
318 }
319 }
320
321 f.fakeClock.waiters = newWaiters
322
323 return !f.waiter.fired
324 }
325
326
327
328 func (f *fakeTimer) Reset(d time.Duration) bool {
329 f.fakeClock.lock.Lock()
330 defer f.fakeClock.lock.Unlock()
331
332 active := !f.waiter.fired
333
334 f.waiter.fired = false
335 f.waiter.targetTime = f.fakeClock.time.Add(d)
336
337 var isWaiting bool
338 for i := range f.fakeClock.waiters {
339 w := f.fakeClock.waiters[i]
340 if w == &f.waiter {
341 isWaiting = true
342 break
343 }
344 }
345 if !isWaiting {
346 f.fakeClock.waiters = append(f.fakeClock.waiters, &f.waiter)
347 }
348
349 return active
350 }
351
352 type fakeTicker struct {
353 c <-chan time.Time
354 }
355
356 func (t *fakeTicker) C() <-chan time.Time {
357 return t.c
358 }
359
360 func (t *fakeTicker) Stop() {
361 }
362
View as plain text