Files
SDR-Rover/tests/test_rf001_bootstrap_install_orchestrator.py
2026-09-30 11:42:19 +03:00

134 lines
4.5 KiB
Python

"""Software-only regressions for external bootstrap install evidence."""
from __future__ import annotations
import hashlib
import hmac
import json
from pathlib import Path
import sys
import pytest
from tools.rf001_bootstrap_install_orchestrator import (
EvidencePathError,
PackageValidationError,
SIGNATURE_DOMAIN,
run_installer,
snapshot_tree,
validate_pristine_package,
)
def _sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def _signed_package(tmp_path: Path) -> tuple[Path, Path]:
package = tmp_path / "clean-bootstrap"
package.mkdir()
(package / "INSTALL_RX_AGENT.cmd").write_text("@echo off\n", encoding="utf-8")
payload = package / "payload.bin"
payload.write_bytes(b"fixed bootstrap payload")
rows = []
for path in sorted(item for item in package.rglob("*") if item.is_file()):
rows.append(
{
"path": path.relative_to(package).as_posix(),
"bytes": path.stat().st_size,
"sha256": _sha256(path),
}
)
manifest = {
"schema_version": 1,
"package_kind": "BOOTSTRAP",
"bootstrap_id": "rf001-bootstrap-2099.01.01.1",
"agent_release_id": "rf001-agent-2099.01.01.1",
"agent_version": "2099.01.01.1",
"files": rows,
}
manifest_bytes = (
json.dumps(manifest, sort_keys=True, separators=(",", ":")) + "\n"
).encode("utf-8")
(package / "BOOTSTRAP_MANIFEST.json").write_bytes(manifest_bytes)
token = tmp_path / "token.txt"
token.write_text("fixed-test-token-0123456789abcdef", encoding="utf-8")
signature = hmac.new(
token.read_text(encoding="utf-8").encode("utf-8"),
SIGNATURE_DOMAIN + manifest_bytes,
hashlib.sha256,
).hexdigest()
(package / "BOOTSTRAP_MANIFEST.hmac").write_text(
signature + "\n",
encoding="ascii",
)
return package, token
def test_pristine_package_uses_external_logs_and_remains_unchanged(
tmp_path: Path,
) -> None:
package, token = _signed_package(tmp_path)
evidence = tmp_path / "external-evidence"
before = snapshot_tree(package)
command = [
sys.executable,
"-c",
"import sys; print('installer stdout'); print('installer stderr', file=sys.stderr)",
]
result = run_installer(package, evidence, token, command=command)
assert result["exit_code"] == 0
assert result["package_content_unchanged_immediate"] is True
assert result["package_content_unchanged_after"] is True
assert result["package_metadata_unchanged_after"] is True
assert snapshot_tree(package) == before
assert (evidence / "install.stdout.txt").read_text().strip() == "installer stdout"
assert (evidence / "install.stderr.txt").read_text().strip() == "installer stderr"
assert not (package / "install.stdout.txt").exists()
assert not (package / "install.stderr.txt").exists()
preflight = json.loads((evidence / "package_preflight.json").read_text())
assert preflight["hmac"] == "PASS"
assert preflight["unexpected"] == 0
assert preflight["missing"] == 0
def test_contaminated_package_fails_closed_before_command(tmp_path: Path) -> None:
package, token = _signed_package(tmp_path)
(package / "install.stdout.txt").write_text("orchestration leak\n", encoding="utf-8")
evidence = tmp_path / "external-evidence"
command_marker = tmp_path / "command-ran.txt"
command = [
sys.executable,
"-c",
f"from pathlib import Path; Path({str(command_marker)!r}).write_text('ran')",
]
with pytest.raises(PackageValidationError, match="allowlist mismatch"):
run_installer(package, evidence, token, command=command)
assert not command_marker.exists()
assert not (evidence / "install.stdout.txt").exists()
assert not (evidence / "install.stderr.txt").exists()
def test_evidence_directory_inside_package_is_rejected(tmp_path: Path) -> None:
package, token = _signed_package(tmp_path)
evidence = package / "runtime-evidence"
with pytest.raises(EvidencePathError, match="outside the package"):
run_installer(package, evidence, token, command=[sys.executable, "-c", "pass"])
def test_pristine_validation_reports_exact_allowlist(tmp_path: Path) -> None:
package, token = _signed_package(tmp_path)
result = validate_pristine_package(package, token)
assert result["hmac"] == "PASS"
assert result["manifest_file_count"] == 2
assert result["package_file_count"] == 4
assert result["unexpected"] == 0
assert result["missing"] == 0