Orchestrata Ultimate › Tests

Tests — a guide to the orchestrata test suite

This page explains the orchestrata test suite for a person who has to run it, read its results, or decide whether a red run means anything.

The numbers below were measured on 2026-10-23 in wt-MAP-PRECOMMIT, at 8a2cb42ad on feat/maps-via-codetools, one commit ahead of master (a4cbc2bdf). Where a number comes from another checkout, the page says so.

The generated reference pages hold the per-module detail:

1. What the suite is

tests/ holds 2,094 Python files. 1,976 of them are test_*.py modules; the rest are conftest.py files (19 of them), fixtures, helpers and __init__.py. There are 50 top-level directories, and 66 test modules sit directly in tests/.

Directory Python files test_*.py modules Area (from the directory and module names)
scripts 294 291 The repo's own tooling: the runner, gates, AST pipeline, map generators, worktree and deploy scripts
agents 136 121 Volks (the agents) and their runtime
verification 117 103 Spec, traceability and conformance checkers
knowledge_graph 114 110 The operational graph: sync, schema, queries
session 107 105 The session controller, goals, handoff, the session CLI
claude 99 99 Claude Code hooks, skills and tools shipped with the repo
core 95 82 Shared core: threading, the test executor, the live observer, config
generated_recovery 88 88 Generated (see below). Excluded from runs
gateway, orchestrator, kernel, postman, … The other runtime subsystems

The generated_* directories

Six directories hold tests that a generator wrote, not a person:

Directory Modules
generated_recovery 88
generated_core 63
generated_agents 50
generated_orchestrator 40
generated_gateway 37
generated_plugin 13

The files are named test_<module>_generated.py. They come from the test generators in src/orchestrata_tools/test_generator/: scripts/gen_tests.py drives EnhancedTestGenerator, and there are Jinja, interface, branch and behavioural generators besides. The generators write interface, branch and behavioural tests against the modules they cover.

tests/generated_recovery and tests/_generated_broken are passed to pytest as --ignore in pyproject.toml, so a normal run never collects them. In September 2026 the generated suites were regenerated with backward-compatible signature pins (see blockers, history section).

Markers

pyproject.toml runs pytest with --strict-markers, so every marker must be declared. Declared markers include:

The default selection is not slow and not llm_integration and not incus_live. The runner overrides that so slow tests are included, and leaves llm_integration and incus_live as opt-in lanes.

2. How to run it

The runner: scripts/run_tests.py

All suite runs go through one entry point, scripts/run_tests.py. It is not plain pytest. It checks inputs, starts or verifies infrastructure, runs blocking static gates, reuses anything already proven green, then runs the rest in batches across worker processes and writes a machine-readable report.

Diagram projects-orchestrata-ultimate-tests-index-1

The run pipeline, read from _main in scripts/run_tests.py through the AST toolkit. Stage numbers are the ones in the source comments.

Modes

From scripts/run_tests.py --help:

You want to… Command Notes
Run named modules or directories .venv/bin/python scripts/run_tests.py tests/scripts/test_worktrees.py tests/core Positional paths; the default is tests/. A path that does not exist aborts the run before any infra starts
Run what a change affects .venv/bin/python scripts/run_tests.py --affected [REV] Resolves the changes since REV (default HEAD) through scripts/affected_tests.py. A subset run: non-authoritative, and the full suite is still owed
Proceed past a refusal --affected-decision "<citation>" Records a human decision that lets a refused resolution run its bounded remainder. RUL-040: a refusal is never a silent full run
Include rehearsal tests --include-rehearsal Real deploy, Incus or tofu surfaces. For a deliberate rehearsal, never for a gate (RUL-039)
Re-run even if proven --force Ignores the proven-run reuse check
Machine output or deep failures --json, --debug --debug captures DEBUG logs into each failing test's report
Tune parallelism -j/--workers (8), -b/--batch-multiplier (6), -t/--timeout (420 s per batch), --backfill (0), --solo-retry-cap (25) Defaults shown in brackets
Skip stages --skip-infra, --skip-services kernel,gateway,redis,graph, --skip-gates, --skip-freshness For debugging only. The flags take no value except --skip-services, and a stray value after one is read as a test path
Extra pytest arguments -a/--pytest-arg (repeatable)

