R7: factor run_job/run_job_capture onto one shared core

The two were ~90% identical (lock/skip, job_runs create, subprocess exec,
timeout/kill, finalize) and had already drifted once during the use_lock
change. Extract _execute(capture=bool) plus _record_run/_finalize_run helpers;
run_job and run_job_capture become thin wrappers. run_job_capture also gains
the use_lock parameter for free. Behavior is unchanged.

Covered by tests/test_pipeline_runner.py, now including run_job_capture output
capture + persistence and its skipped-lock case (42 tests green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
andrew
2026-07-10 16:11:12 -06:00
parent bcd07750bf
commit 1b775e42f0
2 changed files with 133 additions and 153 deletions
+22
View File
@@ -58,3 +58,25 @@ def test_timeout_kills_and_marks_failed():
run = _run(pr.run_job("test:timeout", ["sleep", "5"], timeout=0.3))
assert run.status == "failed"
assert run.exit_code == -1
def test_run_job_capture_returns_and_persists_output():
from pathlib import Path
run, out = _run(pr.run_job_capture("test:cap", ["sh", "-c", "echo hello; echo world"]))
assert run.status == "success"
assert "hello" in out and "world" in out
assert "hello" in Path(run.log_path).read_text() # also written to the log file
def test_run_job_capture_skips_when_locked():
async def scenario():
await pr._lock.acquire()
try:
return await pr.run_job_capture("test:caplock", ["true"])
finally:
pr._lock.release()
run, out = _run(scenario())
assert run.status == "skipped_lock"
assert out == ""