259 lines
9.6 KiB
Python
259 lines
9.6 KiB
Python
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from ops.capture_vps_canonical_postgres_snapshot import (
|
|
SOURCE_SNAPSHOT_RECEIPT_SCHEMA,
|
|
build_provenance_binding,
|
|
)
|
|
from ops.verify_vps_canonical_snapshot_delta import verify_delta, write_private_json
|
|
|
|
|
|
def manifest_text(*, claims: int = 1, constraint_name: str = "claims_pkey") -> str:
|
|
rows = [
|
|
{
|
|
"kind": "identity",
|
|
"database": "teleo",
|
|
"server_version_num": 160014,
|
|
"transaction_read_only": "on",
|
|
},
|
|
{"kind": "schemas", "items": ["kb_stage", "public"]},
|
|
{"kind": "extensions", "items": [{"name": "pgcrypto", "version": "1.3"}]},
|
|
{"kind": "application_roles", "items": [{"name": "kb_apply", "can_login": True}]},
|
|
{"kind": "columns", "items": []},
|
|
{"kind": "constraints", "items": [{"name": constraint_name}]},
|
|
{"kind": "indexes", "items": []},
|
|
{"kind": "sequences", "items": []},
|
|
{"kind": "views", "items": []},
|
|
{"kind": "functions", "items": []},
|
|
{"kind": "triggers", "items": []},
|
|
{"kind": "types", "items": []},
|
|
{"kind": "policies", "items": []},
|
|
{
|
|
"kind": "table",
|
|
"schema": "public",
|
|
"table": "claims",
|
|
"row_count": claims,
|
|
"rowset_md5": hashlib.md5(str(claims).encode(), usedforsecurity=False).hexdigest(),
|
|
},
|
|
{"kind": "performance", "query": "count_claims", "elapsed_ms": 1.0, "observed_rows": claims},
|
|
]
|
|
return "".join(json.dumps(row, sort_keys=True) + "\n" for row in rows)
|
|
|
|
|
|
def capture_fixture(
|
|
root: Path,
|
|
*,
|
|
name: str,
|
|
captured_at: str,
|
|
authorization_ref: str,
|
|
claims: int = 1,
|
|
constraint_name: str = "claims_pkey",
|
|
) -> tuple[Path, Path]:
|
|
manifest = root / f"{name}-manifest.jsonl"
|
|
manifest.write_text(manifest_text(claims=claims, constraint_name=constraint_name), encoding="utf-8")
|
|
dump_sha256 = hashlib.sha256(f"{name}-dump".encode()).hexdigest()
|
|
manifest_sha256 = hashlib.sha256(manifest.read_bytes()).hexdigest()
|
|
manifest_sql_sha256 = "2" * 64
|
|
source_context_sha256 = "3" * 64
|
|
source = {
|
|
"ssh_target": "root@77.42.65.182",
|
|
"container": "teleo-pg",
|
|
"database": "teleo",
|
|
"service": "leoclean-gateway.service",
|
|
}
|
|
healthy_service = {
|
|
"ActiveState": "active",
|
|
"SubState": "running",
|
|
"MainPID": "148735",
|
|
"NRestarts": "0",
|
|
}
|
|
snapshot = {
|
|
"exported_snapshot_id": "00000003-000001A2-1",
|
|
"txid_snapshot": "100:120:105,111",
|
|
"wal_lsn": "0/16B6C50",
|
|
"system_identifier": "7649789040005668902",
|
|
"captured_at_utc": captured_at,
|
|
}
|
|
receipt = {
|
|
"artifact": "vps_canonical_postgres_exported_snapshot",
|
|
"schema": SOURCE_SNAPSHOT_RECEIPT_SCHEMA,
|
|
"receipt_version": 2,
|
|
"status": "pass",
|
|
"run_id": name,
|
|
"capture_authorization_ref": authorization_ref,
|
|
"source": source,
|
|
"snapshot_exported": True,
|
|
"snapshot": snapshot,
|
|
"dump": {"sha256": dump_sha256},
|
|
"manifest": {
|
|
"sha256": manifest_sha256,
|
|
"manifest_sql_sha256": manifest_sql_sha256,
|
|
"table_count": 1,
|
|
"total_rows": claims,
|
|
},
|
|
"source_context": {"sha256": source_context_sha256},
|
|
"provenance_binding": build_provenance_binding(
|
|
run_id=name,
|
|
authorization_ref=authorization_ref,
|
|
source=source,
|
|
snapshot=snapshot,
|
|
dump_sha256=dump_sha256,
|
|
manifest_sql_sha256=manifest_sql_sha256,
|
|
source_manifest_sha256=manifest_sha256,
|
|
source_context_sha256=source_context_sha256,
|
|
),
|
|
"service_unchanged": True,
|
|
"source_service": {"before": healthy_service, "after": healthy_service, "unchanged": True},
|
|
"production_db_mutated": False,
|
|
"telegram_send_attempted": False,
|
|
}
|
|
receipt_path = root / f"{name}-receipt.json"
|
|
receipt_path.write_text(json.dumps(receipt, sort_keys=True) + "\n", encoding="utf-8")
|
|
return receipt_path, manifest
|
|
|
|
|
|
def test_postflight_no_delta_is_bound_and_explicit(tmp_path: Path) -> None:
|
|
baseline_receipt, baseline_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-baseline",
|
|
captured_at="2026-07-15T01:00:00+00:00",
|
|
authorization_ref="codex-delegation:baseline123",
|
|
)
|
|
current_receipt, current_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-postflight",
|
|
captured_at="2026-07-15T02:00:00+00:00",
|
|
authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
result = verify_delta(
|
|
baseline_receipt_path=baseline_receipt,
|
|
baseline_manifest_path=baseline_manifest,
|
|
baseline_authorization_ref="codex-delegation:baseline123",
|
|
current_receipt_path=current_receipt,
|
|
current_manifest_path=current_manifest,
|
|
current_authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
assert result["status"] == "pass"
|
|
assert result["delta"]["delta_detected"] is False
|
|
assert result["delta"]["total_row_delta"] == 0
|
|
|
|
|
|
def test_postflight_data_and_structure_delta_is_reported_not_hidden(tmp_path: Path) -> None:
|
|
baseline_receipt, baseline_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-baseline",
|
|
captured_at="2026-07-15T01:00:00+00:00",
|
|
authorization_ref="codex-delegation:baseline123",
|
|
)
|
|
current_receipt, current_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-postflight",
|
|
captured_at="2026-07-15T02:00:00+00:00",
|
|
authorization_ref="codex-delegation:postflight123",
|
|
claims=2,
|
|
constraint_name="claims_pkey_v2",
|
|
)
|
|
|
|
result = verify_delta(
|
|
baseline_receipt_path=baseline_receipt,
|
|
baseline_manifest_path=baseline_manifest,
|
|
baseline_authorization_ref="codex-delegation:baseline123",
|
|
current_receipt_path=current_receipt,
|
|
current_manifest_path=current_manifest,
|
|
current_authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
assert result["status"] == "pass"
|
|
assert result["delta"]["delta_detected"] is True
|
|
assert result["delta"]["total_row_delta"] == 1
|
|
assert result["delta"]["changed_tables"][0]["table"] == "public.claims"
|
|
assert result["delta"]["changed_structures"][0]["kind"] == "constraints"
|
|
|
|
|
|
def test_postflight_rejects_wrong_authorization_or_stale_capture(tmp_path: Path) -> None:
|
|
baseline_receipt, baseline_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-baseline",
|
|
captured_at="2026-07-15T02:00:00+00:00",
|
|
authorization_ref="codex-delegation:baseline123",
|
|
)
|
|
current_receipt, current_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-postflight",
|
|
captured_at="2026-07-15T01:00:00+00:00",
|
|
authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="newer than"):
|
|
verify_delta(
|
|
baseline_receipt_path=baseline_receipt,
|
|
baseline_manifest_path=baseline_manifest,
|
|
baseline_authorization_ref="codex-delegation:baseline123",
|
|
current_receipt_path=current_receipt,
|
|
current_manifest_path=current_manifest,
|
|
current_authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="authorization"):
|
|
verify_delta(
|
|
baseline_receipt_path=baseline_receipt,
|
|
baseline_manifest_path=baseline_manifest,
|
|
baseline_authorization_ref="codex-delegation:wrong123",
|
|
current_receipt_path=current_receipt,
|
|
current_manifest_path=current_manifest,
|
|
current_authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
|
|
def test_postflight_rejects_unchanged_but_unhealthy_service(tmp_path: Path) -> None:
|
|
baseline_receipt, baseline_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-baseline",
|
|
captured_at="2026-07-15T01:00:00+00:00",
|
|
authorization_ref="codex-delegation:baseline123",
|
|
)
|
|
current_receipt, current_manifest = capture_fixture(
|
|
tmp_path,
|
|
name="canonical-postflight",
|
|
captured_at="2026-07-15T02:00:00+00:00",
|
|
authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
current = json.loads(current_receipt.read_text())
|
|
current["source_service"]["before"]["ActiveState"] = "failed"
|
|
current["source_service"]["after"]["ActiveState"] = "failed"
|
|
current_receipt.write_text(json.dumps(current, sort_keys=True) + "\n", encoding="utf-8")
|
|
|
|
with pytest.raises(ValueError, match="source_service_healthy"):
|
|
verify_delta(
|
|
baseline_receipt_path=baseline_receipt,
|
|
baseline_manifest_path=baseline_manifest,
|
|
baseline_authorization_ref="codex-delegation:baseline123",
|
|
current_receipt_path=current_receipt,
|
|
current_manifest_path=current_manifest,
|
|
current_authorization_ref="codex-delegation:postflight123",
|
|
)
|
|
|
|
|
|
def test_delta_receipt_writer_keeps_private_mode(tmp_path: Path) -> None:
|
|
output = tmp_path / "private" / "delta.json"
|
|
|
|
write_private_json(output, {"status": "pass"})
|
|
|
|
assert output.stat().st_mode & 0o777 == 0o600
|
|
assert output.parent.stat().st_mode & 0o777 == 0o700
|
|
|
|
|
|
def test_delta_receipt_writer_does_not_chmod_an_existing_parent(tmp_path: Path) -> None:
|
|
parent = tmp_path / "existing"
|
|
parent.mkdir(mode=0o755)
|
|
output = parent / "delta.json"
|
|
|
|
write_private_json(output, {"status": "pass"})
|
|
|
|
assert parent.stat().st_mode & 0o777 == 0o755
|
|
assert output.stat().st_mode & 0o777 == 0o600
|