clockmock

package
v0.1.0-develop.2026061... Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package clockmock provides a deterministic clock.Clock implementation driven by explicit FakeClock.Advance and FakeClock.Set calls.

All FakeClock methods are safe for concurrent use. Time progress is fully caller-controlled: FakeClock.Now never advances on its own, and timers created via FakeClock.NewTimerAt only fire when Advance or Set moves the clock past their deadline. This is the only mechanism test code should use to exercise time-dependent business logic in GoCell.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FakeClock

type FakeClock struct {
	// contains filtered or unexported fields
}

FakeClock is a controllable clock.Clock for deterministic testing. Time advances only when FakeClock.Advance or FakeClock.Set is called; all timers and tickers created by this clock fire synchronously when the clock passes their deadline.

func New

func New(initial time.Time) *FakeClock

New creates a FakeClock starting at the given initial time. If zero, the clock starts at a fixed UTC epoch (2024-01-01) so test fixtures remain deterministic across runs.

func (*FakeClock) Advance

func (fc *FakeClock) Advance(d time.Duration)

Advance moves the clock forward by d and fires all timers / tickers whose deadline has passed. Returns after every due timer's channel has been written and every due AfterFunc callback has been launched.

func (*FakeClock) AfterFunc

func (fc *FakeClock) AfterFunc(deadline time.Time, fn func()) clock.Timer

AfterFunc implements clock.Clock. fn is invoked on its own goroutine the first time Advance / Set causes the clock to reach deadline. Past deadlines schedule fn immediately. The returned timer's C channel never receives a value; only Stop / Reset are meaningful for AfterFunc timers.

func (*FakeClock) NewTicker

func (fc *FakeClock) NewTicker(interval time.Duration) clock.Ticker

NewTicker implements clock.Clock. The returned FakeTicker fires every interval starting from Now()+interval, mirroring stdlib time.NewTicker first-fire semantics. Advance / Set may fire multiple ticks worth of elapsed intervals; the channel is buffered to 1 so excess ticks coalesce (also matching stdlib).

func (*FakeClock) NewTimerAt

func (fc *FakeClock) NewTimerAt(deadline time.Time) clock.Timer

NewTimerAt implements clock.Clock. The returned FakeTimer fires when FakeClock.Advance or FakeClock.Set moves fc past deadline.

The deadline write and timer registration happen under a single fc.mu hold, which is what makes the API race-free against concurrent Advance — a duration-based API would require two non-atomic clock interactions.

func (*FakeClock) Now

func (fc *FakeClock) Now() time.Time

Now implements clock.Clock.

func (*FakeClock) PendingTickers

func (fc *FakeClock) PendingTickers() int

PendingTickers returns the number of active (non-stopped) tickers.

func (*FakeClock) PendingTimers

func (fc *FakeClock) PendingTimers() int

PendingTimers returns the number of active (non-stopped, non-fired) timers currently registered with this clock. Useful for syncing with goroutines that re-arm a timer after a tick.

func (*FakeClock) Set

func (fc *FakeClock) Set(t time.Time)

Set moves the clock to t (forward or backward) and fires all timers / tickers whose deadline has passed. Backward moves do not un-fire already-fired timers.

func (*FakeClock) Since

func (fc *FakeClock) Since(t time.Time) time.Duration

Since implements clock.Clock.

func (*FakeClock) Sleep

func (fc *FakeClock) Sleep(ctx context.Context, until time.Time) error

Sleep implements clock.Clock. Blocks until ctx is canceled or the fake clock is advanced past until, whichever happens first. Returns ctx.Err() on cancelation, nil otherwise.

func (*FakeClock) Until

func (fc *FakeClock) Until(t time.Time) time.Duration

Until implements clock.Clock.

type FakeTicker

type FakeTicker struct {
	// contains filtered or unexported fields
}

FakeTicker is a periodic ticker controlled by a FakeClock. Mutable fields are protected by the parent FakeClock's mu.

func (*FakeTicker) C

func (ft *FakeTicker) C() <-chan time.Time

C implements clock.Ticker.

func (*FakeTicker) Reset

func (ft *FakeTicker) Reset(interval time.Duration)

Reset implements clock.Ticker. Resets interval and computes the next fire time as Now()+interval (matching stdlib semantics).

func (*FakeTicker) Stop

func (ft *FakeTicker) Stop()

Stop implements clock.Ticker. Stop is idempotent.

type FakeTimer

type FakeTimer struct {
	// contains filtered or unexported fields
}

FakeTimer is a single-fire timer controlled by a FakeClock. All mutable fields are protected by the parent FakeClock's mu; FakeTimer itself holds no lock.

func (*FakeTimer) C

func (ft *FakeTimer) C() <-chan time.Time

C implements clock.Timer.

func (*FakeTimer) Reset

func (ft *FakeTimer) Reset(d time.Duration) bool

Reset implements clock.Timer. Returns true if the timer was active when Reset was called.

The channel drain and re-arm are performed while fc.mu is held so that a concurrent sendDueTimers cannot deliver a new tick between the drain and the re-arm, eliminating the I-05 race window.

func (*FakeTimer) ResetAt

func (ft *FakeTimer) ResetAt(deadline time.Time) bool

ResetAt implements clock.Timer. Re-arms the timer to fire at the given absolute deadline. Uses the same locked-drain pattern as Reset to avoid the I-05 race window.

func (*FakeTimer) Stop

func (ft *FakeTimer) Stop() bool

Stop implements clock.Timer. Returns true if the timer was stopped before firing; false if it had already fired or been stopped.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL