"""SUPERCHARGE tests for ``muse update-ref``. Coverage tiers -------------- - U (Unit): duration_ms / exit_code in every JSON success path - E (Error): JSON errors → stdout when --json; stderr in text mode - S (Schema): error payload has {error, message, duration_ms, exit_code} - D (Data): exit_code semantics, previous/deleted field accuracy - CAS: compare-and-swap timing and error payloads - P (Perf): duration_ms stays under a sane ceiling - Sec (Security): no traceback on any error path; path traversal rejected - C (Concurrency): independent branches updated safely in parallel threads Utilities used -------------- - ``long_id(hex)`` — ``sha256:<64-hex>`` from a bare hex string - ``short_id(id)`` — ``sha256:<12-hex>`` abbreviated form - ``blob_id(data)`` — ``sha256:`` of arbitrary bytes (unique IDs) """ from __future__ import annotations from collections.abc import Mapping import datetime import json import pathlib import threading from unittest import mock import pytest from muse.core.errors import ExitCode from muse.core.paths import muse_dir, ref_path from muse.core.ids import hash_commit as compute_commit_id, hash_snapshot as compute_snapshot_id from muse.core.store import CommitRecord, SnapshotRecord, write_commit, write_snapshot from muse.core.types import blob_id, long_id, short_id from tests.cli_test_helper import CliRunner, InvokeResult runner = CliRunner() _SNAP_ID: str = compute_snapshot_id({}) _COMMITTED_AT: datetime.datetime = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def _make_repo(tmp_path: pathlib.Path) -> pathlib.Path: repo = tmp_path / "repo" dot_muse = muse_dir(repo) for sub in ("objects", "commits", "snapshots", "refs/heads"): (dot_muse / sub).mkdir(parents=True) (dot_muse / "HEAD").write_text("ref: refs/heads/main") (dot_muse / "repo.json").write_text(json.dumps({"repo_id": "test-repo", "domain": "code"})) return repo def _snap(repo: pathlib.Path) -> str: write_snapshot(repo, SnapshotRecord( snapshot_id=_SNAP_ID, manifest={}, created_at=_COMMITTED_AT, )) return _SNAP_ID def _commit(repo: pathlib.Path, message: str = "test") -> str: snap_id = _snap(repo) commit_id = compute_commit_id( parent_ids=[], snapshot_id=snap_id, message=message, committed_at_iso=_COMMITTED_AT.isoformat(), ) write_commit(repo, CommitRecord( commit_id=commit_id, branch="main", snapshot_id=snap_id, message=message, committed_at=_COMMITTED_AT, )) return commit_id def _write_ref(repo: pathlib.Path, branch: str, commit_id: str) -> None: branch_ref = ref_path(repo, branch) branch_ref.parent.mkdir(parents=True, exist_ok=True) branch_ref.write_text(commit_id) def _ur(repo: pathlib.Path, *args: str) -> InvokeResult: from muse.cli.app import main as cli return runner.invoke( cli, ["update-ref", *args], env={"MUSE_REPO_ROOT": str(repo)}, ) # --------------------------------------------------------------------------- # U — Unit: duration_ms and exit_code in every success JSON path # --------------------------------------------------------------------------- class TestElapsedMsExitCode: """U1–U8: every successful JSON response carries duration_ms and exit_code.""" def test_u1_create_ref_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """U1: creating a new ref emits duration_ms.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "feat/alpha", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert "duration_ms" in data, "duration_ms missing from create-ref JSON" def test_u2_create_ref_has_exit_code_zero(self, tmp_path: pathlib.Path) -> None: """U2: creating a new ref has exit_code 0.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "feat/beta", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert data["exit_code"] == 0 def test_u3_update_ref_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """U3: updating an existing ref emits duration_ms.""" repo = _make_repo(tmp_path) old = _commit(repo, "old") new = _commit(repo, "new") _write_ref(repo, "main", old) r = _ur(repo, "main", new, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert "duration_ms" in data def test_u4_update_ref_has_exit_code_zero(self, tmp_path: pathlib.Path) -> None: """U4: updating an existing ref has exit_code 0.""" repo = _make_repo(tmp_path) old = _commit(repo, "old") new = _commit(repo, "new") _write_ref(repo, "main", old) r = _ur(repo, "main", new, "--json") assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_u5_delete_ref_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """U5: deleting a ref emits duration_ms.""" repo = _make_repo(tmp_path) cid = long_id("a" * 64) _write_ref(repo, "to-del", cid) r = _ur(repo, "--delete", "to-del", "--json") assert r.exit_code == 0 data = json.loads(r.output) assert "duration_ms" in data, "duration_ms missing from delete-ref JSON" def test_u6_delete_ref_has_exit_code_zero(self, tmp_path: pathlib.Path) -> None: """U6: deleting a ref has exit_code 0.""" repo = _make_repo(tmp_path) cid = long_id("b" * 64) _write_ref(repo, "to-del2", cid) r = _ur(repo, "--delete", "to-del2", "--json") assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_u7_duration_ms_is_float(self, tmp_path: pathlib.Path) -> None: """U7: duration_ms is a float (not int, not string).""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "timing-branch", cid, "--json") assert r.exit_code == 0 val = json.loads(r.output)["duration_ms"] assert isinstance(val, float), f"expected float, got {type(val)}" def test_u8_duration_ms_non_negative(self, tmp_path: pathlib.Path) -> None: """U8: duration_ms >= 0.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "timing-branch2", cid, "--json") assert r.exit_code == 0 assert json.loads(r.output)["duration_ms"] >= 0.0 def test_u9_no_verify_success_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """U9: --no-verify path also emits duration_ms.""" repo = _make_repo(tmp_path) cid = long_id("f" * 64) # not in store — valid format, skip verification r = _ur(repo, "--no-verify", "staging", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert "duration_ms" in data def test_u10_short_id_in_output_is_not_expected(self, tmp_path: pathlib.Path) -> None: """U10: commit_id in JSON output is the full long_id (not short_id).""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "full-id-branch", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) # Full id must be present — short_id (12 hex chars) would be truncated assert data["commit_id"] == cid assert len(data["commit_id"]) == 71 # sha256: + 64 hex # --------------------------------------------------------------------------- # E — Error routing: JSON errors → stdout when --json, stderr in text mode # --------------------------------------------------------------------------- class TestJsonErrorsToStdout: """E1–E7: all error paths emit JSON to stdout when --json is active.""" def test_e1_invalid_branch_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E1: invalid branch name → JSON error on stdout, stderr empty.""" repo = _make_repo(tmp_path) r = _ur(repo, "branch\x00null", long_id("a" * 64), "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e2_commit_not_found_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E2: commit not in store → JSON error on stdout, stderr empty.""" repo = _make_repo(tmp_path) cid = long_id("9" * 64) # not in store, valid format r = _ur(repo, "main", cid, "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e3_invalid_commit_id_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E3: malformed commit ID → JSON error on stdout, stderr empty.""" repo = _make_repo(tmp_path) r = _ur(repo, "main", "not-a-valid-id", "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e4_delete_nonexistent_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E4: --delete on nonexistent ref → JSON error on stdout.""" repo = _make_repo(tmp_path) r = _ur(repo, "--delete", "ghost-branch", "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e5_cas_mismatch_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E5: CAS mismatch → JSON error on stdout with current/expected fields.""" repo = _make_repo(tmp_path) actual = _commit(repo, "actual") new_id = _commit(repo, "new") other = blob_id(b"other-id") # valid ID, not the actual value _write_ref(repo, "main", actual) r = _ur(repo, "--old-value", other, "main", new_id, "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e6_no_commit_id_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E6: missing commit_id (no --delete) → JSON error on stdout.""" repo = _make_repo(tmp_path) r = _ur(repo, "main", "--json") assert r.exit_code != 0 assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data def test_e7_text_mode_errors_on_stderr(self, tmp_path: pathlib.Path) -> None: """E7: text mode errors go to stderr (stdout_bytes empty).""" repo = _make_repo(tmp_path) r = _ur(repo, "branch\x00bad", long_id("a" * 64), "--format", "text") assert r.exit_code != 0 assert r.stdout_bytes == b"", f"stdout_bytes should be empty in text mode: {r.stdout_bytes!r}" assert r.stderr.strip() != "", "stderr should have error text in text mode" def test_e8_write_failure_json_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """E8: OSError from write_branch_ref → exit 3, JSON error on stdout.""" repo = _make_repo(tmp_path) cid = _commit(repo) with mock.patch( "muse.cli.commands.update_ref.write_branch_ref", side_effect=OSError("disk full"), ): r = _ur(repo, "main", cid, "--json") assert r.exit_code == ExitCode.INTERNAL_ERROR assert r.stderr.strip() == "", f"stderr should be empty: {r.stderr!r}" data = json.loads(r.output) assert "error" in data assert "disk full" in data.get("message", "") # --------------------------------------------------------------------------- # S — Schema completeness for error payloads # --------------------------------------------------------------------------- class TestErrorJsonSchema: """S1–S5: every JSON error payload has {error, message, duration_ms, exit_code}.""" def _parse_error(self, r: InvokeResult) -> Mapping[str, object]: return json.loads(r.output) def _required_keys(self) -> set[str]: return {"error", "message", "duration_ms", "exit_code"} def test_s1_invalid_branch_error_schema(self, tmp_path: pathlib.Path) -> None: """S1: invalid branch name error has all required keys.""" repo = _make_repo(tmp_path) r = _ur(repo, "bad\x00branch", long_id("a" * 64), "--json") data = self._parse_error(r) missing = self._required_keys() - data.keys() assert not missing, f"missing keys: {missing}" def test_s2_commit_not_found_error_schema(self, tmp_path: pathlib.Path) -> None: """S2: commit-not-found error has all required keys.""" repo = _make_repo(tmp_path) r = _ur(repo, "main", long_id("e" * 64), "--json") data = self._parse_error(r) missing = self._required_keys() - data.keys() assert not missing, f"missing keys: {missing}" def test_s3_cas_mismatch_error_schema(self, tmp_path: pathlib.Path) -> None: """S3: CAS mismatch error has all required keys.""" repo = _make_repo(tmp_path) actual = _commit(repo, "actual") new_id = _commit(repo, "new") wrong = blob_id(b"wrong-old-value") _write_ref(repo, "main", actual) r = _ur(repo, "--old-value", wrong, "main", new_id, "--json") data = self._parse_error(r) missing = self._required_keys() - data.keys() assert not missing, f"missing keys: {missing}" def test_s4_write_failure_error_schema(self, tmp_path: pathlib.Path) -> None: """S4: write-failure error has all required keys.""" repo = _make_repo(tmp_path) cid = _commit(repo) with mock.patch( "muse.cli.commands.update_ref.write_branch_ref", side_effect=OSError("ENOSPC"), ): r = _ur(repo, "main", cid, "--json") data = self._parse_error(r) missing = self._required_keys() - data.keys() assert not missing, f"missing keys: {missing}" def test_s5_error_duration_ms_is_float_non_negative(self, tmp_path: pathlib.Path) -> None: """S5: duration_ms in error JSON is a float >= 0.""" repo = _make_repo(tmp_path) r = _ur(repo, "bad\x00name", long_id("a" * 64), "--json") data = self._parse_error(r) assert isinstance(data["duration_ms"], float) assert data["duration_ms"] >= 0.0 def test_s6_error_exit_code_matches_process_exit(self, tmp_path: pathlib.Path) -> None: """S6: exit_code in JSON matches actual process exit code.""" repo = _make_repo(tmp_path) r = _ur(repo, "bad\x00name", long_id("a" * 64), "--json") data = self._parse_error(r) assert data["exit_code"] == r.exit_code def test_s7_success_json_all_fields_present(self, tmp_path: pathlib.Path) -> None: """S7: create-ref success JSON has branch, commit_id, previous, duration_ms, exit_code.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "schema-check", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) for key in ("branch", "commit_id", "previous", "duration_ms", "exit_code"): assert key in data, f"missing key {key!r} in success JSON" def test_s8_delete_json_all_fields_present(self, tmp_path: pathlib.Path) -> None: """S8: delete-ref success JSON has branch, deleted, duration_ms, exit_code.""" repo = _make_repo(tmp_path) cid = long_id("d" * 64) _write_ref(repo, "del-schema", cid) r = _ur(repo, "--delete", "del-schema", "--json") assert r.exit_code == 0 data = json.loads(r.output) for key in ("branch", "deleted", "duration_ms", "exit_code"): assert key in data, f"missing key {key!r} in delete JSON" # --------------------------------------------------------------------------- # D — Data integrity # --------------------------------------------------------------------------- class TestDataIntegrity: """D1–D8: output values are semantically correct.""" def test_d1_previous_is_none_for_new_ref(self, tmp_path: pathlib.Path) -> None: """D1: previous is null when no ref existed before.""" repo = _make_repo(tmp_path) cid = _commit(repo) data = json.loads(_ur(repo, "fresh-branch", cid, "--json").output) assert data["previous"] is None def test_d2_previous_matches_old_commit(self, tmp_path: pathlib.Path) -> None: """D2: previous matches the commit_id that was there before.""" repo = _make_repo(tmp_path) old = _commit(repo, "old commit") new = _commit(repo, "new commit") _write_ref(repo, "main", old) data = json.loads(_ur(repo, "main", new, "--json").output) assert data["previous"] == old assert data["commit_id"] == new def test_d3_branch_field_matches_arg(self, tmp_path: pathlib.Path) -> None: """D3: branch field in JSON matches the branch argument.""" repo = _make_repo(tmp_path) cid = _commit(repo) data = json.loads(_ur(repo, "my-feature", cid, "--json").output) assert data["branch"] == "my-feature" def test_d4_deleted_true_on_delete(self, tmp_path: pathlib.Path) -> None: """D4: deleted field is boolean true on successful delete.""" repo = _make_repo(tmp_path) _write_ref(repo, "ephemeral", long_id("e" * 64)) data = json.loads(_ur(repo, "--delete", "ephemeral", "--json").output) assert data["deleted"] is True def test_d5_exit_code_1_for_user_errors(self, tmp_path: pathlib.Path) -> None: """D5: user-visible errors (bad branch, not-found commit) use exit_code 1.""" repo = _make_repo(tmp_path) r = _ur(repo, "main", long_id("9" * 64), "--json") # not in store data = json.loads(r.output) assert data["exit_code"] == ExitCode.USER_ERROR def test_d6_exit_code_3_for_write_failure(self, tmp_path: pathlib.Path) -> None: """D6: write failure uses exit_code 3 (internal error).""" repo = _make_repo(tmp_path) cid = _commit(repo) with mock.patch( "muse.cli.commands.update_ref.write_branch_ref", side_effect=OSError("ENOSPC"), ): r = _ur(repo, "main", cid, "--json") data = json.loads(r.output) assert data["exit_code"] == ExitCode.INTERNAL_ERROR def test_d7_cas_mismatch_includes_current_and_expected(self, tmp_path: pathlib.Path) -> None: """D7: CAS error JSON includes current ref value and what was expected.""" repo = _make_repo(tmp_path) actual = _commit(repo, "actual-commit") new_id = _commit(repo, "new-commit") wrong_old = blob_id(b"wrong-expected-value") _write_ref(repo, "main", actual) r = _ur(repo, "--old-value", wrong_old, "main", new_id, "--json") assert r.exit_code == ExitCode.USER_ERROR data = json.loads(r.output) # current and expected give agents enough context to retry correctly assert "current" in data, "CAS error must include current ref value" assert "expected" in data or wrong_old in str(data), "CAS error must include expected value" def test_d8_blob_id_produces_unique_valid_ids(self, tmp_path: pathlib.Path) -> None: """D8: blob_id() always produces distinct valid sha256-prefixed IDs.""" ids = {blob_id(__import__("os").urandom(32)) for _ in range(20)} assert len(ids) == 20, "blob_id must produce unique IDs" for bid in ids: assert bid.startswith("sha256:") assert len(bid) == 71 def test_d9_long_id_produces_correct_prefix(self, tmp_path: pathlib.Path) -> None: """D9: long_id() round-trips correctly through update-ref.""" repo = _make_repo(tmp_path) bare = "c" * 64 cid = long_id(bare) assert cid == f"sha256:{bare}" # Use it as a ref value (bypassing store check) r = _ur(repo, "--no-verify", "long-id-test", cid, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert data["commit_id"] == cid def test_d10_short_id_is_prefix_of_long_id(self) -> None: """D10: short_id is the first 19 chars of long_id (sha256: + 12 hex).""" cid = long_id("abcdef1234567890" * 4) sid = short_id(cid) assert cid.startswith(sid) assert sid.startswith("sha256:") assert len(sid) == 19 # "sha256:" (7) + 12 hex chars # --------------------------------------------------------------------------- # CAS — compare-and-swap error payloads and timing # --------------------------------------------------------------------------- class TestCASSchema: """CAS-specific: error routing and schema when CAS fires.""" def test_cas1_null_guard_mismatch_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """CAS1: --old-value null mismatch (ref exists) error has duration_ms.""" repo = _make_repo(tmp_path) existing = _commit(repo, "existing") new_id = _commit(repo, "new") _write_ref(repo, "contested", existing) r = _ur(repo, "--old-value", "null", "contested", new_id, "--json") assert r.exit_code != 0 data = json.loads(r.output) assert "duration_ms" in data def test_cas2_mismatch_error_to_stdout_not_stderr(self, tmp_path: pathlib.Path) -> None: """CAS2: CAS mismatch with --json → error on stdout, stderr empty.""" repo = _make_repo(tmp_path) actual = _commit(repo, "actual") new_id = _commit(repo, "new") wrong = blob_id(b"wrong-cas-value") _write_ref(repo, "main", actual) r = _ur(repo, "--old-value", wrong, "main", new_id, "--json") assert r.exit_code != 0 assert r.stderr.strip() == "" data = json.loads(r.output) assert "error" in data assert "duration_ms" in data assert "exit_code" in data def test_cas3_success_has_duration_ms(self, tmp_path: pathlib.Path) -> None: """CAS3: successful CAS also emits duration_ms.""" repo = _make_repo(tmp_path) old = _commit(repo, "old") new = _commit(repo, "new") _write_ref(repo, "main", old) r = _ur(repo, "--old-value", old, "main", new, "--json") assert r.exit_code == 0 data = json.loads(r.output) assert "duration_ms" in data def test_cas4_invalid_old_value_format_error_on_stdout(self, tmp_path: pathlib.Path) -> None: """CAS4: bare hex (missing sha256: prefix) in --old-value → JSON error on stdout.""" repo = _make_repo(tmp_path) cid = _commit(repo) bare_hex = "a" * 64 # missing sha256: prefix r = _ur(repo, "--old-value", bare_hex, "main", cid, "--json") assert r.exit_code != 0 assert r.stderr.strip() == "" data = json.loads(r.output) assert "error" in data # --------------------------------------------------------------------------- # P — Performance # --------------------------------------------------------------------------- class TestPerformance: """P1–P3: duration_ms is a realistic duration.""" def test_p1_single_update_under_2000ms(self, tmp_path: pathlib.Path) -> None: """P1: a single ref update finishes in < 2 seconds.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "perf-branch", cid, "--json") assert r.exit_code == 0 assert json.loads(r.output)["duration_ms"] < 2000.0 def test_p2_delete_under_2000ms(self, tmp_path: pathlib.Path) -> None: """P2: a ref delete finishes in < 2 seconds.""" repo = _make_repo(tmp_path) _write_ref(repo, "perf-del", long_id("f" * 64)) r = _ur(repo, "--delete", "perf-del", "--json") assert r.exit_code == 0 assert json.loads(r.output)["duration_ms"] < 2000.0 def test_p3_200_sequential_updates_all_have_duration_ms(self, tmp_path: pathlib.Path) -> None: """P3: 200 sequential updates all emit duration_ms.""" repo = _make_repo(tmp_path) cid = _commit(repo) for i in range(200): r = _ur(repo, "perf-stress", cid, "--json") assert r.exit_code == 0, f"failed at iteration {i}" assert "duration_ms" in json.loads(r.output), f"missing duration_ms at iteration {i}" # --------------------------------------------------------------------------- # Sec — Security: no traceback on any error path # --------------------------------------------------------------------------- class TestSecurity: """Sec1–Sec5: error paths never produce raw Python tracebacks.""" def test_sec1_no_traceback_invalid_branch_json_mode(self, tmp_path: pathlib.Path) -> None: """Sec1: invalid branch name with --json → no Traceback.""" repo = _make_repo(tmp_path) r = _ur(repo, "bad\x00branch", long_id("a" * 64), "--json") assert r.exit_code != 0 assert "Traceback" not in r.output assert "Traceback" not in r.stderr def test_sec2_no_traceback_write_failure_json_mode(self, tmp_path: pathlib.Path) -> None: """Sec2: mocked write failure with --json → no Traceback.""" repo = _make_repo(tmp_path) cid = _commit(repo) with mock.patch( "muse.cli.commands.update_ref.write_branch_ref", side_effect=OSError("permission denied"), ): r = _ur(repo, "main", cid, "--json") assert r.exit_code != 0 assert "Traceback" not in r.output assert "Traceback" not in r.stderr def test_sec3_no_traceback_write_failure_text_mode(self, tmp_path: pathlib.Path) -> None: """Sec3: mocked write failure in text mode → no Traceback.""" repo = _make_repo(tmp_path) cid = _commit(repo) with mock.patch( "muse.cli.commands.update_ref.write_branch_ref", side_effect=OSError("permission denied"), ): r = _ur(repo, "main", cid, "--format", "text") assert r.exit_code != 0 assert "Traceback" not in r.output assert "Traceback" not in r.stderr def test_sec4_path_traversal_in_branch_rejected(self, tmp_path: pathlib.Path) -> None: """Sec4: branch names with ../ path traversal are rejected.""" repo = _make_repo(tmp_path) cid = _commit(repo) r = _ur(repo, "../../../etc/cron.d/malicious", cid, "--json") assert r.exit_code != 0 assert r.stderr.strip() == "" # error in stdout (json mode) data = json.loads(r.output) assert "error" in data def test_sec5_ansi_in_branch_rejected_json_mode(self, tmp_path: pathlib.Path) -> None: """Sec5: ANSI escape codes in branch name are rejected; error to stdout.""" repo = _make_repo(tmp_path) r = _ur(repo, "\x1b[31mbranch", long_id("a" * 64), "--json") assert r.exit_code != 0 assert r.stderr.strip() == "" data = json.loads(r.output) assert "error" in data # --------------------------------------------------------------------------- # C — Concurrency: parallel updates to independent branches # --------------------------------------------------------------------------- class TestConcurrency: """C1: N threads each update a distinct branch — no cross-contamination.""" def test_c1_parallel_independent_branch_updates(self, tmp_path: pathlib.Path) -> None: """C1: 16 threads each write to their own branch — all succeed.""" repo = _make_repo(tmp_path) cid = _commit(repo, "shared commit") N = 16 results: list[InvokeResult | None] = [None] * N errors: list[str] = [] def _worker(idx: int) -> None: branch = f"concurrent-branch-{idx}" r = _ur(repo, "--no-verify", branch, cid, "--json") results[idx] = r if r.exit_code != 0: errors.append(f"thread {idx} failed: exit_code={r.exit_code}") threads = [threading.Thread(target=_worker, args=(i,)) for i in range(N)] for t in threads: t.start() for t in threads: t.join() assert not errors, "\n".join(errors) for i, r in enumerate(results): assert r is not None assert r.exit_code == 0, f"thread {i} non-zero exit" data = json.loads(r.output) assert data["branch"] == f"concurrent-branch-{i}" assert "duration_ms" in data