mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-09-04 02:01:48 +03:00
fix(gateway): preserve shared runtime identity
This commit is contained in:
@@ -8,7 +8,13 @@ from typer.testing import CliRunner
|
||||
|
||||
from nanobot.cli.gateway import _resolved_config_selector, create_gateway_app
|
||||
from nanobot.config.schema import Config
|
||||
from nanobot.gateway import GatewayRuntimePaths, GatewayStartOptions, GatewayStatus, RuntimeResult
|
||||
from nanobot.gateway import (
|
||||
GatewayInstance,
|
||||
GatewayRuntimePaths,
|
||||
GatewayStartOptions,
|
||||
GatewayStatus,
|
||||
RuntimeResult,
|
||||
)
|
||||
from nanobot.gateway.service import GatewayServiceOptions, GatewayServiceResult
|
||||
|
||||
runner = CliRunner()
|
||||
@@ -111,7 +117,9 @@ def _test_app(
|
||||
app = typer.Typer()
|
||||
fake_runtime = FakeRuntime(tmp_path)
|
||||
fake_service = FakeServiceInstaller(tmp_path)
|
||||
run_calls: list[tuple[Config, int | None, str | None, str | None]] = []
|
||||
run_calls: list[
|
||||
tuple[Config, int | None, str | None, str | None, GatewayInstance | None]
|
||||
] = []
|
||||
prepare_calls: list[tuple[Config, str]] = []
|
||||
|
||||
def load_runtime_config(_config_path: str | None, _workspace: str | None) -> Config:
|
||||
@@ -123,9 +131,10 @@ def _test_app(
|
||||
port: int | None = None,
|
||||
webui_bundle_mode: str | None = None,
|
||||
unconfigured_provider_error: str | None = None,
|
||||
gateway_instance: GatewayInstance | None = None,
|
||||
) -> None:
|
||||
run_calls.append(
|
||||
(config, port, webui_bundle_mode, unconfigured_provider_error)
|
||||
(config, port, webui_bundle_mode, unconfigured_provider_error, gateway_instance)
|
||||
)
|
||||
|
||||
def prepare_webui_bundle(config: Config, mode: str) -> None:
|
||||
@@ -162,6 +171,22 @@ def test_gateway_default_still_runs_foreground(tmp_path):
|
||||
assert len(calls) == 1
|
||||
assert calls[0][1] == 18791
|
||||
assert calls[0][2] == "warn"
|
||||
assert calls[0][4] == GatewayInstance.resolve(
|
||||
config_path=_resolved_config_selector(None)
|
||||
)
|
||||
|
||||
|
||||
def test_config_workspace_does_not_split_the_foreground_instance(tmp_path: Path) -> None:
|
||||
config = Config()
|
||||
config.agents.defaults.workspace = str(tmp_path / "configured-workspace")
|
||||
app, _runtime, _service, calls, _prepare_calls = _test_app(tmp_path, config=config)
|
||||
|
||||
result = runner.invoke(app, ["gateway"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert calls[0][4] == GatewayInstance.resolve(
|
||||
config_path=_resolved_config_selector(None)
|
||||
)
|
||||
|
||||
|
||||
def test_gateway_foreground_passes_recoverable_provider_error_to_runner(tmp_path):
|
||||
@@ -213,7 +238,9 @@ def test_gateway_background_starts_detached_runtime(tmp_path):
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Gateway started in the background" in result.stdout
|
||||
assert fake_runtime.started_options == GatewayStartOptions(port=18792)
|
||||
assert fake_runtime.started_options == GatewayInstance.resolve(
|
||||
config_path=_resolved_config_selector(None)
|
||||
).start_options(port=18792)
|
||||
assert prepare_calls == [(config, "warn")]
|
||||
|
||||
|
||||
@@ -344,7 +371,9 @@ def test_gateway_restart_starts_background_runtime(tmp_path):
|
||||
assert result.exit_code == 0
|
||||
assert "Gateway restarted in the background" in result.stdout
|
||||
assert fake_runtime.stop_timeout == 9
|
||||
assert fake_runtime.restarted_options == GatewayStartOptions(port=18793, verbose=True)
|
||||
assert fake_runtime.restarted_options == GatewayInstance.resolve(
|
||||
config_path=_resolved_config_selector(None)
|
||||
).start_options(port=18793, verbose=True)
|
||||
assert prepare_calls == [(config, "warn")]
|
||||
assert json.loads(lease_state.read_text(encoding="utf-8"))["auto_stop"] is True
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import pytest
|
||||
|
||||
from nanobot.gateway import (
|
||||
GatewayClientLease,
|
||||
GatewayInstance,
|
||||
GatewayRuntime,
|
||||
GatewayRuntimePaths,
|
||||
GatewayStartOptions,
|
||||
@@ -58,6 +59,34 @@ def test_paths_use_stable_instance_suffix_for_custom_selectors(tmp_path):
|
||||
assert first_paths.log_path != second_paths.log_path
|
||||
|
||||
|
||||
def test_default_instance_preserves_released_gateway_paths() -> None:
|
||||
config_path = Path.home() / ".nanobot" / "config.json"
|
||||
|
||||
instance = GatewayInstance.resolve(config_path=config_path)
|
||||
|
||||
assert instance.paths.state_path == config_path.parent / "run" / "gateway.json"
|
||||
assert instance.paths.log_path == config_path.parent / "logs" / "gateway.log"
|
||||
assert instance.start_options(port=18790) == GatewayStartOptions(port=18790)
|
||||
|
||||
|
||||
def test_custom_instance_round_trips_the_same_child_selectors(tmp_path: Path) -> None:
|
||||
config_path = tmp_path / "instance" / "config.json"
|
||||
workspace = tmp_path / "workspace"
|
||||
parent = GatewayInstance.resolve(
|
||||
config_path=config_path,
|
||||
workspace=str(workspace),
|
||||
)
|
||||
options = parent.start_options(port=18790)
|
||||
|
||||
child = GatewayInstance.resolve(
|
||||
config_path=options.config_path or "",
|
||||
workspace=options.workspace,
|
||||
)
|
||||
|
||||
assert child == parent
|
||||
assert parent.paths.state_path.name.startswith("gateway.")
|
||||
|
||||
|
||||
def test_start_background_writes_state_and_child_command(tmp_path, monkeypatch):
|
||||
calls: list[dict] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user