diff --git a/tests/test_issue17_item4_decisions.py b/tests/test_issue17_item4_decisions.py index fb592d4..342bf29 100644 --- a/tests/test_issue17_item4_decisions.py +++ b/tests/test_issue17_item4_decisions.py @@ -222,10 +222,13 @@ def _shim(tmp_path: Path) -> Path: def _env(tmp_path: Path, **extra) -> dict: + # WORKSPACE_ROOT is this test's tmp_path, never inherited: sourcing the + # wrapper sources lib.sh, which rewrites $WORKSPACE_ROOT/.mam/shim/herdr - + # and unset, lib.sh would derive the checkout itself (Issue #17 follow-up). env = {k: v for k, v in os.environ.items() - if not k.startswith(("HERDR_", "MAM_", "SKS_")) and k not in ("PYTHONPATH",)} + if not k.startswith(("HERDR_", "MAM_", "SKS_")) and k not in ("PYTHONPATH", "WORKSPACE_ROOT")} env.update(MAM_DELEGATE_JOB_NO_MAIN="1", MAM_ENV_FILE=str(tmp_path / ".mam.env.absent"), HOME=str(tmp_path), - DELEGATE_JOB_LOGS_DIR=str(tmp_path / "logs")) + WORKSPACE_ROOT=str(tmp_path), DELEGATE_JOB_LOGS_DIR=str(tmp_path / "logs")) env.update({k: str(v) for k, v in extra.items() if v is not None}) return env @@ -464,6 +467,37 @@ def test_c_mam_int_and_knob(tmp_path, locale, minimum): assert outs[0] == outs[1], outs +def _mtime(path: Path): + try: + return path.stat().st_mtime_ns + except OSError: + return None + + +def test_c_helpers_write_nothing_to_an_inherited_workspace(tmp_path, monkeypatch): + """v4.8.7 review (claude): _env kept an inherited WORKSPACE_ROOT, so every + helper that sources the wrapper (lib.sh) rewrote /.mam/ + shim/herdr - another workspace's, during the PR #51 review. With a sentinel + workspace in the environment, nothing appears under it, the checkout's own + shim is not rewritten either, and the shell sees the test's tmp dir.""" + sentinel = tmp_path / "sentinel-ws" + sentinel.mkdir() + monkeypatch.setenv("WORKSPACE_ROOT", str(sentinel)) + checkout_shim = REPO_ROOT / ".mam" / "shim" / "herdr" + before = _mtime(checkout_shim) + both = _run_both(tmp_path / "both", 'echo "ws=$WORKSPACE_ROOT"\n', {}) + work = tmp_path / "direct" + work.mkdir() + res = subprocess.run(["bash", "-c", f'source "{WRAPPER}"; echo "ws=$WORKSPACE_ROOT"'], capture_output=True, + text=True, cwd=str(work), timeout=60, env=_env(work)) + assert sorted(str(p.relative_to(sentinel)) for p in sentinel.rglob("*")) == [], "written into the sentinel" + assert _mtime(checkout_shim) == before, "the checkout's shim was rewritten" + for rc, out, err, _ in both: + assert rc == 0 and "ws=" in out, (rc, out, err) + assert res.returncode == 0 and f"ws={work}" in res.stdout, (res.stdout, res.stderr) + assert (work / ".mam" / "shim" / "herdr").is_file(), "lib.sh wrote its shim into the test's own root" + + # --------------------------------------------------------------------------- # S - static guard # ---------------------------------------------------------------------------