Skip to content
Python Basics: Test Scheduled Event Order with a Virtual Clock

Python Basics: Test Scheduled Event Order with a Virtual Clock

October 28, 2026

A scheduler test does not need real sleeping. Supplying a virtual clock makes deadlines, priorities, and cancellation deterministic while leaving the event queue behavior intact.

Prepare a scratch directory

Tested on Linux with CPython 3.12.14. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. Run Python without -O so assertions remain enabled. The examples use only controlled local data; generated fixture directories are cleaned automatically.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-sched.py:

import sched

now = [0.0]
seen = []

def delay(seconds):
    now[0] += seconds

def record(label):
    seen.append(label)
    print(f"{now[0]:.0f}: {label}")

queue = sched.scheduler(lambda: now[0], delay)
queue.enterabs(5, 2, record, argument=("normal",))
queue.enterabs(5, 1, record, argument=("urgent",))
cancelled = queue.enterabs(3, 1, record, argument=("cancelled",))
queue.cancel(cancelled)
queue.enterabs(1, 1, record, argument=("early",))
queue.run()
assert seen == ["early", "urgent", "normal"]
assert queue.empty() and now[0] == 5
print("Queue empty:", queue.empty())

Run it:

python3 -B demonstrate-sched.py

Observed output:

1: early
5: urgent
5: normal
Queue empty: True

Read the result

The injected delay function advances time instead of sleeping. The earlier deadline runs first; lower numeric priority wins when two deadlines match. Cancelling the saved event removes it before execution.

Apply it carefully

This clock is a test double, not a production timing implementation. The default scheduler uses a monotonic clock and real sleep. Actions run synchronously, so a slow action delays later events. Priority does not preempt an action that is already running.

The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.

Clean up

Remove the saved source, return to the starting directory, then remove the empty practice directory:

rm -- demonstrate-sched.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect its remaining contents rather than deleting unknown files.

Acknowledgements

This post was created with assistance from AI.

Last updated on