#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Compare the first Go detector port with the Python reference oracle.""" from __future__ import annotations import json import os import subprocess import sys from pathlib import Path from types import SimpleNamespace ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from enodia_sentinel import __version__, event # noqa: E402 from enodia_sentinel.config import Config # noqa: E402 from enodia_sentinel.detectors import deleted_exe # noqa: E402 from enodia_sentinel.system import SystemState # noqa: E402 HOST = "parity-host" TIMESTAMP = "2026-07-10T00:00:00-07:00" def main() -> int: fixture = ROOT / "tests/fixtures/go/deleted-exe.json" fixture_data = json.loads(fixture.read_text()) env = os.environ.copy() env.pop("ENODIA_CONFIG", None) env["GOCACHE"] = "/tmp/enodia-go-cache" command = [ "go", "run", "./cmd/enodia-sentinel-go", "--once", "--fixture", str(fixture), "--host", HOST, "--timestamp", TIMESTAMP, ] result = subprocess.run( command, cwd=ROOT / "go-agent", env=env, capture_output=True, text=True, timeout=60, ) if result.returncode: print(result.stderr, file=sys.stderr, end="") return result.returncode go_events = [json.loads(line) for line in result.stdout.splitlines() if line] go_alerts = [record for record in go_events if record["event_type"] == "alert"] processes = [SimpleNamespace(**item) for item in fixture_data["processes"]] cfg = Config() cfg.detectors = frozenset({"deleted_exe"}) state = SystemState(processes=processes, sockets=[]) python_alerts = [ event.from_alert(alert, host=HOST, timestamp=TIMESTAMP) for alert in deleted_exe.detect(state, cfg) ] if go_alerts != python_alerts: print("Go/Python alert parity mismatch", file=sys.stderr) print(json.dumps({"go": go_alerts, "python": python_alerts}, indent=2), file=sys.stderr) return 1 status_events = [record for record in go_events if record["event_type"] == "status"] if len(status_events) != 1 or status_events[0].get("schema") != "enodia.event.v1": print("Go sidecar did not emit one enodia.event.v1 status record", file=sys.stderr) return 1 status = status_events[0].get("status", {}) if status.get("schema") != "enodia.status.v1" or status.get("version") != __version__: print("Go status schema/version drifted from Python", file=sys.stderr) return 1 print(f"parity ok: {len(go_alerts)} deleted_exe alert events") return 0 if __name__ == "__main__": raise SystemExit(main())