refactor: use rpc

This commit is contained in:
youhuanghe
2026-03-21 10:28:03 +00:00
committed by WangCham
parent 791d052687
commit 14057d1722
12 changed files with 791 additions and 857 deletions
+31 -69
View File
@@ -1,11 +1,11 @@
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import AsyncMock, Mock
from unittest.mock import AsyncMock, Mock, patch
import pytest
from langbot.pkg.box.client import RemoteBoxRuntimeClient
from langbot.pkg.box.client import ActionRPCBoxClient
from langbot.pkg.box.connector import BoxRuntimeConnector
from langbot.pkg.box.errors import BoxRuntimeUnavailableError
@@ -31,95 +31,57 @@ def patch_platform(monkeypatch: pytest.MonkeyPatch, value: str):
monkeypatch.setattr('langbot.pkg.box.connector.platform.get_platform', lambda: value)
def test_box_runtime_connector_uses_explicit_runtime_url():
def test_box_runtime_connector_manages_local_when_no_url(monkeypatch: pytest.MonkeyPatch):
patch_platform(monkeypatch, 'linux')
connector = BoxRuntimeConnector(make_app(Mock()))
assert connector.manages_local_runtime is True
assert isinstance(connector.client, ActionRPCBoxClient)
def test_box_runtime_connector_remote_when_url_configured():
logger = Mock()
connector = BoxRuntimeConnector(make_app(logger, runtime_url='http://box-runtime:5410'))
assert connector.runtime_url == 'http://box-runtime:5410'
assert connector.manages_local_runtime is False
assert isinstance(connector.client, RemoteBoxRuntimeClient)
assert connector.client._base_url == 'http://box-runtime:5410'
assert isinstance(connector.client, ActionRPCBoxClient)
def test_box_runtime_connector_uses_local_default_runtime_url(monkeypatch: pytest.MonkeyPatch):
patch_platform(monkeypatch, 'linux')
connector = BoxRuntimeConnector(make_app(Mock()))
assert connector.runtime_url == 'http://127.0.0.1:5410'
assert connector.manages_local_runtime is True
assert connector.client._base_url == 'http://127.0.0.1:5410'
def test_box_runtime_connector_uses_docker_default_runtime_url(monkeypatch: pytest.MonkeyPatch):
def test_box_runtime_connector_remote_when_docker(monkeypatch: pytest.MonkeyPatch):
patch_platform(monkeypatch, 'docker')
connector = BoxRuntimeConnector(make_app(Mock()))
assert connector.runtime_url == 'http://langbot_box_runtime:5410'
assert connector.manages_local_runtime is False
assert connector.client._base_url == 'http://langbot_box_runtime:5410'
assert connector.ws_relay_base_url == 'http://langbot_box_runtime:5410'
@pytest.mark.asyncio
async def test_box_runtime_connector_initialize_delegates_to_client_when_runtime_is_healthy(
monkeypatch: pytest.MonkeyPatch,
):
def test_box_runtime_connector_ws_relay_url_default(monkeypatch: pytest.MonkeyPatch):
patch_platform(monkeypatch, 'linux')
connector = BoxRuntimeConnector(make_app(Mock()))
connector.client.initialize = AsyncMock()
connector._start_local_runtime_process = AsyncMock()
connector._wait_until_runtime_ready = AsyncMock()
await connector.initialize()
connector.client.initialize.assert_awaited_once()
connector._start_local_runtime_process.assert_not_awaited()
connector._wait_until_runtime_ready.assert_not_awaited()
assert connector.ws_relay_base_url == 'http://127.0.0.1:5410'
@pytest.mark.asyncio
async def test_box_runtime_connector_initialize_autostarts_local_runtime_when_unavailable(
monkeypatch: pytest.MonkeyPatch,
):
patch_platform(monkeypatch, 'linux')
connector = BoxRuntimeConnector(make_app(Mock()))
connector.client.initialize = AsyncMock(side_effect=BoxRuntimeUnavailableError('down'))
connector._start_local_runtime_process = AsyncMock()
connector._wait_until_runtime_ready = AsyncMock()
await connector.initialize()
connector.client.initialize.assert_awaited_once()
connector._start_local_runtime_process.assert_awaited_once()
connector._wait_until_runtime_ready.assert_awaited_once()
@pytest.mark.asyncio
async def test_box_runtime_connector_initialize_remote_runtime_does_not_autostart():
def test_box_runtime_connector_ws_relay_url_explicit():
connector = BoxRuntimeConnector(make_app(Mock(), runtime_url='http://box-runtime:5410'))
connector.client.initialize = AsyncMock()
connector._start_local_runtime_process = AsyncMock()
connector._wait_until_runtime_ready = AsyncMock()
await connector.initialize()
connector.client.initialize.assert_awaited_once()
connector._start_local_runtime_process.assert_not_awaited()
connector._wait_until_runtime_ready.assert_not_awaited()
assert connector.ws_relay_base_url == 'http://box-runtime:5410'
def test_box_runtime_connector_dispose_terminates_local_runtime_process():
def test_box_runtime_connector_dispose_terminates_subprocess():
logger = Mock()
connector = BoxRuntimeConnector(make_app(logger))
runtime_process = Mock()
runtime_process.returncode = None
runtime_task = Mock()
connector.runtime_subprocess = runtime_process
connector.runtime_subprocess_task = runtime_task
subprocess = Mock()
subprocess.returncode = None
handler_task = Mock()
ctrl_task = Mock()
connector._subprocess = subprocess
connector._handler_task = handler_task
connector._ctrl_task = ctrl_task
connector.dispose()
runtime_process.terminate.assert_called_once()
runtime_task.cancel.assert_called_once()
assert connector.runtime_subprocess_task is None
subprocess.terminate.assert_called_once()
handler_task.cancel.assert_called_once()
ctrl_task.cancel.assert_called_once()
assert connector._handler_task is None
assert connector._ctrl_task is None