Skip to content

feat(testing): add skip-time virtual clock#523

Open
yaythomas wants to merge 1 commit into
mainfrom
feat/skip-time-clock
Open

feat(testing): add skip-time virtual clock#523
yaythomas wants to merge 1 commit into
mainfrom
feat/skip-time-clock

Conversation

@yaythomas

Copy link
Copy Markdown
Contributor

Description of changes:

  • Add Clock protocol with RealClock and SkipClock implementations
  • Give each ExecutionWorker its own clock via the registry factory
  • Drive wait and step-retry timers off the clock so modeled delays complete instantly under skip while history keeps real durations
  • Default DurableFunctionTestRunner to skip_time=True; pass skip_time=False for real wall-clock timing
  • Remove the DURABLE_EXECUTION_TIME_SCALE env-var scaling

Issue #, if available:
closes #437

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@yaythomas yaythomas force-pushed the feat/per-execution-worker branch from 5c208f2 to 355edf1 Compare July 9, 2026 08:49
@yaythomas yaythomas force-pushed the feat/skip-time-clock branch from 346a870 to 2e9ba2b Compare July 9, 2026 08:56
@yaythomas yaythomas force-pushed the feat/per-execution-worker branch 2 times, most recently from 9829546 to 71962f1 Compare July 9, 2026 14:50
@yaythomas yaythomas force-pushed the feat/skip-time-clock branch 2 times, most recently from d2f04f2 to c494657 Compare July 9, 2026 15:27
@yaythomas yaythomas force-pushed the feat/per-execution-worker branch from 71962f1 to 11103e3 Compare July 10, 2026 00:32
@yaythomas yaythomas force-pushed the feat/skip-time-clock branch from c494657 to c1b3e66 Compare July 10, 2026 09:18
zhongkechen
zhongkechen previously approved these changes Jul 10, 2026

@zhongkechen zhongkechen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Base automatically changed from feat/per-execution-worker to main July 13, 2026 20:15
@yaythomas yaythomas dismissed zhongkechen’s stale review July 13, 2026 20:15

The base branch was changed.

@yaythomas yaythomas force-pushed the feat/skip-time-clock branch from c1b3e66 to c317391 Compare July 13, 2026 20:19
@yaythomas yaythomas requested a review from zhongkechen July 13, 2026 20:20
@yaythomas

yaythomas commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

rebased on main, no other change

[edit:] ooh hang on CI failures 😕 , investigating

zhongkechen
zhongkechen previously approved these changes Jul 13, 2026
@yaythomas yaythomas dismissed zhongkechen’s stale review July 13, 2026 20:37

failing tests, fix inbound

@zhongkechen

Copy link
Copy Markdown
Contributor

seems wait_for_callback(...) failed before the test ever sends a callback.

@yaythomas yaythomas force-pushed the feat/skip-time-clock branch from c317391 to 907f424 Compare July 14, 2026 00:16
- Add Clock protocol with RealClock and SkipClock implementations
- SkipClock returns real time plus the accumulated skipped duration,
  so virtual time advances with real time between jumps and every
  read stays monotonic and distinct
- One clock per runner, shared by the Executor, CheckpointProcessor,
  and all timestamp stamping, so history events form a single totally
  ordered clock domain
- Drive wait and step-retry timers off the clock so modeled delays
  complete instantly under skip while history keeps modeled durations
- Stamp operation, invocation, and execution start/end timestamps
  from the clock; reconstruct operations from event timestamps
- Ban datetime.now via ruff TID251 outside clock.py so all time reads
  go through the clock
- Default DurableFunctionTestRunner to skip_time=True; pass
  skip_time=False for real wall-clock timing
- Remove the DURABLE_EXECUTION_TIME_SCALE env-var scaling
@yaythomas yaythomas force-pushed the feat/skip-time-clock branch from 907f424 to 089c4b8 Compare July 14, 2026 00:30
@yaythomas

yaythomas commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

changed:

  1. Advancing SkipClock: now() = real time + accumulated skip, arm() adds the gap — monotonic, distinct timestamps, matching fake-timers shouldAdvanceTime: true.
  2. Per-runner clock: registry and worker are clock-free again; one Clock is shared by the Executor, CheckpointProcessor, and both runner types.
  3. All history stamp sites moved to the clock: execution start/end, wait and callback completions, invocation start/end, the history fallback, and the stop response now reuses the stamped time. events_to_operations uses the event's own timestamp instead of wall-clock. Test-only fallbacks go through real_now().
  4. TID251 ruff ban on datetime.now outside clock.py — verified it fires on a synthetic violation.

Verification: 1353 testing-package tests pass, full workspace run 2883 passed, the 4 previously failing callback tests pass locally and in CI, mypy clean (119 files), hatch fmt --check clean.

3.13 integration test failure failing only on test_otel_logger_example_spans_in_xray, which is known pre-existing OTel X-Ray flk.

@yaythomas yaythomas requested a review from zhongkechen July 14, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Testing] [Feature]: Add option to skip time in test runner

2 participants