Skip to content

Commit c50a593

Browse files
committed
add tests
1 parent 23ff11d commit c50a593

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

src/mcp/server/fastmcp/tools/tool_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def remove_tool(self, name: str) -> None:
7272
"""Remove a tool by name."""
7373
if name not in self._tools:
7474
logger.warning(f"Tried to remove unknown tool: {name}")
75+
return
7576
del self._tools[name]
7677

7778
async def call_tool(

tests/server/fastmcp/test_tool_manager.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,117 @@ def get_scores() -> dict[str, int]:
633633
# Test converted result
634634
result = await manager.call_tool("get_scores", {})
635635
assert result == expected
636+
637+
638+
class TestRemoveTools:
639+
"""Test tool removal functionality in the tool manager."""
640+
641+
def test_remove_existing_tool(self, caplog: pytest.LogCaptureFixture):
642+
"""Test removing an existing tool."""
643+
def add(a: int, b: int) -> int:
644+
"""Add two numbers."""
645+
return a + b
646+
647+
manager = ToolManager()
648+
manager.add_tool(add)
649+
650+
# Verify tool exists
651+
assert manager.get_tool("add") is not None
652+
assert len(manager.list_tools()) == 1
653+
654+
# Remove the tool
655+
with caplog.at_level(logging.WARNING):
656+
manager.remove_tool("add")
657+
# Should not log a warning for removing existing tool
658+
assert "Tried to remove unknown tool: add" not in caplog.text
659+
660+
# Verify tool is removed
661+
assert manager.get_tool("add") is None
662+
assert len(manager.list_tools()) == 0
663+
664+
def test_remove_nonexistent_tool(self, caplog: pytest.LogCaptureFixture):
665+
"""Test removing a non-existent tool logs a warning."""
666+
manager = ToolManager()
667+
668+
with caplog.at_level(logging.WARNING):
669+
manager.remove_tool("nonexistent")
670+
assert "Tried to remove unknown tool: nonexistent" in caplog.text
671+
672+
def test_remove_tool_from_multiple_tools(self):
673+
"""Test removing one tool when multiple tools exist."""
674+
def add(a: int, b: int) -> int:
675+
"""Add two numbers."""
676+
return a + b
677+
678+
def multiply(a: int, b: int) -> int:
679+
"""Multiply two numbers."""
680+
return a * b
681+
682+
def divide(a: int, b: int) -> float:
683+
"""Divide two numbers."""
684+
return a / b
685+
686+
manager = ToolManager()
687+
manager.add_tool(add)
688+
manager.add_tool(multiply)
689+
manager.add_tool(divide)
690+
691+
# Verify all tools exist
692+
assert len(manager.list_tools()) == 3
693+
assert manager.get_tool("add") is not None
694+
assert manager.get_tool("multiply") is not None
695+
assert manager.get_tool("divide") is not None
696+
697+
# Remove middle tool
698+
manager.remove_tool("multiply")
699+
700+
# Verify only multiply is removed
701+
assert len(manager.list_tools()) == 2
702+
assert manager.get_tool("add") is not None
703+
assert manager.get_tool("multiply") is None
704+
assert manager.get_tool("divide") is not None
705+
706+
@pytest.mark.anyio
707+
async def test_call_removed_tool_raises_error(self):
708+
"""Test that calling a removed tool raises ToolError."""
709+
def greet(name: str) -> str:
710+
"""Greet someone."""
711+
return f"Hello, {name}!"
712+
713+
manager = ToolManager()
714+
manager.add_tool(greet)
715+
716+
# Verify tool works before removal
717+
result = await manager.call_tool("greet", {"name": "World"})
718+
assert result == "Hello, World!"
719+
720+
# Remove the tool
721+
manager.remove_tool("greet")
722+
723+
# Verify calling removed tool raises error
724+
with pytest.raises(ToolError, match="Unknown tool: greet"):
725+
await manager.call_tool("greet", {"name": "World"})
726+
727+
def test_remove_tool_case_sensitive(self, caplog: pytest.LogCaptureFixture):
728+
"""Test that tool removal is case-sensitive."""
729+
def test_func() -> str:
730+
"""Test function."""
731+
return "test"
732+
733+
manager = ToolManager()
734+
manager.add_tool(test_func)
735+
736+
# Verify tool exists
737+
assert manager.get_tool("test_func") is not None
738+
739+
# Try to remove with different case
740+
with caplog.at_level(logging.WARNING):
741+
manager.remove_tool("Test_Func")
742+
assert "Tried to remove unknown tool: Test_Func" in caplog.text
743+
744+
# Verify original tool still exists
745+
assert manager.get_tool("test_func") is not None
746+
747+
# Remove with correct case
748+
manager.remove_tool("test_func")
749+
assert manager.get_tool("test_func") is None

0 commit comments

Comments
 (0)