Watching a run: pytest-live and observe-pytest

Never start a run and wait for its exit code (RUL-009). A six-minute run gives no signal until the end, and a hang gives none at all. Start the run in the background and watch it:

pytest-live tests/unit -q &        # any project: uses ./.venv/bin/python, puts the observer plugin on PYTHONPATH
observe-pytest list                # instant: running and finished sessions with pass/fail counts
observe-pytest attach latest       # streams PASS/FAIL, exits when the session finishes

Both tools are deployed at /opt/orchestrata-tools/bin. /usr/local/bin/observe-pytest is a symlink to observe_pytest there, and pytest-live is on PATH too. pytest-live also pins OPENBLAS/OMP/MKL_NUM_THREADS=1, because free-threaded Python aborts when native maths thread pools race. See pytest-live observer and the observe-work skill.

In a Claude session the hooks enforce this:

3. The rules

Rule What it means in practice
RUL-001: no xdist Never pytest -n or --dist. xdist deadlocked this suite in about 78% of runs. Parallelism comes from the batched executor's worker processes, each with its own database slot
RUL-002: no mocks, monkeypatch or skips Tests use the real test fleet. The test-purity gate and a stop-hook enforce it. When a test catches a real bug, fix the code, never the test
Test isolation Every test gets an id and cleans up exactly what it created, in graphs, Redis and the home directory. See the test-isolation skill, test Memgraph isolation, and the teardown and Redis sections of running the test suite
The 300 s cap (RUL-038 amendment) The test phase (preflight and gates excluded) has a hard cap, ORCH_TEST_CAP_SECONDS, default 300 s. The runner prints the selected count first, then a live run X / selected Y · left Z · failed F line. At the cap every child pytest kills itself, the passing modules go into the green ledger, and the run exits non-zero with CAPPED. A pytest session that is not run by a sanctioned runner and selects tests from more than one file is refused at collection. Mohamed kept the 300 s cap on 2026-10-22 ("keep 300s")
RUL-009: observe, never wait blind Background plus observe-pytest, as above
RUL-032: a test runs once per code state A module whose content key matches its last green run is not run again (section 4)
RUL-036: functional or integration Integration means the test uses a fleet service or the network. Functional means fully in-process. The category is derived from fixtures
RUL-038: no containers in test runs No test creates, copies, launches or inits a container or VM. Container code is exercised only by explicit rehearsals. The same page carries the 300 s cap above as an amendment
RUL-039: no rehearsals in the gate Rehearsal-class modules exist but are excluded from gate runs
RUL-040: scope at symbol level A change's blast radius is measured, and an escalation to the full suite is a bug, not an answer

For agents: no test run without Mohamed's permission and an agreed time budget. Reading recorded logs and reports is not a run.

4. The environment and the gates

The test fleet

Tests run against the Incus project orchestrata-test on the isolated bridge 10.53.2.0/24. The fleet holds:

The endpoint profile is env/test.env, with 71 keys and no secrets; secrets layer in from a gitignored file. tests/conftest.py hard-pins the suite to this env and refuses to run if the resolved infra is not on 10.53.2.x. The test env cannot reach prod (Incus ACL). See isolated test fleet.

Since 2026-10-21 the fleet's autostart is off (see the DeepChat review). After a reboot it must be started before integration tests can pass. The runner's infrastructure check (stage 1) reports what is down.

What the pre-push gate runs

scripts/hooks/pre-push, wired through core.hooksPath = scripts/hooks, runs on every push:

  1. It refuses to run the suite from a protected-branch worktree.
  2. It skips the suite if reports/.ship-verified already certifies this exact source id.
  3. It fails closed if the base ref does not resolve.
  4. It computes the range from the commit being pushed: BASE...<pushed sha>, three-dot, committed changes only. With an empty diff it exits 0.
  5. It runs .venv/bin/python scripts/run_tests.py --affected "$RANGE".
  6. On a green run whose report names the pushed HEAD, it writes the source id into reports/.ship-verified, so a re-push of identical source skips the suite.

Diagram projects-orchestrata-ultimate-tests-index-2

Affected-test selection on push, from scripts/hooks/pre-push and the runner's stages.

How affected_tests.py decides:

