"""Adversarial branch coverage for CLI lane foundation helpers.""" from __future__ import annotations import json 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 _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 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 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" } 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_artifact_directories_and_foreign_statuses_are_filtered( tmp_path: Path, ): """String directory paths and non-result statuses never become evidence.""" workspace = tmp_path / "workspace" (workspace / "directory").mkdir(parents=True) assert lanes.workspace_artifacts(workspace, ["directory"]) == [] assert lanes._extract_json('{"status": "unknown"}') is None def test_provider_events_without_sessions_or_results_stay_unparsed( tmp_path: Path, ): """Session persistence and result extraction require explicit fields.""" state_file = tmp_path / "state.json" state = {} assert ( lanes._event_payload( "codex", json.dumps({"type": "thread.started", "thread": {}}), state, state_file, ) is None ) assert "codex_thread_id" not in state assert ( lanes._event_payload( "codex", json.dumps({"item": {"text": "no structured result here"}}), state, state_file, ) is None ) direct = lanes._event_payload( "codex", json.dumps({"result": json.dumps(_completed_result("direct"))}), state, state_file, ) assert direct and direct["summary"] == "direct"