clock

package
v0.229.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package clock provides a pluggable Now() time source so the mock's protocol-time outputs (JWT iat/exp, code/OTP TTLs, bearer validation) can be frozen or skewed at runtime via /admin0/clock for deterministic tests.

Wall-clock uses (request logging, middleware latency, http.Server timeouts) deliberately keep using time.Now directly — log timestamps should not lie because protocol time was frozen.

Index

Constants

This section is empty.

Variables

View Source
var ErrAdvanceInRealMode = errors.New("clock: cannot advance while in real mode (Freeze or Offset first)")

ErrAdvanceInRealMode is returned by Advance when the clock is in real mode. There's nothing to advance against; the caller should Freeze or Offset first.

Functions

This section is empty.

Types

type Clock

type Clock interface {
	Now() time.Time
}

Clock is the single read-side primitive the mock's handlers depend on. One method keeps the surface trivial to stub.

type Controlled

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

Controlled is a mutable Clock the admin0 surface and the SDK drive. Safe for concurrent use; all reads take an RLock, all mutations take the write lock.

func NewControlled

func NewControlled() *Controlled

NewControlled returns a Controlled in real mode.

func (*Controlled) Advance

func (c *Controlled) Advance(d time.Duration) error

Advance mutates the held value by d. In frozen mode the pinned instant moves by d; in offset mode the offset grows by d; in real mode the call is a no-op and returns ErrAdvanceInRealMode.

func (*Controlled) ConfiguredOffset

func (c *Controlled) ConfiguredOffset() (time.Duration, bool)

ConfiguredOffset returns the configured offset and true when the clock is in offset mode; (0, false) otherwise. Used by callers that want the raw offset without the resolved Now (Snapshot is the better choice for callers that need both).

func (*Controlled) Freeze

func (c *Controlled) Freeze(t time.Time)

Freeze pins Now to t until the next mode change. Also zeroes the offset field even though Now never reads it in frozen mode — a future method that touches offset without rechecking mode (e.g. a "scale offset by N" helper) shouldn't see leftover state from a prior Offset() call.

func (*Controlled) Now

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

Now returns the current effective time given the mode.

func (*Controlled) Offset

func (c *Controlled) Offset(d time.Duration)

Offset switches to offset mode with the given skew. The wall clock keeps ticking; Now returns time.Now() + d. Also zeroes the pinned field for the same future-safety reason as Freeze.

func (*Controlled) Reset

func (c *Controlled) Reset()

Reset returns the clock to real mode and clears any held state.

func (*Controlled) Snapshot

func (c *Controlled) Snapshot() (mode Mode, now time.Time, offset time.Duration, hasOffset bool)

Snapshot returns (mode, now, offset, hasOffset) under a single RLock so callers get a consistent view. `hasOffset` is true only when `mode == ModeOffset`; in that case `offset` is the configured skew.

Prefer Snapshot over composing State + ConfiguredOffset when both values are needed: a concurrent Freeze/Offset call between the two accessor calls would otherwise produce an inconsistent picture (e.g. mode=frozen but hasOffset=true).

func (*Controlled) State

func (c *Controlled) State() (Mode, time.Time)

State returns (mode, current Now) as an atomic snapshot — no races between the mode and value reads.

type Mode

type Mode string

Mode is the discriminator for Controlled's internal state.

const (
	ModeReal   Mode = "real"
	ModeFrozen Mode = "frozen"
	ModeOffset Mode = "offset"
)

Mode values are also the JSON wire form returned by GET /admin0/clock.

type Real

type Real struct{}

Real is the production default: delegates straight to time.Now. Zero value is usable; empty struct so embedding is cheap.

func (Real) Now

func (Real) Now() time.Time

Now returns the wall clock.

Jump to

Keyboard shortcuts

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