Since GATE-AFFECTED (68024751d, 2026-10-21), a push of only inert files (docs, config, generated) skips infrastructure and gates entirely.

RUL-032: green-ledger reuse

The runner reuses proven work at two levels:

Today the ledger in wt-MAP-PRECOMMIT holds 9 modules. They come from runs at three commits: 7fa34f61d (2 modules), d4ae44819 (6) and a4cbc2bdf (1). See green ledger.

5. Durations and the slow tail

Most modules are fast, and a few dominate. The components worktree's module duration cache (wt-COMPONENTS/.cache/test_durations.json, last written 2026-10-21) gives:

Measure Value
Modules with a recorded duration 1,962
Sum of module durations 10,124 s
Median module 0.39 s
Modules at 60 s or more 43
Modules at 120 s or more 12
Share of total time in the slowest 50 modules 4,715 s (47%)
Slowest modules (components cache) Seconds
tests/gateway/test_mcp_registration_installer.py 252
tests/core/threading/test_test_executor.py 191
tests/scripts/test_ast_live_sync.py 183
tests/harness/test_cli.py 163
tests/scripts/test_run_tests.py 158
tests/scripts/test_gen_brief_pack.py 158
tests/scripts/test_verify_package.py 157
tests/scripts/test_validate_ci.py 157

Why the tail matters. The executor packs modules into bins by their recorded durations (longest first). One slow module caps how fast a bin can finish, and so how fast the whole run can finish. On 2026-10-21 an affected run of 151 modules lost 137 fast modules this way: a slow Memgraph module in the same bin hit the 420 s batch timeout and took the bin down with it. The cache records contention-free durations, so the packer under-provisioned the bins.

How the runner reports slowness. Any test over 60 s in a run is listed as a defect candidate in the summary. A test marked known_slow has had its slowness reviewed, and is listed separately.

The measured floor. The full gate floors at about 250 s on the dev box. See suite parallelism floor and how the suite got 32% faster.

In this worktree the slowest recent single test is test_gen_codebase_map.py::TestDeterminism::test_two_builds_are_byte_identical: 117 s in one of its recorded runs, 19–32 s in the others (reports/test-durations.ndjson, 691 test records over 9 runs). See durations for the generated per-module table.

6. How to read a report

The canonical report is reports/run-tests-latest.json. The runner writes it atomically, so it is always valid JSON. A scoped run or an abort never overwrites a current full-scope record.

Here is today's report, field by field (read with jq):

Field Today's value Meaning
head_commit a4cbc2bdf… The commit the run tested
dirty_sig 5f1b24f6… A hash of uncommitted changes. Report reuse needs both identities to match
scope 7 paths The tests asked for. "full" for a whole-suite run
affected "subset run — non-authoritative, full suite still owed" Says plainly that this run does not certify the whole suite
affected_details.verdict bounded The selector's verdict
test_totals 134 passed, 0 failed, 0 errors, 0 skipped Test counts, including reused modules' recorded counts
passed / failed / total 1 / 0 / 1 Module counts for modules actually executed this run
module_test_counts test_hooks_pre_commit.py: 12 Tests per executed module
reused 6 modules, 122 tests Proven green earlier and not re-run (RUL-032)
rerun, solo_retry 0, null Batch-failed modules re-run alone. A recovery is a load or order flake and is logged to .flake_recoveries.ndjson
slow_tests, acknowledged_slow empty Over-60 s candidates, and reviewed known_slow tests
rehearsal_excluded empty Modules dropped under RUL-039
time_seconds 30.8 Wall time of the run

So this run executed 12 tests in one module, reused 122 tests from 6 modules, and passed. It is evidence for those 7 paths at a4cbc2bdf only.

Checks that tell you whether to trust a green report:

  1. test_totals.passed is greater than 0. A run that executed nothing is not green.
  2. head_commit is the commit you care about, and dirty_sig matches a clean tree if you need one.
  3. scope is "full", or covers the paths you changed.
  4. failed and test_totals.failed/errors are 0, and rerun.still_failed is empty.
  5. An aborted key means no test ran; its value names the stage that stopped the run.

Before stamping a source as verified, the pre-push hook applies check 1, the head_commit half of check 2, and the failure and error counts of check 4.