test(issue-18): rec 5 - acceptance5 uses a fresh session and secret per run, widens the idle window, and skips only on proven broker non-delivery

The remote runner subscribes to every job's retained dispatch topic on the
public broker and serves the first dispatch signed for its session. With the
fixed session name `sim-worker` and a fixed secret, a stale retained dispatch
left by an earlier run verified fine and was served instead of this run's
job, which then timed out: in the observed failure the runner logged
`published started/completed ... job=5eb1abcf` and `DONE rc=0` while the
orchestrator waited on job 5ee3fbcf with nothing received. Each run now uses
a random session name and secret, so stale dispatches cannot match.

Also, per the plan: the no-event window is 10 x 2 s instead of 3 x 2 s, and a
failure skips only when the runner provably published `started` for the
orchestrator's own job, the orchestrator subscribed to that job's topic, and
received and dropped nothing for it (broker non-delivery). Every other failure
still fails. The runner's own `started --heartbeat` already covers the window.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
This commit is contained in:
GodopuandClaude Opus 5 committed 2026-09-14 20:55:48 +00:00
1 parent e57663ac4c
commit 7bc3e1a288
1 file changed
+39 -4
+39 -4
View File
@@ -24,6 +24,7 @@ sandbox); each stays under a minute.
from __future__ import annotations
import json
import re
import os
import signal
import subprocess
@@ -1160,17 +1161,49 @@ def test_acceptance3_lost_heartbeats_close_the_job_and_a_late_completed_is_refus
# 6. remote transport (broker): no shared disk, no pane, only the wire
# ---------------------------------------------------------------------------
def _skip_if_broker_did_not_deliver(reg: Path, runner_log: Path) -> None:
"""acceptance5 runs over a public broker. The remote runner already covers
the idle window with `started --heartbeat` (remote.py handle_dispatch). The
observed failures were of one kind: the runner published started and
completed successfully, the orchestrator had subscribed to the right topic,
and it received nothing at all for the job - the broker did not deliver.
Only that proven non-delivery skips; a drop (HMAC, identity), a wrong
topic, or a runner that failed to publish still fails."""
log = runner_log.read_text(errors="replace")
m = re.search(r"published started seq=1 job=(\w+)", log)
if not m:
return
jid = m.group(1)
rec = reg / f"{jid}.json"
if not rec.exists():
return
topic = json.loads(rec.read_text()).get("topic_prefix") or ""
out = reg / f"{jid}.subscriber.out"
sub = out.read_text(errors="replace") if out.exists() else ""
if (topic and f"SUBSCRIBED {topic}/events" in sub
and f"job={jid}" not in sub and f"drop event for job {jid}" not in sub):
pytest.skip(f"public broker did not deliver the runner's events to the orchestrator "
f"(runner published started for {jid}; subscriber received nothing for it)")
def test_acceptance5_remote_runner_completes_a_job_over_the_broker_only(tmp_path):
orch = tmp_path / "orchestrator"
remote = tmp_path / "remote-host"
for d in (orch, remote):
(d / "jobs").mkdir(parents=True)
secret = "issue18-shared-secret"
# A fresh session name and secret per run: dispatches are retained on the
# (public) broker and the runner subscribes to every job's dispatch topic,
# so with fixed values a stale dispatch left by an earlier run was served
# instead of this run's job, which then timed out (observed: runner DONE
# for one job id, the orchestrator waiting on another).
tag = os.urandom(4).hex()
session = f"sim-worker-{tag}"
secret = f"issue18-shared-secret-{tag}"
runner_env = _env(remote, {"MAM_DISPATCH_SECRET": secret, "MAM_JOBS_DIR": str(remote / "jobs")})
runner_log = remote / "runner.log"
with open(runner_log, "wb") as log:
runner = subprocess.Popen(
[sys.executable, str(REMOTE_PY), "run", "--session", "sim-worker", "--registry-dir", str(remote / "jobs"),
[sys.executable, str(REMOTE_PY), "run", "--session", session, "--registry-dir", str(remote / "jobs"),
"--exec", 'echo "remote work done for $JOB_ID"', "--once", "--timeout", "150"],
cwd=str(remote), env=runner_env, stdout=log, stderr=subprocess.STDOUT)
try:
@@ -1181,11 +1214,13 @@ def test_acceptance5_remote_runner_completes_a_job_over_the_broker_only(tmp_path
pytest.skip("broker unreachable: " + runner_log.read_text(errors="replace")[-300:])
reg = orch / "jobs"
proc, env = _submit(orch, reg, "remote:sim-worker", "remote",
["--heartbeat", "2", "--heartbeat-misses", "3", "--ack-timeout", "60"],
proc, env = _submit(orch, reg, f"remote:{session}", "remote",
["--heartbeat", "2", "--heartbeat-misses", "10", "--ack-timeout", "60"],
env_extra={"MAM_DISPATCH_SECRET": secret}, timeout_s=120)
stdout, stderr = proc.communicate(timeout=180)
jid = _wait_job_id(reg)
if proc.returncode != 0:
_skip_if_broker_did_not_deliver(reg, runner_log)
assert proc.returncode == 0, f"rc={proc.returncode}\n{stdout}\n{stderr}\nrunner:\n{runner_log.read_text()}"
assert "subscriber received started" in stderr or "advanced to 'running'" in stderr
assert _job(reg, jid)["status"] == "completed", \