Skip to content
→ All work

Case study 21 / 37

Deterministic-TimeMachine

Makes flaky tests reproducible: route time, randomness, files, environment, network and scheduling through one handle, record a run, and replay it exactly.

Status
Experimental
Period
2026
Domain
Tools
Language
Rust
Last push
26 OCT 2026
License
MIT OR Apache-2.0
Source of claims
README.md, docs/ARCHITECTURE.md, docs/DETERMINISM.md, docs/LIMITATIONS.md, docs/UNSUPPORTED.md, CHANGELOG.md, tests/, .github/workflows/ci.yml

A Rust library and the tm CLI. Code reads its nondeterministic inputs through a Ctx; a run is recorded to a checksummed trace; replay answers every input from the trace and reports the exact point where the code takes a different path. Failing traces are shrunk with delta debugging, and a cooperative scheduler records thread interleavings as choices.

01/The problem

A flaky test is one whose inputs you don't control: the clock, a seed, task order, a leftover file, a slow response. Rerunning until it fails explains nothing, and syscall-level recorders like rr are Linux-only and heavyweight.

02/The system

A Rust library and the tm CLI. Code reads its nondeterministic inputs through a Ctx; a run is recorded to a checksummed trace; replay answers every input from the trace and reports the exact point where the code takes a different path. Failing traces are shrunk with delta debugging, and a cooperative scheduler records thread interleavings as choices.

Engine modes (README)6 components
  • Code under test to Ctx
  • Ctx to Sources
  • Ctx to Trace
  • Trace to Divergence
  • Minimizer to Ctx

03/Implementation

  1. 01A Ctx with live, record, replay and drive modes for time, randomness, choices, environment variables, files, network requests and checkpoints, with each call recorded as one trace event.
  2. 02Simulated sources (virtual clock, seeded xoshiro256**, in-memory filesystem) and real ones, each a small trait.
  3. 03Trace format v1: one JSON object per line with an event count and FNV-1a checksum; truncation, reordering, edits and wrong versions are each rejected with a specific error.
  4. 04Divergence diagnostics with the event index, expected and actual request, call sites, the three preceding events and a hint.
  5. 05tm hunt, replay, minimize, inspect, diff and validate; ddmin plus value shrinking over decisions.

04/Engineering

Explicit injection, not interception

Only inputs read through Ctx are controlled. That keeps it portable and test-suite friendly, and the boundary is documented in UNSUPPORTED.md rather than hidden.

Replay doesn't wait

sleep and now are answered from the trace, so replaying a timing bug reproduces even the measured overshoot without real delays.

Bounded trace loading

Traces are streamed line by line through a reader capped at 1 GiB by default, and saved by streaming, fsyncing and renaming.

05/Interface

No product screenshots are published for this project. The visual above is a code-driven representation of how it behaves, built from the repository source — not a screenshot.

06/Tech stack

  • Rust
  • xoshiro256**
  • FNV-1a
  • Delta debugging
  • JSON Lines

07/Result

Verified outcomes

  • Unit, property, acceptance, malformed-input and CLI end-to-end tests; CI on Linux, macOS and Windows; MIT OR Apache-2.0.
  • Reported in the README (one run each, loaded Apple M5): 600 simulated seeds found 98 failures (16.3%), close to the 2-in-12 jitter values (16.7%) that trigger the bug; the fixed variant had none.

Known limitations

  • No syscall interception; no async adapter yet; one deterministic call order per Ctx.
  • Traces are held in memory and may contain sensitive data; not on crates.io.

08/Links

Related work

Next case study

ChaosProxy →