@@ -0,0 +1,41 @@ |
| | 1 | +"""CLI tests for ``sway serve``. |
| | 2 | + |
| | 3 | +These cover argument validation only — actually running uvicorn would |
| | 4 | +bind a port. The 0.0.0.0-without-api-key refusal is the load-bearing |
| | 5 | +check (sprint plan risk #1: anyone-on-LAN-drives-your-GPU). |
| | 6 | +""" |
| | 7 | + |
| | 8 | +from __future__ import annotations |
| | 9 | + |
| | 10 | +import pytest |
| | 11 | + |
| | 12 | +pytest.importorskip("fastapi") |
| | 13 | + |
| | 14 | +from typer.testing import CliRunner # noqa: E402 |
| | 15 | + |
| | 16 | +from dlm_sway.cli.app import app # noqa: E402 |
| | 17 | + |
| | 18 | + |
| | 19 | +def test_serve_in_help() -> None: |
| | 20 | + result = CliRunner().invoke(app, ["--help"]) |
| | 21 | + assert result.exit_code == 0 |
| | 22 | + assert "serve" in result.stdout |
| | 23 | + |
| | 24 | + |
| | 25 | +def test_serve_refuses_public_bind_without_api_key() -> None: |
| | 26 | + result = CliRunner().invoke(app, ["serve", "--host", "0.0.0.0", "--port", "8787"]) |
| | 27 | + assert result.exit_code == 2 |
| | 28 | + # Mix of stdout/stderr depending on typer version; check both. |
| | 29 | + combined = (result.stdout or "") + (result.stderr or "") |
| | 30 | + assert "--api-key" in combined |
| | 31 | + assert "0.0.0.0" in combined |
| | 32 | + |
| | 33 | + |
| | 34 | +def test_serve_rejects_zero_max_loaded_models() -> None: |
| | 35 | + result = CliRunner().invoke(app, ["serve", "--max-loaded-models", "0"]) |
| | 36 | + assert result.exit_code == 2 |
| | 37 | + |
| | 38 | + |
| | 39 | +def test_serve_rejects_invalid_port() -> None: |
| | 40 | + result = CliRunner().invoke(app, ["serve", "--port", "0"]) |
| | 41 | + assert result.exit_code != 0 |