#!/usr/bin/env python3 """Forge smoke tests — fast checks that core imports resolve and entrypoints load. Total runtime target: < 30 seconds. """ from __future__ import annotations import importlib import subprocess import sys from pathlib import Path # Allow running smoke test directly from repo root before pip install REPO_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(REPO_ROOT)) CORE_MODULES = [ "hermes_cli.config", "hermes_state", "model_tools", "toolsets", "utils", ] CLI_ENTRYPOINTS = [ [sys.executable, "cli.py", "--help"], ] def test_imports() -> None: ok = 0 skipped = 0 for mod in CORE_MODULES: try: importlib.import_module(mod) ok += 1 except ImportError as exc: # If the failure is a missing third-party dependency, skip rather than fail # so the smoke test can run before `pip install` in bare environments. msg = str(exc).lower() if "no module named" in msg and mod.replace(".", "/") not in msg: print(f"SKIP: import {mod} -> missing dependency ({exc})") skipped += 1 else: print(f"FAIL: import {mod} -> {exc}") sys.exit(1) except Exception as exc: print(f"FAIL: import {mod} -> {exc}") sys.exit(1) print(f"OK: {ok} core imports", end="") if skipped: print(f" ({skipped} skipped due to missing deps)") else: print() def test_cli_help() -> None: ok = 0 skipped = 0 for cmd in CLI_ENTRYPOINTS: result = subprocess.run(cmd, capture_output=True, timeout=30) if result.returncode == 0: ok += 1 continue stderr = result.stderr.decode().lower() # Gracefully skip if dependencies are missing in bare environments if "modulenotfounderror" in stderr or "no module named" in stderr: print(f"SKIP: {' '.join(cmd)} -> missing dependency") skipped += 1 else: print(f"FAIL: {' '.join(cmd)} -> {result.stderr.decode()[:200]}") sys.exit(1) print(f"OK: {ok} CLI entrypoints", end="") if skipped: print(f" ({skipped} skipped due to missing deps)") else: print() def main() -> int: test_imports() test_cli_help() print("Smoke tests passed.") return 0 if __name__ == "__main__": raise SystemExit(main())