@@ -691,3 +691,117 @@ def test_absent_files_yield_not_yet_run(
691691 assert "probe=not-yet-run" in result .message
692692 assert "matrix=not-yet-run" in result .message
693693 assert "smoke=not-found" in result .message
694+
695+
696+ class TestCheckCliConformanceProbes :
697+ """Tests for _check_cli_conformance_probes doctor check (Check 34)."""
698+
699+ def test_skip_for_none_backend (self ) -> None :
700+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
701+ from autoskillit .core import Severity
702+
703+ result = _check_cli_conformance_probes (backend = None )
704+ assert result .severity == Severity .OK
705+ assert result .check == "cli_conformance_probes"
706+ assert "skipped" in result .message .lower ()
707+
708+ def test_skip_for_backend_without_version_check_command (self ) -> None :
709+ from types import SimpleNamespace
710+
711+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
712+ from autoskillit .core import Severity
713+
714+ stub = SimpleNamespace (capabilities = SimpleNamespace (version_check_command = "" ))
715+ result = _check_cli_conformance_probes (backend = stub )
716+ assert result .severity == Severity .OK
717+ assert "skipped" in result .message .lower ()
718+
719+ def test_skip_when_cli_unavailable (self , monkeypatch : pytest .MonkeyPatch ) -> None :
720+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
721+ from autoskillit .core import Severity
722+ from autoskillit .execution .backends .codex import CodexBackend
723+
724+ def _raise (* a , ** kw ):
725+ raise FileNotFoundError ("codex" )
726+
727+ monkeypatch .setattr ("autoskillit.cli.doctor._doctor_runtime.subprocess.run" , _raise )
728+ result = _check_cli_conformance_probes (backend = CodexBackend ())
729+ assert result .severity == Severity .OK
730+ assert "unavailable" in result .message .lower ()
731+
732+ def test_skip_when_cli_times_out (self , monkeypatch : pytest .MonkeyPatch ) -> None :
733+ import subprocess
734+
735+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
736+ from autoskillit .core import Severity
737+ from autoskillit .execution .backends .codex import CodexBackend
738+
739+ call_count = 0
740+
741+ def _stateful_fake (* a , ** kw ):
742+ nonlocal call_count
743+ call_count += 1
744+ if call_count == 1 :
745+ return type (
746+ "CompletedProcess" , (), {"returncode" : 0 , "stdout" : "" , "stderr" : "" }
747+ )()
748+ raise subprocess .TimeoutExpired (cmd = "codex" , timeout = 10 )
749+
750+ monkeypatch .setattr (
751+ "autoskillit.cli.doctor._doctor_runtime.subprocess.run" , _stateful_fake
752+ )
753+ result = _check_cli_conformance_probes (backend = CodexBackend ())
754+ assert result .severity == Severity .OK
755+ assert "timed out" in result .message .lower ()
756+
757+ def test_ok_when_config_accepted (self , monkeypatch : pytest .MonkeyPatch ) -> None :
758+ import subprocess
759+
760+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
761+ from autoskillit .core import Severity
762+ from autoskillit .execution .backends .codex import CodexBackend
763+
764+ calls = []
765+
766+ def _fake_run (* a , ** kw ):
767+ calls .append (a )
768+ return type (
769+ "CompletedProcess" ,
770+ (),
771+ {"returncode" : 0 , "stdout" : "codex 0.130.0\n " , "stderr" : "" },
772+ )()
773+
774+ monkeypatch .setattr (subprocess , "run" , _fake_run )
775+ result = _check_cli_conformance_probes (backend = CodexBackend ())
776+ assert result .severity == Severity .OK
777+ assert "accepted" in result .message .lower ()
778+ assert len (calls ) == 2
779+
780+ def test_warning_when_config_rejected (self , monkeypatch : pytest .MonkeyPatch ) -> None :
781+ import subprocess
782+
783+ from autoskillit .cli .doctor ._doctor_runtime import _check_cli_conformance_probes
784+ from autoskillit .core import Severity
785+ from autoskillit .execution .backends .codex import CodexBackend
786+
787+ call_count = 0
788+
789+ def _fake_run (* a , ** kw ):
790+ nonlocal call_count
791+ call_count += 1
792+ if call_count == 1 :
793+ return type (
794+ "CompletedProcess" ,
795+ (),
796+ {"returncode" : 0 , "stdout" : "codex 0.130.0\n " , "stderr" : "" },
797+ )()
798+ return type (
799+ "CompletedProcess" ,
800+ (),
801+ {"returncode" : 1 , "stdout" : "" , "stderr" : "unknown flag" },
802+ )()
803+
804+ monkeypatch .setattr (subprocess , "run" , _fake_run )
805+ result = _check_cli_conformance_probes (backend = CodexBackend ())
806+ assert result .severity == Severity .WARNING
807+ assert "rejected" in result .message .lower () or "exit 1" in result .message
0 commit comments