"""Adversarial branch coverage for CLI lane foundation helpers.""" from __future__ import annotations import json import os import runpy import sqlite3 from contextlib import nullcontext from pathlib import Path from types import SimpleNamespace from urllib.error import URLError import pytest from testing.tests.test_hermes_cli_support import SCRIPTS, _completed_result, lanes def test_board_context_serializes_objects_and_storage_failure_is_bounded( monkeypatch, ): db = SimpleNamespace(build_worker_context=lambda _conn, _task: {"priority": 3}) assert lanes._task_context(db, object(), "t_ctx") == '{\n "priority": 3\n}' connections = [] class Connection: def close(self): connections.append("closed") failing = SimpleNamespace( scoped_current_board=lambda _board: nullcontext(), connect=lambda board: Connection(), ) monkeypatch.setattr(lanes, "KANBAN_STORAGE_ATTEMPTS", 2) monkeypatch.setattr(lanes.time, "sleep", lambda _seconds: None) with pytest.raises(sqlite3.OperationalError, match="volume unavailable"): lanes._board_call( failing, "cassandra", lambda _conn: (_ for _ in ()).throw( sqlite3.OperationalError("volume unavailable") ), ) assert connections == ["closed", "closed"] def test_atomic_json_closes_an_unwrapped_descriptor_on_open_failure( tmp_path: Path, monkeypatch, ): destination = tmp_path / "state.json" real_fdopen = lanes.os.fdopen descriptors = [] def fail_fdopen(descriptor, *_args, **_kwargs): descriptors.append(descriptor) raise OSError("cannot wrap descriptor") monkeypatch.setattr(lanes.os, "fdopen", fail_fdopen) with pytest.raises(OSError, match="cannot wrap"): lanes.atomic_json(destination, {"safe": True}) monkeypatch.setattr(lanes.os, "fdopen", real_fdopen) assert descriptors with pytest.raises(OSError): lanes.os.fstat(descriptors[0]) assert list(tmp_path.glob("*.tmp")) == [] def test_json_and_terminal_path_helpers_fail_closed(tmp_path: Path, monkeypatch): invalid = tmp_path / "invalid.json" invalid.write_bytes(b"\xff") assert lanes.load_json(invalid) == {} array = tmp_path / "array.json" array.write_text("[]", encoding="utf-8") assert lanes.load_json(array) == {} with pytest.raises(ValueError, match="journal state"): lanes._terminal_path(tmp_path / "task.json", 1, "prepared") with pytest.raises(ValueError, match="SQLite"): lanes._terminal_path(tmp_path / "task.json", True) monkeypatch.setattr(lanes, "STATE_ROOT", tmp_path / "lanes") outside = tmp_path / "outside.run-1.terminal.pending.json" assert lanes._terminal_identity(outside) is None nested = lanes.STATE_ROOT / "board" / "nested" / "x.json" assert lanes._terminal_identity(nested) is None missing = lanes.STATE_ROOT / "board" / "t.run-1.terminal.pending.json" assert lanes._terminal_identity(missing) is None assert lanes._terminal_evidence_identity(outside) is None assert lanes._terminal_evidence_identity(nested) is None missing_evidence = lanes.STATE_ROOT / "board" / ( "t.run-1.terminal.prepared-" + "a" * 32 + ".json" ) assert lanes._terminal_evidence_identity(missing_evidence) is None with pytest.raises(ValueError, match="positive SQLite"): lanes.TerminalIdentity("board", "task", 0, "pending") def test_recovery_snapshot_close_is_idempotent_after_descriptors_are_released( tmp_path: Path, ): directory = os.open(tmp_path, os.O_RDONLY | getattr(os, "O_DIRECTORY", 0)) snapshot = lanes.TerminalRecoverySnapshot( None, tmp_path.stat(), None, directory, b"", "synthetic", ) snapshot.close() snapshot.close() assert snapshot.directory_descriptor == -1 def test_goal_helpers_cover_compaction_and_deterministic_failures(): compacted = lanes.cli_lane_goal._bounded("a" * 100, 40) assert len(compacted) == 40 assert "compacted" in compacted assert lanes.cli_lane_goal.unfinished_result_reason( {"status": "incomplete", "summary": ""} ) == "worker explicitly reported incomplete work" assert lanes.cli_lane_goal.unfinished_result_reason( {"status": "blocked", "summary": "waiting"} ) is None assert "blockers" in lanes.cli_lane_goal.unfinished_result_reason( {"status": "completed", "summary": "done", "blockers": ["remote"]} ) assert "unfinished" in lanes.cli_lane_goal.unfinished_result_reason( { "status": "completed", "summary": "verification is pending", "blockers": [], "tests_run": [], } ) accepted, reason = lanes.cli_lane_goal.judge_goal_completion( "finish", {"status": "incomplete", "summary": "still running"}, open_request=lambda *_args, **_kwargs: pytest.fail("network must not run"), ) assert accepted is False assert reason assert lanes.cli_lane_goal.unfinished_result_reason( {"status": "completed", "summary": "done", "tests_run": "not-a-list"} ) is None def test_prompt_artifact_and_json_helpers_reject_unsafe_inputs( tmp_path: Path, ): workspace = tmp_path / "workspace" workspace.mkdir() artifact = workspace / "evidence.txt" artifact.write_text("evidence", encoding="utf-8") outside = tmp_path / "outside.txt" outside.write_text("outside", encoding="utf-8") directory = workspace / "directory" directory.mkdir() assert lanes.workspace_artifacts(workspace, "not-a-list") == [] assert lanes.workspace_artifacts( workspace, [None, "", "missing", outside, directory, artifact, str(artifact)], ) == [str(artifact.resolve())] assert lanes._extract_json({"status": "completed"}) == {"status": "completed"} assert lanes._extract_json(42) is None assert lanes._extract_json("not json") is None assert lanes._extract_json('prefix {"status":"blocked"} suffix') == { "status": "blocked" } assert lanes._extract_json('{"status":"unknown"}') is None state_file = workspace / "state.json" state = {} assert lanes._event_payload( "codex", json.dumps({"type": "thread.started", "result": {"status": "blocked"}}), state, state_file, ) == {"status": "blocked"} assert lanes._event_payload( "claude", json.dumps({"session_id": "session-2", "text": "not-json"}), state, state_file, ) is None assert state["claude_session_id"] == "session-2" prompt_module = __import__("cli_lane_prompt") assert prompt_module.workspace_artifacts( workspace, [str(directory), str(artifact)] ) == [str(artifact.resolve())] assert prompt_module._event_payload( "other", '{"item": {}}', {}, state_file ) is None def test_provider_event_parsing_persists_sessions_and_nested_results( tmp_path: Path, ): state_file = tmp_path / "state.json" state = {} assert lanes._event_payload("codex", "not-json", state, state_file) is None assert lanes._event_payload("codex", "[]", state, state_file) is None assert ( lanes._event_payload( "codex", json.dumps({"type": "thread.started", "thread": {"id": "thread-1"}}), state, state_file, ) is None ) assert state["codex_thread_id"] == "thread-1" result = lanes._event_payload( "claude", json.dumps( { "session_id": "session-1", "item": {"content": json.dumps(_completed_result("nested"))}, } ), state, state_file, ) assert result and result["summary"] == "nested" assert state["claude_session_id"] == "session-1" @pytest.mark.parametrize("assignee", ["cli-codex-max", "worker-auto", ""]) def test_routing_rejects_invalid_assignees(assignee: str): with pytest.raises(ValueError, match="unsupported"): lanes.parse_assignee(assignee) @pytest.mark.parametrize( "target", ["codex/model/high", "worker/local/model/high", "worker/codex/model/max"], ) def test_worker_target_decoder_rejects_invalid_targets(target: str): with pytest.raises(RuntimeError): lanes._decode_worker_target(target) def test_switchyard_network_failure_is_explicit(): with pytest.raises(RuntimeError, match="routing failed"): lanes.select_route( "objective", "cli-auto", open_request=lambda *_args, **_kwargs: (_ for _ in ()).throw( URLError("offline") ), ) def test_runner_main_guard_delegates_to_dispatch(monkeypatch): dispatch = __import__("cli_lane_dispatch") monkeypatch.setattr(dispatch, "main", lambda: 17) with pytest.raises(SystemExit) as raised: runpy.run_path(str(SCRIPTS / "cli_lane_runner.py"), run_name="__main__") assert raised.value.code == 17