Skip to content

fix(tests): WAL-pinning for all inline NullRunRuntime creations#63

Merged
maltsev-dev merged 2 commits into
masterfrom
fix/wal-pinning-all-inline-ctors
Jul 11, 2026
Merged

fix(tests): WAL-pinning for all inline NullRunRuntime creations#63
maltsev-dev merged 2 commits into
masterfrom
fix/wal-pinning-all-inline-ctors

Conversation

@maltsev-dev

Copy link
Copy Markdown
Member

Summary

Follows up on #62 (commit 41a16f7) which pinned NULLRUN_WAL_PATH for the test_runtime fixture only. Other tests in test_protect_branches.py / test_runtime_branches.py / test_toolbox_langgraph.py build NullRunRuntime inline (no fixture) and were still picking up a stale WAL from a previous test run, causing NullRunAuthError: Invalid API key in test (3.12).

CI run 29158094827 — test (3.12) failed on test_protect_async_kill_re_raises_WorkflowKilledInterrupt. The fail-fast: true matrix strategy stopped 3.11 mid-run, then coverage also failed because it depends on the test job.

Root cause

test_protect_async_kill_re_raises_WorkflowKilledInterrupt builds NullRunRuntime(api_key="test-key-12345678", _test_mode=True) inline (no test_runtime fixture), so my previous fix on the fixture didn't cover it. Same pattern in:

  • test_get_protected_runtime_falls_back_to_get_runtime (inline _instance = NullRunRuntime(...))
  • _make_test_runtime / _make_runtime_with_mocked_auth helpers in test_runtime_branches.py
  • autouse _test_runtime fixture in test_toolbox_langgraph.py

What changed

  1. New make_test_runtime factory fixture in tests/conftest.py — pins NULLRUN_WAL_PATH to tmp_path, stubs _do_flush / _do_flush_locked / _client, resets the singleton around the factory. This is the canonical helper that all inline-runtime tests should use.

  2. 4 inline NullRunRuntime(...) calls in test_protect_branches.py replaced with make_test_runtime():

  3. test_runtime_branches.py: local _make_test_runtime / _make_runtime_with_mocked_auth helpers now set NULLRUN_WAL_PATH to a per-call tempfile.mkdtemp() before constructing the runtime. setdefault so an outer-session pinning (from make_test_runtime) is preserved.

  4. test_toolbox_langgraph.py: autouse _test_runtime fixture now takes tmp_path and pins NULLRUN_WAL_PATH.

Verified locally

  • pytest tests/ -n auto (Python 3.11):
    • 1219 passed, 1 failed, 7 skipped, 26 warnings
    • 1 failure: test_actions.py::TestPauseAction::test_is_paused_respects_cooldownpre-existing flake on master (verified by git stash + repro on bare master, NOT introduced by this commit).
    • 0 errors (was 2 errors before this commit on the same code).
  • ruff check src/: All checks passed
  • mypy src/: Success: no issues found in 34 source files

Public API

Unchanged. No SDK_MIN_VERSION bump. Backends on 1.0.0 keep working unchanged. No version bump needed.

The test_runtime fixture in test_protect_branches.py built a
real NullRunRuntime(api_key, _test_mode=True) without going
through the mock_api conftest. The runtime's Transport.start()
calls _replay_from_wal() which reads /tmp/nullrun.wal (the
default NULLRUN_WAL_PATH fallback). If a previous test run in
a different Python version (3.10 or 3.12) had persisted a
non-empty WAL, the 3.11 worker would replay those events to a
real HTTP endpoint, get HTTP 401, and the fixture would fail
at setup with NullRunAuthError:

  nullrun.breaker.exceptions.NullRunAuthError: Invalid API key

This bit CI on 2026-07-11 (run 29156199607): tests 3.10 + 3.12
passed, test 3.11 failed with that error in the fixture setup
of test_enforce_sensitive_tool_dict_with_fallback_fail_open.
The 3.10/3.12 runs cleared the global /tmp/nullrun.wal by
reading it first, so 3.11 picked up the next writer. Order-
dependent; flaky on the matrix.

Pin NULLRUN_WAL_PATH to a tmp_path-scoped file so each test
session reads its own fresh empty WAL. Resolves the flake
without touching SDK source (no production code change).

Verified locally:
- pytest tests/test_protect_branches.py  -> 43/43 pass
- with pre-seeded stale /tmp/nullrun.wal, the previously
  failing test now passes.

No public API change. No SDK_MIN_VERSION bump. Backends on
1.0.0 keep working unchanged. Recommended: 0.13.6 (no
version bump needed for a test-only fix).
Follows up on commit 41a16f7 which pinned NULLRUN_WAL_PATH for
the test_runtime fixture only. Other tests in
test_protect_branches.py / test_runtime_branches.py /
test_toolbox_langgraph.py build NullRunRuntime inline (no
fixture) and were still picking up a stale WAL from a previous
test run, causing HTTP 401 `NullRunAuthError` in 3.12 (CI
run 29158094827, job `test (3.12)`).

This commit:
1. Adds a shared `make_test_runtime` factory fixture to
   conftest.py that pins NULLRUN_WAL_PATH to tmp_path, stubs
   _do_flush / _do_flush_locked / _client, and resets the
   singleton around the factory.
2. Replaces 4 inline `NullRunRuntime(api_key=..., _test_mode=True)`
   calls in test_protect_branches.py with `make_test_runtime()`,
   including:
     - test_protect_async_kill_re_raises_WorkflowKilledInterrupt
     - test_get_protected_runtime_falls_back_to_get_runtime
3. Patches the local _make_test_runtime / _make_runtime_with_mocked_auth
   helpers in test_runtime_branches.py to set NULLRUN_WAL_PATH
   per-call (via tempfile.mkdtemp) before constructing the
   runtime.
4. Extends the autouse _test_runtime fixture in
   test_toolbox_langgraph.py to take tmp_path and pin
   NULLRUN_WAL_PATH, matching conftest::make_test_runtime.

Verified locally on 3.11:
- pytest tests/ -n auto:
    1219 passed, 1 failed, 7 skipped
    (1 failure: test_actions.py::TestPauseAction
     ::test_is_paused_respects_cooldown — pre-existing flake
     on master, NOT introduced by this commit; verified by
     git stash + repro on bare master)
- ruff check src/: all checks passed
- mypy src/: success, no issues in 34 source files

Public API unchanged. No SDK_MIN_VERSION bump. Backends on
1.0.0 keep working unchanged. Recommended: 0.13.6 (no version
bump needed).
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@maltsev-dev
maltsev-dev merged commit 459ab16 into master Jul 11, 2026
5 checks passed
@maltsev-dev
maltsev-dev deleted the fix/wal-pinning-all-inline-ctors branch July 12, 2026 11:56
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.

1 participant