Skip to main content
Glama

mcp-server-pacman

MIT License
7
  • Linux
  • Apple
test_dockerhub.py9.62 kB
"""Tests for Docker Hub provider functions.""" import unittest from unittest.mock import patch, MagicMock, AsyncMock from src.mcp_server_pacman.providers.dockerhub import ( search_docker_hub, get_docker_hub_tags, get_docker_hub_tag_info, ) from mcp.shared.exceptions import McpError from mcp.types import INTERNAL_ERROR from tests.utils.test_utils import async_test # Disable caching for tests import src.mcp_server_pacman.utils.cache src.mcp_server_pacman.utils.cache.ENABLE_CACHE = False class TestDockerHubFunctions(unittest.TestCase): """Tests for Docker Hub search and info functions.""" @patch("httpx.AsyncClient") @async_test async def test_search_docker_hub_success(self, mock_client): # Setup mock mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { "results": [ { "repo_name": "nginx", "description": "Official NGINX image", "star_count": 15000, "pull_count": 10000000, "is_official": True, "last_updated": "2022-10-01T00:00:00Z", }, { "repo_name": "nginxinc/nginx-unprivileged", "description": "Unprivileged NGINX image", "star_count": 100, "pull_count": 10000, "is_official": False, "last_updated": "2022-09-15T00:00:00Z", }, ] } mock_client_instance = AsyncMock() mock_client_instance.get.return_value = mock_response mock_client.return_value.__aenter__.return_value = mock_client_instance # Execute function results = await search_docker_hub("nginx", 2) # Verify calls and results mock_client_instance.get.assert_called_once_with( "https://hub.docker.com/v2/search/repositories", params={"query": "nginx", "page_size": 2}, headers={ "Accept": "application/json", "User-Agent": "ModelContextProtocol/1.0 Pacman (+https://github.com/modelcontextprotocol/servers)", }, follow_redirects=True, ) self.assertEqual(len(results), 2) self.assertEqual(results[0]["name"], "nginx") self.assertEqual(results[0]["is_official"], True) self.assertEqual(results[1]["name"], "nginxinc/nginx-unprivileged") @patch("httpx.AsyncClient") @async_test async def test_search_docker_hub_error_status(self, mock_client): # Setup mock for error status mock_response = MagicMock() mock_response.status_code = 500 mock_client_instance = AsyncMock() mock_client_instance.get.return_value = mock_response mock_client.return_value.__aenter__.return_value = mock_client_instance # Execute and check for exception with self.assertRaises(McpError) as context: await search_docker_hub("nginx", 2) # Verify API call was made with the updated URL mock_client_instance.get.assert_called_once_with( "https://hub.docker.com/v2/search/repositories", params={"query": "nginx", "page_size": 2}, headers={ "Accept": "application/json", "User-Agent": "ModelContextProtocol/1.0 Pacman (+https://github.com/modelcontextprotocol/servers)", }, follow_redirects=True, ) self.assertEqual(context.exception.error.code, INTERNAL_ERROR) self.assertIn("Failed to search Docker Hub", context.exception.error.message) @patch("httpx.AsyncClient") @async_test async def test_get_docker_hub_tags_success(self, mock_client): # Setup mocks for both API calls (tags and repository info) tags_response = MagicMock() tags_response.status_code = 200 tags_response.json.return_value = { "count": 2, "results": [ { "name": "latest", "last_updated": "2022-10-01T00:00:00Z", "digest": "sha256:123", "images": [ { "architecture": "amd64", "os": "linux", "size": 100000000, } ], }, { "name": "1.25.0", "last_updated": "2022-09-15T00:00:00Z", "digest": "sha256:456", "images": [ { "architecture": "amd64", "os": "linux", "size": 90000000, } ], }, ], } repo_response = MagicMock() repo_response.status_code = 200 repo_response.json.return_value = { "description": "Official NGINX image", "star_count": 15000, "pull_count": 10000000, "is_official": True, "last_updated": "2022-10-01T00:00:00Z", } mock_client_instance = AsyncMock() # Configure the mock to return different responses for different calls mock_client_instance.get.side_effect = [tags_response, repo_response] mock_client.return_value.__aenter__.return_value = mock_client_instance # Execute function result = await get_docker_hub_tags("nginx") # Verify calls were made (should be two calls) self.assertEqual(mock_client_instance.get.call_count, 2) # First call should be to get tags mock_client_instance.get.assert_any_call( "https://hub.docker.com/v2/repositories/library/nginx/tags", params={"page_size": 25, "ordering": "last_updated"}, headers={ "Accept": "application/json", "User-Agent": "ModelContextProtocol/1.0 Pacman (+https://github.com/modelcontextprotocol/servers)", }, follow_redirects=True, ) # Second call should be to get repo info mock_client_instance.get.assert_any_call( "https://hub.docker.com/v2/repositories/library/nginx", headers={ "Accept": "application/json", "User-Agent": "ModelContextProtocol/1.0 Pacman (+https://github.com/modelcontextprotocol/servers)", }, follow_redirects=True, ) # Verify results self.assertEqual(result["name"], "library/nginx") self.assertEqual(len(result["tags"]), 2) self.assertEqual(result["tag_count"], 2) self.assertEqual(result["tags"][0]["name"], "latest") self.assertEqual(result["tags"][1]["name"], "1.25.0") self.assertEqual(result["repository"]["is_official"], True) @patch("httpx.AsyncClient") @async_test async def test_get_docker_hub_tag_info_success(self, mock_client): # Setup mock mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { "name": "latest", "last_updated": "2022-10-01T00:00:00Z", "full_size": 100000000, "digest": "sha256:123", "images": [ { "architecture": "amd64", "os": "linux", "size": 100000000, } ], } mock_client_instance = AsyncMock() mock_client_instance.get.return_value = mock_response mock_client.return_value.__aenter__.return_value = mock_client_instance # Execute function result = await get_docker_hub_tag_info("nginx", "latest") # Verify call was made mock_client_instance.get.assert_called_once_with( "https://hub.docker.com/v2/repositories/library/nginx/tags/latest", headers={ "Accept": "application/json", "User-Agent": "ModelContextProtocol/1.0 Pacman (+https://github.com/modelcontextprotocol/servers)", }, follow_redirects=True, ) # Verify results self.assertEqual(result["name"], "library/nginx") self.assertEqual(result["tag"], "latest") self.assertEqual(result["digest"], "sha256:123") self.assertEqual(result["full_size"], 100000000) self.assertEqual(len(result["images"]), 1) self.assertEqual(result["images"][0]["architecture"], "amd64") @patch("httpx.AsyncClient") @async_test async def test_get_docker_hub_tag_info_error_status(self, mock_client): # Setup mock for error status mock_response = MagicMock() mock_response.status_code = 404 mock_client_instance = AsyncMock() mock_client_instance.get.return_value = mock_response mock_client.return_value.__aenter__.return_value = mock_client_instance # Execute and check for exception with self.assertRaises(McpError) as context: await get_docker_hub_tag_info("nonexistent-image", "latest") # Verify API call was made mock_client_instance.get.assert_called_once() self.assertEqual(context.exception.error.code, INTERNAL_ERROR) self.assertIn("Failed to get tag info", context.exception.error.message) if __name__ == "__main__": unittest.main()

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/oborchers/mcp-server-pacman'

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