"""Tests for scripts/self_healing.py safe CLI behavior.""" from __future__ import annotations import importlib.util import subprocess from pathlib import Path from unittest.mock import MagicMock import pytest REPO_ROOT = Path(__file__).parent.parent spec = importlib.util.spec_from_file_location("self_healing", REPO_ROOT / "scripts" / "self_healing.py") sh = importlib.util.module_from_spec(spec) spec.loader.exec_module(sh) class TestMainCli: def test_help_exits_without_running_healer(self, monkeypatch, capsys): healer_cls = MagicMock() monkeypatch.setattr(sh, "SelfHealer", healer_cls) with pytest.raises(SystemExit) as excinfo: sh.main(["--help"]) assert excinfo.value.code == 0 healer_cls.assert_not_called() out = capsys.readouterr().out assert "--execute" in out assert "--help-safe" in out def test_help_safe_exits_without_running_healer(self, monkeypatch, capsys): healer_cls = MagicMock() monkeypatch.setattr(sh, "SelfHealer", healer_cls) with pytest.raises(SystemExit) as excinfo: sh.main(["--help-safe"]) assert excinfo.value.code == 0 healer_cls.assert_not_called() out = capsys.readouterr().out assert "DRY-RUN" in out assert "--confirm-kill" in out def test_default_invocation_runs_in_dry_run_mode(self, monkeypatch): healer = MagicMock() healer_cls = MagicMock(return_value=healer) monkeypatch.setattr(sh, "SelfHealer", healer_cls) sh.main([]) healer_cls.assert_called_once_with(dry_run=True, confirm_kill=False, yes=False) healer.run.assert_called_once_with() def test_execute_flag_disables_dry_run(self, monkeypatch): healer = MagicMock() healer_cls = MagicMock(return_value=healer) monkeypatch.setattr(sh, "SelfHealer", healer_cls) sh.main(["--execute", "--yes", "--confirm-kill"]) healer_cls.assert_called_once_with(dry_run=False, confirm_kill=True, yes=True) healer.run.assert_called_once_with() def test_real_default_dry_run_path_completes(self, monkeypatch, capsys): class FakeExecutor: def __init__(self): self.calls = [] def run_script(self, host, command, *, local=False, timeout=None): self.calls.append((host, command, local, timeout)) if command.startswith("df -h /"): return subprocess.CompletedProcess(command, 0, stdout="42\n", stderr="") if command.startswith("free -m"): return subprocess.CompletedProcess(command, 0, stdout="12.5\n", stderr="") if command.startswith("ps aux"): return subprocess.CompletedProcess(command, 0, stdout="", stderr="") raise AssertionError(f"unexpected command: {command}") fake_executor = FakeExecutor() monkeypatch.setattr(sh, "FLEET", {"mac": {"ip": "127.0.0.1", "port": 8080}}) monkeypatch.setattr(sh.requests, "get", lambda url, timeout: object()) monkeypatch.setattr(sh, "VerifiedSSHExecutor", lambda: fake_executor) sh.main([]) out = capsys.readouterr().out assert "Starting self-healing cycle (DRY-RUN mode)." in out assert "Auditing mac..." in out assert "Cycle complete." in out assert fake_executor.calls == [ ("127.0.0.1", "df -h / | tail -1 | awk '{print $5}' | sed 's/%//'", True, 15), ("127.0.0.1", "free -m | awk '/^Mem:/{print $3/$2 * 100}'", True, 15), ("127.0.0.1", "ps aux --sort=-%cpu | awk 'NR>1 && $3>80 {print $2, $11, $3}'", True, 15), ]