import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from llamacppctl import actions, main as main_mod # noqa: E402 CONFIG = """ [default] hf_home = /srv/models model_path = qwen3/default.gguf container_name = test_main """ def _config(tmp_path: Path) -> Path: path = tmp_path / "llama.cpp.config" path.write_text(CONFIG, encoding="utf-8") return path def test_print_effective_config_has_no_side_effects(tmp_path, monkeypatch, capsys): """Regression: --print-effective-config used to fall through into do_start() because argparse always required an action, silently replacing a running container.""" started = [] monkeypatch.setattr(actions, "do_start", lambda *a, **k: started.append(1)) monkeypatch.setattr(actions, "do_change", lambda *a, **k: started.append(1)) monkeypatch.setattr(actions, "do_stop", lambda *a, **k: started.append(1)) rc = main_mod.run(["--print-effective-config", "--config", str(_config(tmp_path))]) assert rc == 0 assert started == [] assert '"container_name": "test_main"' in capsys.readouterr().out def test_print_effective_config_works_without_docker(tmp_path, monkeypatch, capsys): """It is a pure config check, so it must not require a reachable daemon.""" def boom() -> bool: raise AssertionError("docker_available() must not be consulted") monkeypatch.setattr(main_mod, "docker_available", boom) rc = main_mod.run(["--print-effective-config", "--config", str(_config(tmp_path))]) assert rc == 0 assert '"hf_home": "/srv/models"' in capsys.readouterr().out def test_start_still_requires_docker(tmp_path, monkeypatch, capsys): monkeypatch.setattr(main_mod, "docker_available", lambda: False) rc = main_mod.run(["--start", "--config", str(_config(tmp_path))]) assert rc == 1 assert "docker is not available" in capsys.readouterr().err