testclock

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package testclock provides a deterministic, manually-advanced implementation of warden.IClock for tests. Time only moves when Advance is called; timers and tickers fire from Advance in chronological order. This lets the election and watchdog state machines be exercised without real sleeps, so tests are fast and non-flaky.

The zero value is not usable; construct with New. A single *Clock can be shared by an entire simulated cluster so every node observes the same global time.

This is a supported test double, not an internal fixture: anything built on warden.IClock — including code outside this repository — can drive it the same way warden's own suites do. Callers may rely on Advance being the only thing that moves time, and on the waiters due within one Advance firing in deadline order, ties broken by creation order, so a test observes one fixed interleaving rather than a scheduler-dependent one. Delivery matches the real time package rather than improving on it: each channel is buffered to one and the send is non-blocking, so a tick an unread receiver has not drained is dropped exactly as time.Ticker would drop it. BlockUntilTimers is how a test waits for the code under test to arm its timers before advancing. It never returns wall-clock time and has no place in a production wiring.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Clock

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

Clock is a deterministic fake clock implementing warden.IClock. All methods are safe for concurrent use.

func New

func New(start time.Time) *Clock

New returns a Clock whose current time is start.

func (*Clock) Advance

func (c *Clock) Advance(d time.Duration)

Advance moves simulated time forward by d, firing every timer and ticker whose deadline falls within the new interval, in chronological order. Tickers reschedule and may fire multiple times. After each fire the lock is released and the scheduler is yielded so a woken goroutine gets a chance to run (and arm follow-on timers that Advance will then also fire if due), keeping multi-goroutine tests deterministic when combined with an explicit settle barrier.

func (*Clock) After

func (c *Clock) After(d time.Duration) <-chan time.Time

After implements warden.IClock. It returns a channel that receives the time once d has elapsed (via Advance).

func (*Clock) ArmedTimers

func (c *Clock) ArmedTimers() int

ArmedTimers returns the number of currently armed timers/tickers.

func (*Clock) BlockUntilTimers

func (c *Clock) BlockUntilTimers(n int)

BlockUntilTimers blocks until at least n timers/tickers are armed. It is the recommended synchronization point for tests that arm timers on background goroutines: wait for the expected number to be registered before advancing.

func (*Clock) NewTicker

func (c *Clock) NewTicker(d time.Duration) warden.Ticker

NewTicker implements warden.IClock. It panics if d <= 0, mirroring time.NewTicker.

func (*Clock) NewTimer

func (c *Clock) NewTimer(d time.Duration) warden.Timer

NewTimer implements warden.IClock. The returned warden.Timer is filled from this clock's own machinery: the waiter's channel, and closures over the waiter id that reach back into stop and reset.

func (*Clock) Now

func (c *Clock) Now() time.Time

Now returns the current simulated time.

Jump to

Keyboard shortcuts

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