222 lines
6.5 KiB
Python
222 lines
6.5 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess # nosec B404
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
from grok_support import (
|
|
AGENT_ID,
|
|
VALID_PRIVATE_KEY,
|
|
prepare_fixture,
|
|
write_text,
|
|
)
|
|
|
|
|
|
def symlink_or_skip(
|
|
target: Path, link: Path, *, directory: bool = False
|
|
) -> None:
|
|
try:
|
|
link.symlink_to(target, target_is_directory=directory)
|
|
except OSError as error:
|
|
pytest.skip(f"Symbolic links unavailable: {error}")
|
|
|
|
|
|
def test_install_rejects_linked_hook_file_before_runtime_creation(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
target = tmp_path / "hooks-target.json"
|
|
source = '{"owner":"protected"}\n'
|
|
write_text(target, source)
|
|
fixture.config_path.parent.mkdir(parents=True)
|
|
symlink_or_skip(target, fixture.config_path)
|
|
|
|
with pytest.raises(OSError, match="not a physical file"):
|
|
fixture.install()
|
|
|
|
assert target.read_text(encoding="utf-8") == source
|
|
assert not fixture.agent_dir.exists()
|
|
|
|
|
|
@pytest.mark.parametrize("kind", ["home", "hooks", "runtime"])
|
|
def test_install_rejects_linked_directories_before_writes(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
kind: str,
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
target = tmp_path / f"{kind}-target"
|
|
target.mkdir()
|
|
if kind == "home":
|
|
link = fixture.grok_home
|
|
(target / "hooks").mkdir()
|
|
elif kind == "hooks":
|
|
link = fixture.config_path.parent
|
|
fixture.grok_home.mkdir(parents=True)
|
|
else:
|
|
link = fixture.agent_dir.parent
|
|
link.parent.mkdir(parents=True, exist_ok=True)
|
|
symlink_or_skip(target, link, directory=True)
|
|
|
|
with pytest.raises(OSError, match="physical directory"):
|
|
fixture.install()
|
|
|
|
untouched = fixture.config_path if kind == "runtime" else fixture.agent_dir
|
|
assert not untouched.exists()
|
|
|
|
|
|
def test_status_rejects_linked_private_key(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
fixture.install()
|
|
target = tmp_path / "private-key-target"
|
|
source = fixture.private_key_path.read_text(encoding="utf-8")
|
|
write_text(target, source)
|
|
fixture.private_key_path.unlink()
|
|
symlink_or_skip(target, fixture.private_key_path)
|
|
|
|
with pytest.raises(OSError, match="not a physical file"):
|
|
fixture.plugin.status()
|
|
|
|
assert target.read_text(encoding="utf-8") == source
|
|
|
|
|
|
def test_preflight_inspects_every_runtime_artifact(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
fixture.agent_dir.mkdir(parents=True)
|
|
write_text(fixture.guard_path, "orphaned guard\n", 0o700)
|
|
target = tmp_path / "linked-audit-target"
|
|
write_text(target, "linked audit\n", 0o700)
|
|
symlink_or_skip(target, fixture.hook_path)
|
|
|
|
with pytest.raises(OSError, match="not a physical file"):
|
|
fixture.install()
|
|
|
|
assert target.read_text(encoding="utf-8") == "linked audit\n"
|
|
assert not fixture.config_path.exists()
|
|
|
|
|
|
@pytest.mark.parametrize("kind", ["orphaned", "mismatched"])
|
|
def test_install_rejects_unverifiable_runtime_identity(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
kind: str,
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
fixture.agent_dir.mkdir(parents=True)
|
|
if kind == "orphaned":
|
|
write_text(fixture.guard_path, "orphaned guard\n", 0o700)
|
|
else:
|
|
write_text(
|
|
fixture.runtime_config_path,
|
|
'{"agent_name":"grok","agent_id":"another-agent"}\n',
|
|
)
|
|
|
|
pattern = (
|
|
"identity cannot be verified"
|
|
if kind == "orphaned"
|
|
else "identity does not match"
|
|
)
|
|
with pytest.raises(ValueError, match=pattern):
|
|
fixture.install()
|
|
|
|
assert not fixture.config_path.exists()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("field", "value", "pattern"),
|
|
[
|
|
("agent_name", "codex", "requires agent_name grok"),
|
|
("agent_id", "../escape", "Invalid agent ID"),
|
|
("private_key", "invalid", "canonical 32-byte"),
|
|
("token", "", "non-empty string"),
|
|
(
|
|
"base_url",
|
|
"https://api.elydora.com/path?token=secret",
|
|
"query parameters",
|
|
),
|
|
("guard_script_path", "outside", "managed agent directory"),
|
|
],
|
|
)
|
|
def test_install_validates_runtime_inputs_before_creating_files(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
field: str,
|
|
value: str,
|
|
pattern: str,
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
fixture.config[field] = (
|
|
str(fixture.home_dir / "outside" / "guard.py")
|
|
if field == "guard_script_path"
|
|
else value
|
|
)
|
|
|
|
with pytest.raises(ValueError, match=pattern):
|
|
fixture.install()
|
|
|
|
assert not fixture.config_path.exists()
|
|
assert not fixture.agent_dir.exists()
|
|
|
|
|
|
def test_status_surfaces_malformed_runtime_metadata(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
fixture = prepare_fixture(monkeypatch, tmp_path)
|
|
fixture.install()
|
|
fixture.runtime_config_path.write_text("{ malformed", encoding="utf-8")
|
|
|
|
with pytest.raises(ValueError, match="parse Elydora runtime config"):
|
|
fixture.plugin.status()
|
|
|
|
|
|
def test_cli_preflight_preserves_malformed_config_before_runtime_creation(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
home_dir = tmp_path / "cli-home"
|
|
config_path = home_dir / ".grok" / "hooks" / "elydora-audit.json"
|
|
key_path = tmp_path / "private.key"
|
|
write_text(config_path, "{ malformed")
|
|
write_text(key_path, VALID_PRIVATE_KEY)
|
|
result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"-m",
|
|
"elydora.cli",
|
|
"install",
|
|
"--agent",
|
|
"grok",
|
|
"--org_id",
|
|
"org-1",
|
|
"--agent_id",
|
|
AGENT_ID,
|
|
"--private_key_file",
|
|
str(key_path),
|
|
"--kid",
|
|
"kid-1",
|
|
"--base_url",
|
|
"https://api.elydora.com",
|
|
],
|
|
capture_output=True,
|
|
check=False,
|
|
cwd=Path(__file__).parents[1],
|
|
env={
|
|
**os.environ,
|
|
"HOME": str(home_dir),
|
|
"USERPROFILE": str(home_dir),
|
|
"GROK_HOME": "",
|
|
},
|
|
text=True,
|
|
)
|
|
|
|
assert result.returncode == 1
|
|
assert "parse Grok user hooks" in result.stderr
|
|
assert config_path.read_text(encoding="utf-8") == "{ malformed"
|
|
assert not (home_dir / ".elydora").exists()
|