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