Add CLI subcommands and doctor diagnostics
This commit is contained in:
parent
9c7d7b35b1
commit
ad1af63fac
7 changed files with 385 additions and 13 deletions
58
tests/test_aman_cli.py
Normal file
58
tests/test_aman_cli.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import io
|
||||
import json
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SRC = ROOT / "src"
|
||||
if str(SRC) not in sys.path:
|
||||
sys.path.insert(0, str(SRC))
|
||||
|
||||
import aman
|
||||
from diagnostics import DiagnosticCheck, DiagnosticReport
|
||||
|
||||
|
||||
class AmanCliTests(unittest.TestCase):
|
||||
def test_parse_cli_args_defaults_to_run_command(self):
|
||||
args = aman._parse_cli_args(["--dry-run"])
|
||||
|
||||
self.assertEqual(args.command, "run")
|
||||
self.assertTrue(args.dry_run)
|
||||
|
||||
def test_parse_cli_args_doctor_command(self):
|
||||
args = aman._parse_cli_args(["doctor", "--json"])
|
||||
|
||||
self.assertEqual(args.command, "doctor")
|
||||
self.assertTrue(args.json)
|
||||
|
||||
def test_doctor_command_json_output_and_exit_code(self):
|
||||
report = DiagnosticReport(
|
||||
checks=[DiagnosticCheck(id="config.load", ok=True, message="ok", hint="")]
|
||||
)
|
||||
args = aman._parse_cli_args(["doctor", "--json"])
|
||||
out = io.StringIO()
|
||||
with patch("aman.run_diagnostics", return_value=report), patch("sys.stdout", out):
|
||||
exit_code = aman._doctor_command(args)
|
||||
|
||||
self.assertEqual(exit_code, 0)
|
||||
payload = json.loads(out.getvalue())
|
||||
self.assertTrue(payload["ok"])
|
||||
self.assertEqual(payload["checks"][0]["id"], "config.load")
|
||||
|
||||
def test_doctor_command_failed_report_returns_exit_code_2(self):
|
||||
report = DiagnosticReport(
|
||||
checks=[DiagnosticCheck(id="config.load", ok=False, message="broken", hint="fix")]
|
||||
)
|
||||
args = aman._parse_cli_args(["doctor"])
|
||||
out = io.StringIO()
|
||||
with patch("aman.run_diagnostics", return_value=report), patch("sys.stdout", out):
|
||||
exit_code = aman._doctor_command(args)
|
||||
|
||||
self.assertEqual(exit_code, 2)
|
||||
self.assertIn("[FAIL] config.load", out.getvalue())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
69
tests/test_diagnostics.py
Normal file
69
tests/test_diagnostics.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import json
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SRC = ROOT / "src"
|
||||
if str(SRC) not in sys.path:
|
||||
sys.path.insert(0, str(SRC))
|
||||
|
||||
from config import Config
|
||||
from diagnostics import DiagnosticCheck, DiagnosticReport, run_diagnostics
|
||||
|
||||
|
||||
class _FakeDesktop:
|
||||
def validate_hotkey(self, _hotkey: str) -> None:
|
||||
return
|
||||
|
||||
|
||||
class DiagnosticsTests(unittest.TestCase):
|
||||
def test_run_diagnostics_all_checks_pass(self):
|
||||
cfg = Config()
|
||||
with patch("diagnostics.load", return_value=cfg), patch(
|
||||
"diagnostics.resolve_input_device", return_value=1
|
||||
), patch("diagnostics.get_desktop_adapter", return_value=_FakeDesktop()), patch(
|
||||
"diagnostics.ensure_model", return_value=Path("/tmp/model.gguf")
|
||||
):
|
||||
report = run_diagnostics("/tmp/config.json")
|
||||
|
||||
self.assertTrue(report.ok)
|
||||
ids = [check.id for check in report.checks]
|
||||
self.assertEqual(
|
||||
ids,
|
||||
["config.load", "audio.input", "hotkey.parse", "injection.backend", "model.cache"],
|
||||
)
|
||||
self.assertTrue(all(check.ok for check in report.checks))
|
||||
|
||||
def test_run_diagnostics_marks_config_fail_and_skips_dependent_checks(self):
|
||||
with patch("diagnostics.load", side_effect=ValueError("broken config")), patch(
|
||||
"diagnostics.ensure_model", return_value=Path("/tmp/model.gguf")
|
||||
):
|
||||
report = run_diagnostics("/tmp/config.json")
|
||||
|
||||
self.assertFalse(report.ok)
|
||||
results = {check.id: check for check in report.checks}
|
||||
self.assertFalse(results["config.load"].ok)
|
||||
self.assertFalse(results["audio.input"].ok)
|
||||
self.assertFalse(results["hotkey.parse"].ok)
|
||||
self.assertFalse(results["injection.backend"].ok)
|
||||
self.assertTrue(results["model.cache"].ok)
|
||||
|
||||
def test_report_json_schema(self):
|
||||
report = DiagnosticReport(
|
||||
checks=[
|
||||
DiagnosticCheck(id="config.load", ok=True, message="ok", hint=""),
|
||||
DiagnosticCheck(id="model.cache", ok=False, message="nope", hint="fix"),
|
||||
]
|
||||
)
|
||||
|
||||
payload = json.loads(report.to_json())
|
||||
|
||||
self.assertFalse(payload["ok"])
|
||||
self.assertEqual(payload["checks"][0]["id"], "config.load")
|
||||
self.assertEqual(payload["checks"][1]["hint"], "fix")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue