mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-08 05:18:49 +03:00
feat(config): add actionable startup diagnostics and WebUI recovery (#5110)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import typer
|
||||
from rich.console import Console
|
||||
from typer.testing import CliRunner
|
||||
@@ -27,6 +28,7 @@ class FakeRuntime:
|
||||
self.restarted_options: GatewayStartOptions | None = None
|
||||
self.stop_timeout: int | None = None
|
||||
self.follow_tail: int | None = None
|
||||
self.validated_configs: list[Config] = []
|
||||
|
||||
def start_background(self, options: GatewayStartOptions) -> RuntimeResult:
|
||||
self.started_options = options
|
||||
@@ -84,11 +86,15 @@ class FakeServiceInstaller:
|
||||
)
|
||||
|
||||
|
||||
def _test_app(tmp_path: Path, config: Config | None = None):
|
||||
def _test_app(
|
||||
tmp_path: Path,
|
||||
config: Config | None = None,
|
||||
startup_error: str | None = None,
|
||||
):
|
||||
app = typer.Typer()
|
||||
fake_runtime = FakeRuntime(tmp_path)
|
||||
fake_service = FakeServiceInstaller(tmp_path)
|
||||
run_calls: list[tuple[Config, int | None, str | None]] = []
|
||||
run_calls: list[tuple[Config, int | None, str | None, str | None]] = []
|
||||
prepare_calls: list[tuple[Config, str]] = []
|
||||
|
||||
def load_runtime_config(_config_path: str | None, _workspace: str | None) -> Config:
|
||||
@@ -99,18 +105,28 @@ def _test_app(tmp_path: Path, config: Config | None = None):
|
||||
*,
|
||||
port: int | None = None,
|
||||
webui_bundle_mode: str | None = None,
|
||||
unconfigured_provider_error: str | None = None,
|
||||
) -> None:
|
||||
run_calls.append((config, port, webui_bundle_mode))
|
||||
run_calls.append(
|
||||
(config, port, webui_bundle_mode, unconfigured_provider_error)
|
||||
)
|
||||
|
||||
def prepare_webui_bundle(config: Config, mode: str) -> None:
|
||||
prepare_calls.append((config, mode))
|
||||
|
||||
def validate_startup_config(config: Config) -> str | None:
|
||||
fake_runtime.validated_configs.append(config)
|
||||
return startup_error
|
||||
|
||||
app.add_typer(
|
||||
create_gateway_app(
|
||||
console=Console(),
|
||||
log_handler_id=0,
|
||||
load_runtime_config=load_runtime_config,
|
||||
run_gateway=run_gateway,
|
||||
validate_startup_config=(
|
||||
validate_startup_config if startup_error is not None else None
|
||||
),
|
||||
runtime_factory=lambda **_kwargs: fake_runtime,
|
||||
service_factory=lambda: fake_service,
|
||||
prepare_webui_bundle=prepare_webui_bundle,
|
||||
@@ -131,6 +147,46 @@ def test_gateway_default_still_runs_foreground(tmp_path):
|
||||
assert calls[0][2] == "warn"
|
||||
|
||||
|
||||
def test_gateway_foreground_passes_recoverable_provider_error_to_runner(tmp_path):
|
||||
setup_error = "No provider is configured."
|
||||
app, _runtime, _service, calls, _prepare_calls = _test_app(
|
||||
tmp_path,
|
||||
startup_error=setup_error,
|
||||
)
|
||||
|
||||
result = runner.invoke(app, ["gateway"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert len(calls) == 1
|
||||
assert calls[0][3] == setup_error
|
||||
assert len(_runtime.validated_configs) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("args", "runtime_attribute"),
|
||||
[
|
||||
(["gateway", "--background"], "started_options"),
|
||||
(["gateway", "restart"], "restarted_options"),
|
||||
],
|
||||
)
|
||||
def test_gateway_managed_start_allows_recoverable_provider_error(
|
||||
tmp_path,
|
||||
args: list[str],
|
||||
runtime_attribute: str,
|
||||
) -> None:
|
||||
app, fake_runtime, _service, calls, _prepare_calls = _test_app(
|
||||
tmp_path,
|
||||
startup_error="No provider is configured.",
|
||||
)
|
||||
|
||||
result = runner.invoke(app, args)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert calls == []
|
||||
assert len(fake_runtime.validated_configs) == 1
|
||||
assert getattr(fake_runtime, runtime_attribute) is not None
|
||||
|
||||
|
||||
def test_gateway_background_starts_detached_runtime(tmp_path):
|
||||
config = Config()
|
||||
config.gateway.port = 18792
|
||||
|
||||
Reference in New Issue
Block a user