test(herdr): add regression tests for pane misattribution and idle-pane reuse

- Add test_r2 and test_r3 for bare-kind fallback restriction and R-1 exact-match enforcement
- Add test_h24 and test_h25 for idle-pane reuse and env_flags preservation
This commit is contained in:
2026-08-30 11:02:51 +09:00
parent b327bc7132
commit 526f7a59b7
2 changed files with 141 additions and 0 deletions
+69
View File
@@ -481,3 +481,72 @@ def test_h23_persisted_workspace_id_scopes_without_env(mam_sandbox, mock_herdr,
persisted = ws_file.read_text().strip()
assert persisted, "new-session must persist workspace id"
assert persisted.startswith("w")
def test_h24_new_session_reuses_idle_pane_without_split(mam_sandbox, mock_herdr, mock_agents):
"""BUG-4: new-session into an existing workspace must reuse an already
idle (agent-less) pane instead of unconditionally splitting a new one."""
tmp_path = mam_sandbox
state = _load_mock_state(mock_herdr)
state["panes"] = [{
"pane_id": "w1:p_idle",
"workspace_id": "w1",
"cwd": str(tmp_path),
"buffer": "",
}]
_write_mock_state(mock_herdr, state)
n_calls = len(state.get("calls", []))
res = _run_lib(
tmp_path,
f'herdr new-session -d -s "test-creator-claude" -c "{tmp_path}" "claude --dangerously-skip-permissions"',
)
assert res.returncode == 0, f"Stderr: {res.stderr}\nStdout: {res.stdout}"
final_state = _load_mock_state(mock_herdr)
agents = final_state.get("agents", {})
matched = [d for n, d in agents.items() if "test-creator-claude" in n]
assert matched, agents
assert matched[0].get("pane_id") == "w1:p_idle", (
f"Expected the idle pane to be reused as-is, not a freshly split one: {matched}"
)
new_calls = final_state.get("calls", [])[n_calls:]
split_calls = [c for c in new_calls if len(c) >= 2 and c[0] == "pane" and c[1] == "split"]
assert not split_calls, f"Expected no pane split call when an idle pane was available: {split_calls}"
def test_h25_new_session_idle_pane_preserves_env_and_ws_id(mam_sandbox, mock_herdr, mock_agents):
"""Finding A: when an idle pane is reused, caller-provided KEY=VAL environment
flags (and HERDR_WORKSPACE_ID) must be prepended via env to final_cmd so they
are not silently lost when pane split / workspace create is bypassed."""
tmp_path = mam_sandbox
state = _load_mock_state(mock_herdr)
state["panes"] = [{
"pane_id": "w1:p_idle",
"workspace_id": "w1",
"cwd": str(tmp_path),
"buffer": "",
}]
_write_mock_state(mock_herdr, state)
n_calls = len(state.get("calls", []))
res = _run_lib(
tmp_path,
f'herdr new-session -d -s "test-creator-claude" -c "{tmp_path}" "MY_TEST_FLAG=active claude --dangerously-skip-permissions"',
)
assert res.returncode == 0, f"Stderr: {res.stderr}\nStdout: {res.stdout}"
final_state = _load_mock_state(mock_herdr)
agents = final_state.get("agents", {})
matched = [d for n, d in agents.items() if "test-creator-claude" in n]
assert matched, agents
assert matched[0].get("pane_id") == "w1:p_idle"
cmd = matched[0].get("command", "")
assert "MY_TEST_FLAG=active" in cmd, f"Expected MY_TEST_FLAG=active in agent command: {cmd}"
assert "HERDR_WORKSPACE_ID=w1" in cmd, f"Expected HERDR_WORKSPACE_ID=w1 in agent command: {cmd}"
new_calls = final_state.get("calls", [])[n_calls:]
split_calls = [c for c in new_calls if len(c) >= 2 and c[0] == "pane" and c[1] == "split"]
assert not split_calls, f"Expected no pane split call when an idle pane was available: {split_calls}"