"""Tests for fleet_audit — Deduplicate Agents, One Identity Per Machine.""" import json import tempfile from pathlib import Path import pytest import yaml # Adjust import path import sys sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "bin")) from fleet_audit import ( AuditFinding, validate_registry, cross_reference_registry_agents, audit_git_authors, ) # --------------------------------------------------------------------------- # Identity registry validation tests # --------------------------------------------------------------------------- class TestValidateRegistry: """Test identity registry validation rules.""" def _make_registry(self, agents): return {"version": 1, "agents": agents, "rules": {"one_identity_per_machine": True}} def test_clean_registry_passes(self): registry = self._make_registry([ {"name": "allegro", "machine": "167.99.126.228", "role": "burn", "gitea_user": "allegro"}, {"name": "ezra", "machine": "143.198.27.163", "role": "triage", "gitea_user": "ezra"}, ]) findings = validate_registry(registry) critical = [f for f in findings if f.severity == "critical"] assert len(critical) == 0 def test_same_name_on_different_machines_detected(self): registry = self._make_registry([ {"name": "allegro", "machine": "167.99.126.228", "role": "burn"}, {"name": "allegro", "machine": "104.131.15.18", "role": "burn"}, ]) findings = validate_registry(registry) critical = [f for f in findings if f.severity == "critical" and f.category == "duplicate"] # Two findings: one for name-on-multiple-machines, one for duplicate name assert len(critical) >= 1 machine_findings = [f for f in critical if "registered on" in f.description] assert len(machine_findings) == 1 assert "167.99.126.228" in machine_findings[0].description assert "104.131.15.18" in machine_findings[0].description def test_multiple_agents_same_machine_ok(self): # Multiple different agents on the same VPS is normal. registry = self._make_registry([ {"name": "allegro", "machine": "167.99.126.228", "role": "burn"}, {"name": "bilbo", "machine": "167.99.126.228", "role": "queries"}, ]) findings = validate_registry(registry) critical = [f for f in findings if f.severity == "critical"] assert len(critical) == 0 def test_duplicate_name_detected(self): registry = self._make_registry([ {"name": "bezalel", "machine": "104.131.15.18", "role": "ci"}, {"name": "bezalel", "machine": "167.99.126.228", "role": "ci"}, ]) findings = validate_registry(registry) name_dupes = [f for f in findings if f.severity == "critical" and "bezalel" in f.description.lower() and "registered on" in f.description.lower()] assert len(name_dupes) == 1 def test_duplicate_gitea_user_detected(self): registry = self._make_registry([ {"name": "agent-a", "machine": "host1", "role": "x", "gitea_user": "shared"}, {"name": "agent-b", "machine": "host2", "role": "x", "gitea_user": "shared"}, ]) findings = validate_registry(registry) gitea_dupes = [f for f in findings if "Gitea user 'shared'" in f.description] assert len(gitea_dupes) == 1 assert "agent-a" in gitea_dupes[0].affected assert "agent-b" in gitea_dupes[0].affected def test_missing_required_fields(self): registry = self._make_registry([ {"name": "incomplete-agent"}, ]) findings = validate_registry(registry) missing = [f for f in findings if f.category == "orphan"] assert len(missing) >= 1 assert "machine" in missing[0].description or "role" in missing[0].description def test_empty_registry_passes(self): registry = self._make_registry([]) findings = validate_registry(registry) assert len(findings) == 0 # --------------------------------------------------------------------------- # Cross-reference tests # --------------------------------------------------------------------------- class TestCrossReference: """Test registry vs fleet-routing.json cross-reference.""" def test_orphan_in_fleet_not_registry(self): reg_agents = [{"name": "allegro", "machine": "x", "role": "y"}] fleet_agents = [{"name": "allegro", "location": "x"}, {"name": "unknown-agent", "location": "y"}] findings = cross_reference_registry_agents(reg_agents, fleet_agents) orphans = [f for f in findings if f.category == "orphan" and "unknown-agent" in f.description] assert len(orphans) == 1 def test_location_mismatch_detected(self): reg_agents = [{"name": "allegro", "machine": "167.99.126.228", "role": "y"}] fleet_agents = [{"name": "allegro", "location": "totally-different-host"}] findings = cross_reference_registry_agents(reg_agents, fleet_agents) mismatches = [f for f in findings if f.category == "duplicate" and "different locations" in f.description] assert len(mismatches) == 1 # --------------------------------------------------------------------------- # Integration test against actual registry # --------------------------------------------------------------------------- class TestRealRegistry: """Test against the actual identity-registry.yaml in the repo.""" def test_registry_loads(self): reg_path = Path(__file__).resolve().parent.parent / "fleet" / "identity-registry.yaml" if reg_path.exists(): with open(reg_path) as f: registry = yaml.safe_load(f) assert registry["version"] == 1 assert len(registry["agents"]) > 0 def test_registry_no_critical_findings(self): reg_path = Path(__file__).resolve().parent.parent / "fleet" / "identity-registry.yaml" if reg_path.exists(): with open(reg_path) as f: registry = yaml.safe_load(f) findings = validate_registry(registry) critical = [f for f in findings if f.severity == "critical"] assert len(critical) == 0, f"Critical findings: {[f.description for f in critical]}"