70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
"""Tests for client-side opencode-native launch state."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from omnigent.opencode_native_state import (
|
|
read_launch_state,
|
|
write_launch_state,
|
|
)
|
|
|
|
|
|
def test_write_and_read_round_trips(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(tmp_path / "state"))
|
|
write_launch_state("conv_abc", "/repo")
|
|
state = read_launch_state("conv_abc")
|
|
assert state is not None
|
|
assert state.working_directory == "/repo"
|
|
|
|
|
|
def test_missing_state_is_none(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(tmp_path / "state"))
|
|
assert read_launch_state("nope") is None
|
|
|
|
|
|
def test_path_hashes_conversation_id(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
state_root = tmp_path / "state"
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(state_root))
|
|
conversation_id = "../../../etc/passwd"
|
|
digest = hashlib.sha256(conversation_id.encode("utf-8")).hexdigest()[:32]
|
|
write_launch_state(conversation_id, "/repo")
|
|
assert (state_root / digest / "launch.json").is_file()
|
|
assert not (tmp_path / "etc").exists()
|
|
|
|
|
|
def test_relative_path_rejected(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(tmp_path / "state"))
|
|
with pytest.raises(ValueError, match="absolute path"):
|
|
write_launch_state("conv_abc", "relative/dir")
|
|
|
|
|
|
def test_conflicting_write_keeps_original(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(tmp_path / "state"))
|
|
logging.getLogger("omnigent").propagate = True
|
|
write_launch_state("conv_abc", "/original")
|
|
with caplog.at_level(logging.WARNING):
|
|
write_launch_state("conv_abc", "/other")
|
|
state = read_launch_state("conv_abc")
|
|
assert state is not None
|
|
assert state.working_directory == "/original"
|
|
assert any("launch state mismatch" in r.message for r in caplog.records)
|
|
|
|
|
|
def test_malformed_state_is_none(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
state_root = tmp_path / "state"
|
|
monkeypatch.setenv("OMNIGENT_OPENCODE_NATIVE_STATE_DIR", str(state_root))
|
|
digest = hashlib.sha256(b"conv_abc").hexdigest()[:32]
|
|
target = state_root / digest
|
|
target.mkdir(parents=True)
|
|
(target / "launch.json").write_text("{bad", encoding="utf-8")
|
|
assert read_launch_state("conv_abc") is None
|