Skip to main content
Glama

adx-mcp-server

MIT License
48
  • Linux
  • Apple
test_server.py15 kB
#!/usr/bin/env python import os import pytest import json from unittest.mock import patch, MagicMock, AsyncMock import asyncio # Import the modules to test from adx_mcp_server import server from adx_mcp_server.server import execute_query, list_tables, get_table_schema, sample_table_data class TestServerTools: @pytest.mark.asyncio async def test_execute_query(self, monkeypatch): """Test the execute_query tool.""" # Configure a known database value original_database = server.config.database server.config.database = "testdb" try: with patch('adx_mcp_server.server.get_kusto_client') as mock_get_client: # Create mock client and result mock_client = MagicMock() # Set up mock response mock_result_set = MagicMock() primary_result = MagicMock() # Create a column structure similar to what KustoClient would return column1 = MagicMock() column1.column_name = "Column1" column2 = MagicMock() column2.column_name = "Column2" primary_result.columns = [column1, column2] primary_result.rows = [ ["Value1", 1], ["Value2", 2] ] mock_result_set.primary_results = [primary_result] mock_client.execute.return_value = mock_result_set mock_get_client.return_value = mock_client # Execute the query test_query = "test query" result = await execute_query(test_query) # Manually verify the call arguments assert mock_client.execute.call_count == 1 args, kwargs = mock_client.execute.call_args assert args[0] == "testdb" # First arg should be database assert args[1] == test_query # Second arg should be query # Check result structure assert len(result) == 2 assert result[0]["Column1"] == "Value1" assert result[0]["Column2"] == 1 assert result[1]["Column1"] == "Value2" assert result[1]["Column2"] == 2 finally: # Restore the original database value server.config.database = original_database @pytest.mark.asyncio async def test_list_tables(self, monkeypatch): """Test the list_tables tool.""" # Configure a known database value original_database = server.config.database server.config.database = "testdb" try: with patch('adx_mcp_server.server.get_kusto_client') as mock_get_client: # Create mock client and result mock_client = MagicMock() # Set up mock response mock_result_set = MagicMock() primary_result = MagicMock() # Create columns for table list col1 = MagicMock() col1.column_name = "TableName" col2 = MagicMock() col2.column_name = "Folder" col3 = MagicMock() col3.column_name = "DatabaseName" primary_result.columns = [col1, col2, col3] primary_result.rows = [ ["table1", "folder1", "testdb"], ["table2", "folder2", "testdb"] ] mock_result_set.primary_results = [primary_result] mock_client.execute.return_value = mock_result_set mock_get_client.return_value = mock_client # Execute the query result = await list_tables() # Manually verify the execute call assert mock_client.execute.call_count == 1 args, kwargs = mock_client.execute.call_args assert args[0] == "testdb" # First arg should be database assert ".show tables" in args[1] # Second arg should contain the query # Check result structure assert len(result) == 2 assert result[0]["TableName"] == "table1" assert result[1]["TableName"] == "table2" finally: # Restore the original database value server.config.database = original_database @pytest.mark.asyncio async def test_get_table_schema(self, monkeypatch): """Test the get_table_schema tool.""" # Configure a known database value original_database = server.config.database server.config.database = "testdb" try: with patch('adx_mcp_server.server.get_kusto_client') as mock_get_client: # Create mock client and result mock_client = MagicMock() # Set up mock response mock_result_set = MagicMock() primary_result = MagicMock() # Create columns for schema col1 = MagicMock() col1.column_name = "ColumnName" col2 = MagicMock() col2.column_name = "ColumnType" primary_result.columns = [col1, col2] primary_result.rows = [ ["id", "string"], ["value", "double"] ] mock_result_set.primary_results = [primary_result] mock_client.execute.return_value = mock_result_set mock_get_client.return_value = mock_client # Execute the query table_name = "test_table" result = await get_table_schema(table_name) # Manually verify the execute call assert mock_client.execute.call_count == 1 args, kwargs = mock_client.execute.call_args assert args[0] == "testdb" # First arg should be database assert f"{table_name}" in args[1] # Second arg should contain the table name assert "getschema" in args[1] # Second arg should contain the getschema command # Check result structure assert len(result) == 2 assert result[0]["ColumnName"] == "id" assert result[0]["ColumnType"] == "string" assert result[1]["ColumnName"] == "value" assert result[1]["ColumnType"] == "double" finally: # Restore the original database value server.config.database = original_database @pytest.mark.asyncio async def test_sample_table_data(self, monkeypatch): """Test the sample_table_data tool.""" # Configure a known database value original_database = server.config.database server.config.database = "testdb" try: with patch('adx_mcp_server.server.get_kusto_client') as mock_get_client: # Create mock client and result mock_client = MagicMock() # Set up mock response mock_result_set = MagicMock() primary_result = MagicMock() # Create columns for sample data col1 = MagicMock() col1.column_name = "id" col2 = MagicMock() col2.column_name = "value" primary_result.columns = [col1, col2] primary_result.rows = [ ["row1", 100], ["row2", 200] ] mock_result_set.primary_results = [primary_result] mock_client.execute.return_value = mock_result_set mock_get_client.return_value = mock_client # Execute the query table_name = "test_table" sample_size = 5 result = await sample_table_data(table_name, sample_size) # Manually verify the execute call assert mock_client.execute.call_count == 1 args, kwargs = mock_client.execute.call_args assert args[0] == "testdb" # First arg should be database assert table_name in args[1] # Second arg should contain the table name assert f"sample {sample_size}" in args[1] # Second arg should contain the sample command # Check result structure assert len(result) == 2 assert result[0]["id"] == "row1" assert result[0]["value"] == 100 assert result[1]["id"] == "row2" assert result[1]["value"] == 200 finally: # Restore the original database value server.config.database = original_database @pytest.mark.asyncio async def test_missing_config_cluster_url(self, monkeypatch): """Test that tools handle missing configuration.""" # Directly modify the server.config object original_cluster_url = server.config.cluster_url original_database = server.config.database try: # Set empty values for testing server.config.cluster_url = "" server.config.database = "" with pytest.raises(ValueError) as excinfo: await execute_query("test query") assert "Azure Data Explorer configuration is missing" in str(excinfo.value) finally: # Restore original values server.config.cluster_url = original_cluster_url server.config.database = original_database @pytest.mark.asyncio @patch('adx_mcp_server.server.DefaultAzureCredential') @patch('adx_mcp_server.server.KustoConnectionStringBuilder.with_azure_token_credential') async def test_token_credential_error(self, mock_kcsb, mock_credential, monkeypatch): """Test that get_kusto_client handles token credential errors.""" # Make sure we have valid cluster and database original_cluster_url = server.config.cluster_url original_database = server.config.database try: server.config.cluster_url = "https://testcluster.region.kusto.windows.net" server.config.database = "testdb" # Set up the mocks to simulate a token credential error mock_credential.side_effect = Exception("Token credential error") with pytest.raises(Exception) as excinfo: await execute_query("test query") # Verify the error was from the credential assert "Token credential error" in str(excinfo.value) # Verify DefaultAzureCredential was attempted mock_credential.assert_called_once() # Verify KustoConnectionStringBuilder.with_azure_token_credential was NOT called # since the credential creation failed mock_kcsb.assert_not_called() finally: # Restore original values server.config.cluster_url = original_cluster_url server.config.database = original_database def test_format_query_results_empty(self): """Test that format_query_results handles empty results.""" mock_result_set = MagicMock() mock_result_set.primary_results = [] result = server.format_query_results(mock_result_set) assert result == [] # Test with None result = server.format_query_results(None) assert result == [] class TestTransportConfiguration: def test_transport_type_enum_values(self): """Test TransportType enum values.""" from adx_mcp_server.server import TransportType assert TransportType.STDIO == "stdio" assert TransportType.HTTP == "http" assert TransportType.SSE == "sse" assert TransportType.values() == ["stdio", "http", "sse"] def test_mcp_server_config_validation(self): """Test MCPServerConfig validation.""" from adx_mcp_server.server import MCPServerConfig # Valid configuration config = MCPServerConfig( mcp_server_transport="http", mcp_bind_host="localhost", mcp_bind_port=8080 ) assert config.mcp_server_transport == "http" assert config.mcp_bind_host == "localhost" assert config.mcp_bind_port == 8080 def test_mcp_server_config_validation_failures(self): """Test MCPServerConfig validation failures.""" from adx_mcp_server.server import MCPServerConfig # Missing transport with pytest.raises(ValueError, match="MCP SERVER TRANSPORT is required"): MCPServerConfig( mcp_server_transport=None, mcp_bind_host="localhost", mcp_bind_port=8080 ) # Missing host with pytest.raises(ValueError, match="MCP BIND HOST is required"): MCPServerConfig( mcp_server_transport="http", mcp_bind_host=None, mcp_bind_port=8080 ) # Missing port with pytest.raises(ValueError, match="MCP BIND PORT is required"): MCPServerConfig( mcp_server_transport="http", mcp_bind_host="localhost", mcp_bind_port=None ) def test_adx_config_with_mcp_server_config(self): """Test ADXConfig with MCP server configuration.""" from adx_mcp_server.server import ADXConfig, MCPServerConfig mcp_config = MCPServerConfig( mcp_server_transport="sse", mcp_bind_host="0.0.0.0", mcp_bind_port=3000 ) adx_config = ADXConfig( cluster_url="https://test.kusto.windows.net", database="testdb", mcp_server_config=mcp_config ) assert adx_config.cluster_url == "https://test.kusto.windows.net" assert adx_config.database == "testdb" assert adx_config.mcp_server_config.mcp_server_transport == "sse" assert adx_config.mcp_server_config.mcp_bind_host == "0.0.0.0" assert adx_config.mcp_server_config.mcp_bind_port == 3000

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pab1it0/adx-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server