2 Copyright 2014 The Kubernetes Authors.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
24 // Clock allows for injecting fake or real clocks into code that
25 // needs to do arbitrary things based on time.
26 type Clock interface {
28 Since(time.Time) time.Duration
29 After(time.Duration) <-chan time.Time
30 NewTimer(time.Duration) Timer
32 NewTicker(time.Duration) Ticker
35 // RealClock really calls time.Now()
36 type RealClock struct{}
38 // Now returns the current time.
39 func (RealClock) Now() time.Time {
43 // Since returns time since the specified timestamp.
44 func (RealClock) Since(ts time.Time) time.Duration {
48 // Same as time.After(d).
49 func (RealClock) After(d time.Duration) <-chan time.Time {
53 func (RealClock) NewTimer(d time.Duration) Timer {
55 timer: time.NewTimer(d),
59 func (RealClock) NewTicker(d time.Duration) Ticker {
61 ticker: time.NewTicker(d),
65 func (RealClock) Sleep(d time.Duration) {
69 // FakeClock implements Clock, but returns an arbitrary time.
70 type FakeClock struct {
74 // waiters are waiting for the fake time to pass their specified time
75 waiters []fakeClockWaiter
78 type fakeClockWaiter struct {
80 stepInterval time.Duration
82 destChan chan time.Time
86 func NewFakeClock(t time.Time) *FakeClock {
92 // Now returns f's time.
93 func (f *FakeClock) Now() time.Time {
95 defer f.lock.RUnlock()
99 // Since returns time since the time in f.
100 func (f *FakeClock) Since(ts time.Time) time.Duration {
102 defer f.lock.RUnlock()
103 return f.time.Sub(ts)
106 // Fake version of time.After(d).
107 func (f *FakeClock) After(d time.Duration) <-chan time.Time {
109 defer f.lock.Unlock()
110 stopTime := f.time.Add(d)
111 ch := make(chan time.Time, 1) // Don't block!
112 f.waiters = append(f.waiters, fakeClockWaiter{
113 targetTime: stopTime,
119 // Fake version of time.NewTimer(d).
120 func (f *FakeClock) NewTimer(d time.Duration) Timer {
122 defer f.lock.Unlock()
123 stopTime := f.time.Add(d)
124 ch := make(chan time.Time, 1) // Don't block!
127 waiter: fakeClockWaiter{
128 targetTime: stopTime,
132 f.waiters = append(f.waiters, timer.waiter)
136 func (f *FakeClock) NewTicker(d time.Duration) Ticker {
138 defer f.lock.Unlock()
139 tickTime := f.time.Add(d)
140 ch := make(chan time.Time, 1) // hold one tick
141 f.waiters = append(f.waiters, fakeClockWaiter{
142 targetTime: tickTime,
153 // Move clock by Duration, notify anyone that's called After, Tick, or NewTimer
154 func (f *FakeClock) Step(d time.Duration) {
156 defer f.lock.Unlock()
157 f.setTimeLocked(f.time.Add(d))
161 func (f *FakeClock) SetTime(t time.Time) {
163 defer f.lock.Unlock()
167 // Actually changes the time and checks any waiters. f must be write-locked.
168 func (f *FakeClock) setTimeLocked(t time.Time) {
170 newWaiters := make([]fakeClockWaiter, 0, len(f.waiters))
171 for i := range f.waiters {
173 if !w.targetTime.After(t) {
177 case w.destChan <- t:
186 if w.stepInterval > 0 {
187 for !w.targetTime.After(t) {
188 w.targetTime = w.targetTime.Add(w.stepInterval)
190 newWaiters = append(newWaiters, *w)
194 newWaiters = append(newWaiters, f.waiters[i])
197 f.waiters = newWaiters
200 // Returns true if After has been called on f but not yet satisfied (so you can
201 // write race-free tests).
202 func (f *FakeClock) HasWaiters() bool {
204 defer f.lock.RUnlock()
205 return len(f.waiters) > 0
208 func (f *FakeClock) Sleep(d time.Duration) {
212 // IntervalClock implements Clock, but each invocation of Now steps the clock forward the specified duration
213 type IntervalClock struct {
215 Duration time.Duration
218 // Now returns i's time.
219 func (i *IntervalClock) Now() time.Time {
220 i.Time = i.Time.Add(i.Duration)
224 // Since returns time since the time in i.
225 func (i *IntervalClock) Since(ts time.Time) time.Duration {
226 return i.Time.Sub(ts)
229 // Unimplemented, will panic.
230 // TODO: make interval clock use FakeClock so this can be implemented.
231 func (*IntervalClock) After(d time.Duration) <-chan time.Time {
232 panic("IntervalClock doesn't implement After")
235 // Unimplemented, will panic.
236 // TODO: make interval clock use FakeClock so this can be implemented.
237 func (*IntervalClock) NewTimer(d time.Duration) Timer {
238 panic("IntervalClock doesn't implement NewTimer")
241 // Unimplemented, will panic.
242 // TODO: make interval clock use FakeClock so this can be implemented.
243 func (*IntervalClock) NewTicker(d time.Duration) Ticker {
244 panic("IntervalClock doesn't implement NewTicker")
247 func (*IntervalClock) Sleep(d time.Duration) {
248 panic("IntervalClock doesn't implement Sleep")
251 // Timer allows for injecting fake or real timers into code that
252 // needs to do arbitrary things based on time.
253 type Timer interface {
256 Reset(d time.Duration) bool
259 // realTimer is backed by an actual time.Timer.
260 type realTimer struct {
264 // C returns the underlying timer's channel.
265 func (r *realTimer) C() <-chan time.Time {
269 // Stop calls Stop() on the underlying timer.
270 func (r *realTimer) Stop() bool {
271 return r.timer.Stop()
274 // Reset calls Reset() on the underlying timer.
275 func (r *realTimer) Reset(d time.Duration) bool {
276 return r.timer.Reset(d)
279 // fakeTimer implements Timer based on a FakeClock.
280 type fakeTimer struct {
282 waiter fakeClockWaiter
285 // C returns the channel that notifies when this timer has fired.
286 func (f *fakeTimer) C() <-chan time.Time {
287 return f.waiter.destChan
290 // Stop stops the timer and returns true if the timer has not yet fired, or false otherwise.
291 func (f *fakeTimer) Stop() bool {
292 f.fakeClock.lock.Lock()
293 defer f.fakeClock.lock.Unlock()
295 newWaiters := make([]fakeClockWaiter, 0, len(f.fakeClock.waiters))
296 for i := range f.fakeClock.waiters {
297 w := &f.fakeClock.waiters[i]
299 newWaiters = append(newWaiters, *w)
303 f.fakeClock.waiters = newWaiters
305 return !f.waiter.fired
308 // Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet
309 // fired, or false otherwise.
310 func (f *fakeTimer) Reset(d time.Duration) bool {
311 f.fakeClock.lock.Lock()
312 defer f.fakeClock.lock.Unlock()
314 active := !f.waiter.fired
316 f.waiter.fired = false
317 f.waiter.targetTime = f.fakeClock.time.Add(d)
322 type Ticker interface {
327 type realTicker struct {
331 func (t *realTicker) C() <-chan time.Time {
335 func (t *realTicker) Stop() {
339 type fakeTicker struct {
343 func (t *fakeTicker) C() <-chan time.Time {
347 func (t *fakeTicker) Stop() {