Skip to content

Commit 51274ac

Browse files
authored
fix: mcp toolit and test (#2417)
1 parent 6425437 commit 51274ac

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

camel/toolkits/mcp_toolkit.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,6 @@ async def disconnect(self):
715715
for server in self.servers:
716716
await server.disconnect()
717717
self._connected = False
718-
await self._exit_stack.aclose()
719718

720719
@asynccontextmanager
721720
async def connection(self) -> AsyncGenerator["MCPToolkit", None]:

test/toolkits/test_mcp_toolkit.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
1414
import json
1515
import tempfile
16-
from contextlib import AsyncExitStack
1716
from pathlib import Path
1817
from unittest.mock import AsyncMock, MagicMock, patch
1918

@@ -417,8 +416,9 @@ async def test_disconnect_explicit(self):
417416

418417
# Setup connected state
419418
server._is_connected = True
420-
server._exit_stack = AsyncMock()
421-
server._exit_stack.aclose = AsyncMock()
419+
# Assign an AsyncMock to _exit_stack to check its aclose method
420+
mock_exit_stack = AsyncMock()
421+
server._exit_stack = mock_exit_stack
422422
server._session = MagicMock()
423423

424424
# Test disconnect
@@ -427,20 +427,36 @@ async def test_disconnect_explicit(self):
427427
# Verify results
428428
assert server._is_connected is False
429429
assert server.session is None
430-
server._exit_stack.aclose.assert_called_once()
430+
# Assert that aclose was called on the original mock_exit_stack
431+
mock_exit_stack.aclose.assert_called_once()
431432

432433
# Test disconnecting when not connected
433-
server._exit_stack.aclose.reset_mock()
434-
435-
# Set up disconnected state
436-
server._is_connected = False
437434
server._exit_stack = AsyncMock()
438435
server._exit_stack.aclose = AsyncMock()
439436

440437
await server.disconnect()
441438

442439
# Verify exit stack is still closed even when not connected
443-
server._exit_stack.aclose.assert_called_once()
440+
server._exit_stack.aclose.assert_not_called()
441+
442+
@pytest.mark.asyncio
443+
async def test_disconnect_without_connection(self):
444+
r"""Test explicit disconnect method without connection."""
445+
# Create server
446+
server = MCPClient("test_command")
447+
448+
# Setup not connected state
449+
server._is_connected = False
450+
# Store the mock session to assert its identity
451+
initial_mock_session = MagicMock()
452+
server._session = initial_mock_session
453+
454+
# Test disconnect
455+
await server.disconnect()
456+
457+
# Verify results
458+
assert server._is_connected is False
459+
assert server.session is initial_mock_session
444460

445461

446462
class TestMCPToolkit:
@@ -454,7 +470,6 @@ def test_init(self):
454470
toolkit = MCPToolkit(servers=[server1, server2])
455471

456472
assert toolkit.servers == [server1, server2]
457-
assert isinstance(toolkit._exit_stack, AsyncExitStack)
458473
assert toolkit._connected is False
459474

460475
# Test with both servers and config_path
@@ -601,11 +616,11 @@ async def test_connection(self):
601616
# Test connection context manager
602617
async with toolkit.connection() as connected_toolkit:
603618
assert connected_toolkit._connected is True
604-
assert isinstance(connected_toolkit._exit_stack, AsyncExitStack)
619+
for server_mock in [server1, server2]:
620+
server_mock.connect.assert_called_once()
605621

606622
# Verify context exit cleans up properly
607623
assert toolkit._connected is False
608-
assert isinstance(toolkit._exit_stack, AsyncExitStack)
609624

610625
def test_is_connected(self):
611626
r"""Test is_connected method."""
@@ -656,9 +671,8 @@ async def test_connect(self):
656671
# Verify results
657672
assert result == toolkit
658673
assert toolkit._connected is True
659-
assert toolkit._exit_stack is not None
660-
server1.connect.assert_called_once()
661-
server2.connect.assert_called_once()
674+
for server_mock in [server1, server2]:
675+
server_mock.connect.assert_called_once()
662676

663677
# Test connecting when already connected
664678
with patch("camel.toolkits.mcp_toolkit.logger") as mock_logger:
@@ -710,8 +724,6 @@ async def test_disconnect(self):
710724

711725
# Setup connected state
712726
toolkit._connected = True
713-
toolkit._exit_stack = AsyncMock()
714-
toolkit._exit_stack.aclose = AsyncMock()
715727

716728
# Test disconnect
717729
await toolkit.disconnect()
@@ -720,16 +732,13 @@ async def test_disconnect(self):
720732
assert toolkit._connected is False
721733
server1.disconnect.assert_called_once()
722734
server2.disconnect.assert_called_once()
723-
toolkit._exit_stack.aclose.assert_called_once()
724735

725736
# Test disconnecting when not connected
726737
server1.disconnect.reset_mock()
727738
server2.disconnect.reset_mock()
728-
toolkit._exit_stack.aclose.reset_mock()
729739

730740
await toolkit.disconnect()
731741

732742
# Verify no actions taken when not connected
733743
server1.disconnect.assert_not_called()
734744
server2.disconnect.assert_not_called()
735-
toolkit._exit_stack.aclose.assert_not_called()

0 commit comments

Comments
 (0)