|
21 | 21 | fetch_user_auth, |
22 | 22 | get_ias_client_id_lob, |
23 | 23 | get_mcp_tools_lob, |
| 24 | + list_server_tools, |
24 | 25 | get_agent_cards_lob, |
25 | 26 | _fetch_agent_card, |
26 | 27 | call_mcp_tool_lob, |
@@ -600,6 +601,91 @@ async def mock_list_tools_fn(*args, **kwargs): |
600 | 601 | assert result[0].name == "tool2" |
601 | 602 |
|
602 | 603 |
|
| 604 | +# ============================================================ |
| 605 | +# Test: list_server_tools |
| 606 | +# ============================================================ |
| 607 | + |
| 608 | + |
| 609 | +class TestListServerTools: |
| 610 | + """Tests for list_server_tools async function.""" |
| 611 | + |
| 612 | + @pytest.mark.asyncio |
| 613 | + async def test_returns_empty_when_list_tools_returns_none(self, caplog): |
| 614 | + """Return empty list when MCP list_tools response is None (OTel instrumentation).""" |
| 615 | + import logging |
| 616 | + |
| 617 | + caplog.set_level(logging.WARNING, logger="sap_cloud_sdk.agentgateway._lob") |
| 618 | + |
| 619 | + with ( |
| 620 | + patch("sap_cloud_sdk.agentgateway._lob.httpx.AsyncClient") as mock_http, |
| 621 | + patch( |
| 622 | + "sap_cloud_sdk.agentgateway._lob.streamable_http_client" |
| 623 | + ) as mock_stream, |
| 624 | + patch("sap_cloud_sdk.agentgateway._lob.ClientSession") as mock_session, |
| 625 | + ): |
| 626 | + mock_http_instance = AsyncMock() |
| 627 | + mock_http.return_value.__aenter__.return_value = mock_http_instance |
| 628 | + |
| 629 | + mock_stream.return_value.__aenter__.return_value = ( |
| 630 | + AsyncMock(), |
| 631 | + AsyncMock(), |
| 632 | + None, |
| 633 | + ) |
| 634 | + |
| 635 | + mock_session_instance = AsyncMock() |
| 636 | + mock_init = MagicMock() |
| 637 | + mock_init.serverInfo.name = "test-server" |
| 638 | + mock_session_instance.initialize = AsyncMock(return_value=mock_init) |
| 639 | + mock_session_instance.list_tools = AsyncMock(return_value=None) |
| 640 | + mock_session.return_value.__aenter__.return_value = mock_session_instance |
| 641 | + |
| 642 | + result = await list_server_tools( |
| 643 | + "https://example.com/mcp", "auth-token", "frag-a", 60.0 |
| 644 | + ) |
| 645 | + |
| 646 | + assert result == [] |
| 647 | + assert "returned no tools from list_tools()" in caplog.text |
| 648 | + |
| 649 | + @pytest.mark.asyncio |
| 650 | + async def test_returns_empty_when_tools_attribute_is_none(self, caplog): |
| 651 | + """Return empty list when list_tools result has tools=None.""" |
| 652 | + import logging |
| 653 | + |
| 654 | + caplog.set_level(logging.WARNING, logger="sap_cloud_sdk.agentgateway._lob") |
| 655 | + |
| 656 | + with ( |
| 657 | + patch("sap_cloud_sdk.agentgateway._lob.httpx.AsyncClient") as mock_http, |
| 658 | + patch( |
| 659 | + "sap_cloud_sdk.agentgateway._lob.streamable_http_client" |
| 660 | + ) as mock_stream, |
| 661 | + patch("sap_cloud_sdk.agentgateway._lob.ClientSession") as mock_session, |
| 662 | + ): |
| 663 | + mock_http_instance = AsyncMock() |
| 664 | + mock_http.return_value.__aenter__.return_value = mock_http_instance |
| 665 | + |
| 666 | + mock_stream.return_value.__aenter__.return_value = ( |
| 667 | + AsyncMock(), |
| 668 | + AsyncMock(), |
| 669 | + None, |
| 670 | + ) |
| 671 | + |
| 672 | + mock_session_instance = AsyncMock() |
| 673 | + mock_init = MagicMock() |
| 674 | + mock_init.serverInfo.name = "test-server" |
| 675 | + mock_session_instance.initialize = AsyncMock(return_value=mock_init) |
| 676 | + mock_list_result = MagicMock() |
| 677 | + mock_list_result.tools = None |
| 678 | + mock_session_instance.list_tools = AsyncMock(return_value=mock_list_result) |
| 679 | + mock_session.return_value.__aenter__.return_value = mock_session_instance |
| 680 | + |
| 681 | + result = await list_server_tools( |
| 682 | + "https://example.com/mcp", "auth-token", "frag-a", 60.0 |
| 683 | + ) |
| 684 | + |
| 685 | + assert result == [] |
| 686 | + assert "returned no tools from list_tools()" in caplog.text |
| 687 | + |
| 688 | + |
603 | 689 | # ============================================================ |
604 | 690 | # Test: call_mcp_tool_lob |
605 | 691 | # ============================================================ |
|
0 commit comments