import subprocess import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[2] CHECKER = ROOT / "scripts" / "check-metrics-boundaries.py" class MetricsBoundaryTests(unittest.TestCase): def run_checker(self, root: Path, *paths: str) -> subprocess.CompletedProcess[str]: return subprocess.run( ["python3", str(CHECKER), "--root", str(root), "--files", *paths], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, ) def test_rejects_direct_alias_import_reexport_and_wrapper_bypasses(self) -> None: cases = { "direct.rs": 'metrics::counter!("bad").increment(1);', "alias.rs": 'use metrics as m; m::counter!("bad").increment(1);', "import.rs": 'use metrics::counter; counter!("bad").increment(1);', "reexport.rs": 'pub use metrics::histogram;', "absolute.rs": '::metrics::gauge!("bad").set(1.0);', "wrapper.rs": 'macro_rules! bad { () => { metrics::counter!("bad") } }', } with tempfile.TemporaryDirectory() as directory: root = Path(directory) paths = [] for name, content in cases.items(): path = root / "apps" / "demo" / "src" / name path.parent.mkdir(parents=True, exist_ok=True) path.write_text(content, encoding="utf-8") paths.append(str(path.relative_to(root))) result = self.run_checker(root, *paths) self.assertNotEqual(result.returncode, 0) for name in cases: self.assertIn(name, result.stderr) self.assertNotIn(str(root), result.stderr) def test_allows_typed_facade_and_narrow_observability_adapter(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) product = root / "apps" / "demo" / "src" / "main.rs" adapter = root / "crates" / "crank-observability" / "src" / "instrumentation.rs" product.parent.mkdir(parents=True) adapter.parent.mkdir(parents=True) product.write_text("crank_metrics::record_cache_outcome(value);", encoding="utf-8") adapter.write_text("metrics::describe_counter!(definition.name, definition.description);", encoding="utf-8") result = self.run_checker(root, str(product.relative_to(root)), str(adapter.relative_to(root))) self.assertEqual(result.returncode, 0, result.stderr) def test_explicit_missing_traversal_and_symlink_fail_closed(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) outside = root.parent / "metrics-boundary-outside.rs" outside.write_text('metrics::counter!("bad");', encoding="utf-8") try: for path in ["missing.rs", "../metrics-boundary-outside.rs"]: result = self.run_checker(root, path) self.assertNotEqual(result.returncode, 0) target = root / "target.rs" target.write_text("", encoding="utf-8") link = root / "link.rs" link.symlink_to(target) result = self.run_checker(root, "link.rs") self.assertNotEqual(result.returncode, 0) finally: outside.unlink(missing_ok=True) if __name__ == "__main__": unittest.main()