from pathlib import Path import subprocess import sys import tempfile import unittest ROOT = Path(__file__).parents[2] CHECKER = ROOT / "scripts" / "verify_observability_manifests.py" class ObservabilityManifestTest(unittest.TestCase): def run_checker(self, directory=None): command = [sys.executable, str(CHECKER)] if directory is not None: command += ["--directory", str(directory)] return subprocess.run(command, cwd=ROOT, text=True, capture_output=True) def test_checked_in_resources_match_service_and_metric_contract(self): result = self.run_checker() self.assertEqual(result.returncode, 0, result.stderr) # Every file the checker opens, in the order it opens them. Copying only a # subset makes it die on a missing file before it reaches the assertion # under test, so the mutation is never actually exercised. FIXTURE = ( "kustomization.yaml", "prometheus-service-monitor.yaml", "prometheus-allocator-service-monitor.yaml", "prometheus-rules.yaml", ) def build_fixture(self, target, mutate=None): for name in self.FIXTURE: text = (ROOT / "deploy/observability" / name).read_text() if mutate is not None and name == "prometheus-service-monitor.yaml": text = mutate(text) (target / name).write_text(text) def test_unmutated_fixture_copy_passes(self): # Guards the two mutation tests below: if this fails, their non-zero # exit proves nothing, because the fixture itself is broken. with tempfile.TemporaryDirectory() as directory: target = Path(directory) self.build_fixture(target) result = self.run_checker(target) self.assertEqual(result.returncode, 0, result.stderr) def test_checker_rejects_wrong_namespace(self): with tempfile.TemporaryDirectory() as directory: target = Path(directory) # Widen the namespaceSelector only; metadata.namespace stays put so # this isolates the scrape-scope check from the placement check. self.build_fixture(target, lambda text: text.replace(" - cosmic-clash", " - default")) result = self.run_checker(target) self.assertNotEqual(result.returncode, 0) self.assertIn("namespace", result.stderr) def test_checker_rejects_broad_scrape_path(self): with tempfile.TemporaryDirectory() as directory: target = Path(directory) self.build_fixture(target, lambda text: text.replace(" path: /metrics", " path: /")) result = self.run_checker(target) self.assertNotEqual(result.returncode, 0) self.assertIn("path", result.stderr) if __name__ == "__main__": unittest.main()