d198dd5fixed one helper; the same defect was in eleven more modules (reviews grok and codex R1/R2): their shells inherited the process environment, so each `source lib.sh` rewrote <WORKSPACE_ROOT>/.mam/shim/herdr - the checkout's own when the variable is unset or names this checkout (which pytest_configure keeps), another workspace's under --noconftest. - conftest: own_workspace_root, an opt-in fixture setting WORKSPACE_ROOT to <tmp_path>/.mam-test-state/workspace. Not autouse: runner.py and mqtt_common read WORKSPACE_ROOT in-process, and some tests unset it on purpose. mam_sandbox and explicit envs run later and still win. - pytestmark usefixtures("own_workspace_root") in test_version_consistency, test_b19_headless_reconcile_fixes, test_b8_send_keys_verification, test_issue6_fail_closed, test_loop_cli, test_issue5_phase3_loop, test_issue5_phase4_runtime, test_o3_scoped_guard, test_issue25_plan_reuse, test_orc_onboard (their shells inherit os.environ, many with no env at all). - test_orc_onboard (R2): SCRUBBED_ENV is taken at import and no longer carries WORKSPACE_ROOT; every call builds _scrubbed_env(root) with the root of the call (ws / cwd / mam_sandbox, else this test's). - test_workspace_scope (unittest) and test_issue21_worktree_prereqs._mutate pin the root they already create. Tests (test_issue17_workspace_root_isolation.py): W1 copies the checkout and runs one test of each of those modules there with WORKSPACE_ROOT naming the copy - the copy gets no .mam; W2 imports test_orc_onboard under a sentinel root, then calls it under another - the sentinel stays empty. Atd198dd5both fail (the copy gets .mam/shim/herdr; the sentinel gets it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HCGpJXhSZasJLU38ksDghe
40 lines
1.6 KiB
Python
40 lines
1.6 KiB
Python
import os
|
|
import subprocess
|
|
import pytest
|
|
|
|
# Issue #17: shells started here inherit a WORKSPACE_ROOT of this test's own
|
|
# (lib.sh would otherwise rewrite the checkout's .mam/shim/herdr).
|
|
pytestmark = pytest.mark.usefixtures("own_workspace_root")
|
|
|
|
def test_send_keys_safe_b8_verification(tmp_path):
|
|
"""Verify that send_keys_safe for agy sessions goes through submission verification and does not return 0 blindly on failure."""
|
|
# Test script that mocks herdr commands and tests send_keys_safe behavior for agy
|
|
test_script = f"""#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
SKILL_DIR="{os.path.abspath('.agents/skills')}"
|
|
source "$SKILL_DIR/lib.sh"
|
|
|
|
# Mock _pane_quiescent to succeed
|
|
_pane_quiescent() {{ return 0; }}
|
|
_pane_dialog_open() {{ return 1; }}
|
|
|
|
# Mock _sks_herdr commands
|
|
_sks_herdr() {{
|
|
if [ "${{1:-}}" = "agent" ] && [ "${{2:-}}" = "prompt" ]; then
|
|
echo "unknown command: agent prompt" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}}
|
|
|
|
# Mock _pane_capture to simulate fixed pane content (no execution token, no pane change)
|
|
_pane_capture() {{ echo "static content"; }}
|
|
|
|
# Running send_keys_safe for agy session when submission is NOT accepted
|
|
send_keys_safe "test-workspace-creator-agy" "test prompt" "job-123"
|
|
"""
|
|
res = subprocess.run(["bash", "-c", test_script], capture_output=True, text=True)
|
|
# Since submission failed after 3 tries (pane static, no token), it must return exit code 4 (not 0)
|
|
assert res.returncode == 4, f"Expected returncode 4 on submission failure for agy, got {res.returncode}. Output: {res.stdout} {res.stderr}"
|
|
assert "Enter not accepted after 3 tries" in res.stderr
|