diff --git a/src/langbot/pkg/plugin/connector.py b/src/langbot/pkg/plugin/connector.py index cd07565aa..f2dbff418 100644 --- a/src/langbot/pkg/plugin/connector.py +++ b/src/langbot/pkg/plugin/connector.py @@ -841,6 +841,8 @@ class PluginRuntimeConnector(ManagedRuntimeConnector): runtime_id=self._runtime_id, ) self.worker_policy = self._load_worker_policy() + plugin_config = self.ap.instance_config.data.get('plugin', {}) + connect_timeout_seconds = self._runtime_connect_timeout(plugin_config) async with self._lifecycle_lock: if self._closing: @@ -981,7 +983,6 @@ class PluginRuntimeConnector(ManagedRuntimeConnector): task_coro = self.ctrl.run(new_connection_callback) self._transport_task = asyncio.create_task(task_coro) - connect_timeout_seconds = self._runtime_connect_timeout(self.ap.instance_config.data.get('plugin', {})) try: await asyncio.wait_for(self._connected.wait(), timeout=connect_timeout_seconds) except asyncio.TimeoutError as exc: diff --git a/tests/unit_tests/plugin/test_connector_ping.py b/tests/unit_tests/plugin/test_connector_ping.py index c33f4012a..3b3aee016 100644 --- a/tests/unit_tests/plugin/test_connector_ping.py +++ b/tests/unit_tests/plugin/test_connector_ping.py @@ -132,6 +132,49 @@ async def test_stdio_runtime_connection_does_not_capture_unconsumed_stderr( await connector.aclose() +@pytest.mark.asyncio +async def test_invalid_connect_timeout_is_rejected_before_transport_startup( + monkeypatch: pytest.MonkeyPatch, +): + connector = make_connector() + connector.ap.instance_config.data['plugin']['connect_timeout_seconds'] = 0 + stdio_controller = Mock() + websocket_controller = Mock() + create_task = Mock() + get_platform = Mock(return_value='linux') + use_websocket = Mock(return_value=False) + connector._start_runtime_subprocess = AsyncMock() + monkeypatch.setattr(connector_module.constants, 'instance_id', 'instance-a') + monkeypatch.setattr(connector_module.asyncio, 'create_task', create_task) + monkeypatch.setattr(connector_module.platform, 'get_platform', get_platform) + monkeypatch.setattr( + connector_module.platform, + 'use_websocket_to_connect_plugin_runtime', + use_websocket, + ) + monkeypatch.setattr( + connector_module.stdio_client_controller, + 'StdioClientController', + stdio_controller, + ) + monkeypatch.setattr( + connector_module.ws_client_controller, + 'WebSocketClientController', + websocket_controller, + ) + + with pytest.raises(ValueError, match='plugin.connect_timeout_seconds'): + await connector.initialize() + + get_platform.assert_not_called() + use_websocket.assert_not_called() + stdio_controller.assert_not_called() + websocket_controller.assert_not_called() + connector._start_runtime_subprocess.assert_not_awaited() + create_task.assert_not_called() + assert connector._transport_task is None + + @pytest.mark.asyncio async def test_runtime_disconnect_notifies_once_and_clears_handler( monkeypatch: pytest.MonkeyPatch,