mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-24 13:26:08 +00:00
fix(runtime): harden connector lifecycle
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from langbot_plugin.box.client import ActionRPCBoxClient
|
||||
from langbot.pkg.box import connector as connector_module
|
||||
from langbot.pkg.box.connector import BoxRuntimeConnector
|
||||
|
||||
|
||||
@@ -122,3 +124,95 @@ async def test_box_runtime_connector_cleans_partial_transport_on_connect_failure
|
||||
|
||||
assert connector._stop_transport.await_count == 2
|
||||
connector._close_managed_subprocess.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_box_stdio_connection_does_not_capture_unconsumed_stderr(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
monkeypatch.setattr('langbot.pkg.utils.platform.get_platform', lambda: 'linux')
|
||||
monkeypatch.setattr('langbot.pkg.utils.platform.standalone_box', False)
|
||||
created = {}
|
||||
|
||||
class FakeHandler:
|
||||
def __init__(self, connection):
|
||||
self.release = asyncio.Event()
|
||||
|
||||
async def call_action(self, action, data):
|
||||
return None
|
||||
|
||||
async def run(self):
|
||||
await self.release.wait()
|
||||
|
||||
async def close(self):
|
||||
self.release.set()
|
||||
|
||||
class FakeController:
|
||||
def __init__(self, **kwargs):
|
||||
created.update(kwargs)
|
||||
self.process = SimpleNamespace(returncode=0)
|
||||
|
||||
async def run(self, callback):
|
||||
await callback(object())
|
||||
|
||||
async def close(self):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(connector_module, 'Handler', FakeHandler)
|
||||
monkeypatch.setattr(
|
||||
'langbot_plugin.runtime.io.controllers.stdio.client.StdioClientController',
|
||||
FakeController,
|
||||
)
|
||||
connector = BoxRuntimeConnector(make_app(Mock()))
|
||||
|
||||
await connector.initialize()
|
||||
|
||||
assert created['capture_stderr'] is False
|
||||
assert connector._handler is not None
|
||||
await connector.aclose()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_box_disconnect_notifies_once_and_clears_handler(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
monkeypatch.setattr('langbot.pkg.utils.platform.get_platform', lambda: 'linux')
|
||||
monkeypatch.setattr('langbot.pkg.utils.platform.standalone_box', False)
|
||||
disconnect = AsyncMock()
|
||||
|
||||
class FakeHandler:
|
||||
def __init__(self, connection):
|
||||
pass
|
||||
|
||||
async def call_action(self, action, data):
|
||||
return None
|
||||
|
||||
async def run(self):
|
||||
return None
|
||||
|
||||
async def close(self):
|
||||
return None
|
||||
|
||||
class FakeController:
|
||||
def __init__(self, **kwargs):
|
||||
self.process = SimpleNamespace(returncode=0)
|
||||
|
||||
async def run(self, callback):
|
||||
await callback(object())
|
||||
|
||||
async def close(self):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(connector_module, 'Handler', FakeHandler)
|
||||
monkeypatch.setattr(
|
||||
'langbot_plugin.runtime.io.controllers.stdio.client.StdioClientController',
|
||||
FakeController,
|
||||
)
|
||||
connector = BoxRuntimeConnector(make_app(Mock()), runtime_disconnect_callback=disconnect)
|
||||
|
||||
await connector.initialize()
|
||||
await asyncio.sleep(0)
|
||||
|
||||
disconnect.assert_awaited_once_with(connector)
|
||||
assert connector._handler is None
|
||||
await connector.aclose()
|
||||
|
||||
Reference in New Issue
Block a user