Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: go/src/infra/libs/clock/testclock/testclock.go

Issue 1154213012: Add context-aware "time" library wrapper. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Refactored test timer to trigger off of underlying clock. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package testclock
6
7 import (
8 "sync"
9 "time"
10
11 "golang.org/x/net/context"
12 "infra/libs/clock"
13 )
14
15 // TestClock is a Clock interface with additional methods to help instrument it.
16 type TestClock interface {
17 clock.Clock
18 SetNow(time.Time)
19 SetTimerCallback(TimerCallback)
20 }
21
22 // TimerCallback that can be invoked when a timer has been set. This is useful f or
23 // sychronizing state when testing.
24 type TimerCallback func(clock.Timer)
25
26 // testClock is a test-oriented implementation of the 'Clock' interface.
27 //
28 // This implementation's Clock responses are configurable by modifying its membe r
29 // variables. Time-based events are explicitly triggered by sending on a Timer
30 // instance's channel.
31 type testClock struct {
32 sync.RWMutex
33
34 now time.Time // The current clock time.
35 timerCond *sync.Cond // Condition used to manage timer blocking.
36
37 timerCallback TimerCallback // Optional callback when a timer has been s et.
38 }
39
40 var _ TestClock = (*testClock)(nil)
41
42 // New returns a TestClock instance set at the specified time.
43 func New(now time.Time) TestClock {
44 c := testClock{
45 now: now,
46 }
47 c.timerCond = sync.NewCond(&c)
48 return &c
49 }
50
51 func (c *testClock) Now() time.Time {
52 c.RLock()
53 defer c.RUnlock()
54
55 return c.now
56 }
57
58 func (c *testClock) Sleep(d time.Duration) {
59 <-c.After(d)
60 }
61
62 func (c *testClock) NewTimer() clock.Timer {
63 return newTimer(c)
64 }
65
66 func (c *testClock) After(d time.Duration) <-chan time.Time {
67 t := c.NewTimer()
68 t.Reset(d)
69 return t.GetC()
70 }
71
72 func (c *testClock) SetNow(t time.Time) {
73 c.Lock()
74 defer c.Unlock()
75
76 c.now = t
77
78 // Unblock any blocking timers that are waiting on our lock.
79 go c.pokeTimers()
80 }
81
82 func (c *testClock) SetTimerCallback(callback TimerCallback) {
83 c.Lock()
84 defer c.Unlock()
85
86 c.timerCallback = callback
87 }
88
89 func (c *testClock) getTimerCallback() TimerCallback {
90 c.Lock()
91 defer c.Unlock()
92
93 return c.timerCallback
94 }
95
96 func (c *testClock) signalTimerSet(t clock.Timer) {
97 callback := c.getTimerCallback()
98 if callback != nil {
99 callback(t)
100 }
101 }
102
103 func (c *testClock) pokeTimers() {
104 c.Lock()
105 defer c.Unlock()
106
107 c.timerCond.Broadcast()
108 }
109
110 // Set creates a new Context using the supplied clock instance.
111 func Set(ctx context.Context, now time.Time) context.Context {
112 return clock.SetClock(ctx, New(now))
113 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698