Chromium Code Reviews| Index: go/src/infra/libs/clock/testclock/testclock.go |
| diff --git a/go/src/infra/libs/clock/testclock/testclock.go b/go/src/infra/libs/clock/testclock/testclock.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9aa1f947b792b5b583d6d92d63eaa45a400a5f1d |
| --- /dev/null |
| +++ b/go/src/infra/libs/clock/testclock/testclock.go |
| @@ -0,0 +1,78 @@ |
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package testclock |
| + |
| +import ( |
| + "time" |
| + |
| + "golang.org/x/net/context" |
| + "infra/libs/clock" |
| +) |
| + |
| +// TestClock is a Clock interface with additional methods to help instrument it. |
| +type TestClock interface { |
| + clock.Clock |
| + SetNow(time.Time) |
| + SetTimerFactory(TimerFactory) |
| +} |
| + |
| +// testClock is a test-oriented implementation of the 'Clock' interface. |
| +// |
| +// This implementation's Clock responses are configurable by modifying its member |
| +// variables. Time-based events are explicitly triggered by sending on a Timer |
| +// instance's channel. |
| +type testClock struct { |
|
iannucci
2015/06/02 22:19:03
mutex for protecting now/timeC/tf
dnj
2015/06/03 00:25:28
Done.
|
| + now time.Time // The current clock time. |
| + timeC chan time.Time // Channel to unblock sleeping and After. |
| + tf TimerFactory // Timer generator function. Must be set to use NewTimer() and After(). |
| +} |
| + |
| +// testClock implements clock.TestClock. |
| +var _ TestClock = (*testClock)(nil) |
| + |
| +// New returns a TestClock instance set at the specified time. |
| +func New(now time.Time, tf TimerFactory) TestClock { |
| + return &testClock{ |
| + now: now, |
| + tf: tf, |
|
iannucci
2015/06/02 22:19:03
timeC?
dnj
2015/06/03 00:25:28
Acknowledged.
|
| + } |
| +} |
| + |
| +func (c *testClock) Now() time.Time { |
| + return c.now |
| +} |
| + |
| +func (c *testClock) Sleep(time.Duration) { |
| + if c.timeC != nil { |
| + // Wait for sleep signal; update current time. |
| + c.now = <-c.timeC |
| + } |
| +} |
| + |
| +func (c *testClock) NewTimer() clock.Timer { |
| + if c.tf == nil { |
| + panic("No test timer generator is configured.") |
| + } |
| + return c.tf() |
| +} |
| + |
| +func (c *testClock) After(d time.Duration) <-chan time.Time { |
| + t := c.NewTimer() |
| + t.Reset(d) |
| + return t.GetC() |
| +} |
| + |
| +func (c *testClock) SetNow(t time.Time) { |
| + c.now = t |
| +} |
| + |
| +func (c *testClock) SetTimerFactory(tf TimerFactory) { |
| + c.tf = tf |
| +} |
| + |
| +// Set creates a new Context using the supplied clock instance. |
| +func Set(ctx context.Context, now time.Time, tf TimerFactory) context.Context { |
| + return clock.SetClock(ctx, New(now, tf)) |
| +} |