Skip to main content
Glama

MCP Market Statistics Server

by whdghk1907
test_integration.pyβ€’15 kB
"""톡합 ν…ŒμŠ€νŠΈ""" import pytest from unittest.mock import AsyncMock from datetime import datetime from src.server import MarketStatsServer from src.tools.market_tools import MarketOverviewTool from src.tools.investor_tools import InvestorFlowsTool from src.tools.market_breadth_tools import MarketBreadthTool from src.tools.sector_tools import SectorAnalysisTool class TestMCPServerIntegration: """MCP μ„œλ²„ 톡합 ν…ŒμŠ€νŠΈ""" @pytest.fixture def mock_dependencies(self): """Mock μ˜μ‘΄μ„±λ“€""" mock_db = AsyncMock() mock_cache = AsyncMock() return mock_db, mock_cache @pytest.fixture def server(self, mock_dependencies): """톡합 ν…ŒμŠ€νŠΈμš© μ„œλ²„ μΈμŠ€ν„΄μŠ€""" mock_db, mock_cache = mock_dependencies # μ„œλ²„ μ„€μ • config = { "name": "market-stats-server", "version": "1.0.0", "database": {"host": "localhost", "port": 5432, "name": "test_db"}, "redis": {"host": "localhost", "port": 6379} } # μ„œλ²„ 생성 server = MarketStatsServer(config) # Mock μ˜μ‘΄μ„±λ“€μ„ 직접 μ£Όμž… server.db_manager = mock_db server.cache_manager = mock_cache # λͺ¨λ“  도ꡬ 등둝 market_tool = MarketOverviewTool(mock_db, mock_cache) investor_tool = InvestorFlowsTool(mock_db, mock_cache) breadth_tool = MarketBreadthTool(mock_db, mock_cache) sector_tool = SectorAnalysisTool(mock_db, mock_cache) server.register_tool(market_tool.name, market_tool) server.register_tool(investor_tool.name, investor_tool) server.register_tool(breadth_tool.name, breadth_tool) server.register_tool(sector_tool.name, sector_tool) return server, mock_db, mock_cache def test_all_tools_registered(self, server): """λͺ¨λ“  도ꡬ가 μ •μƒμ μœΌλ‘œ λ“±λ‘λ˜μ—ˆλŠ”μ§€ ν…ŒμŠ€νŠΈ""" server_instance, _, _ = server available_tools = server_instance.get_available_tools() tool_names = list(available_tools.keys()) expected_tools = [ "get_market_overview", "get_investor_flows", "get_market_breadth", "get_sector_analysis" ] for expected in expected_tools: assert expected in tool_names assert len(available_tools) == 4 @pytest.mark.asyncio async def test_market_overview_integration(self, server): """μ‹œμž₯ κ°œμš” 도ꡬ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server # μ„œλ²„ μ‹œμž‘ await server_instance.startup() try: # Mock 데이터 μ„€μ • mock_cache.get.return_value = None mock_db.fetch_all.return_value = [ { "index_code": "KOSPI", "current_value": 2650.50, "change": 15.30, "change_rate": 0.58, "volume": 450000000, "market_cap": 1850000000000000, "timestamp": datetime.now() } ] # 도ꡬ μ‹€ν–‰ result = await server_instance.execute_tool("get_market_overview", { "market": "KOSPI" }) # κ²°κ³Ό 검증 assert len(result) == 1 assert result[0].type == "text" # JSON 검증 import json data = json.loads(result[0].text) assert "timestamp" in data assert "indices" in data assert len(data["indices"]) == 1 assert data["indices"][0]["index_code"] == "KOSPI" finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_investor_flows_integration(self, server): """투자자 동ν–₯ 도ꡬ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # Mock 데이터 μ„€μ • mock_cache.get.return_value = None mock_db.fetch_all.return_value = [ { "date": datetime.now().date(), "investor_type": "개인", "buy_amount": 1500000000000, "sell_amount": 1200000000000, "net_amount": 300000000000, "market": "KOSPI" } ] # 도ꡬ μ‹€ν–‰ result = await server_instance.execute_tool("get_investor_flows", { "market": "KOSPI", "period": "1d" }) # κ²°κ³Ό 검증 assert len(result) == 1 import json data = json.loads(result[0].text) assert "flows" in data assert "summary" in data assert len(data["flows"]) == 1 assert data["flows"][0]["investor_type"] == "개인" finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_market_breadth_integration(self, server): """μ‹œμž₯ 폭 μ§€ν‘œ 도ꡬ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # Mock 데이터 μ„€μ • mock_cache.get.return_value = None mock_db.fetch_all.return_value = [ { "date": datetime.now().date(), "market": "KOSPI", "advancing": 850, "declining": 680, "unchanged": 120, "total_issues": 1650, "advance_decline_ratio": 1.25, "advance_volume": 2800000000000, "decline_volume": 1900000000000, "timestamp": datetime.now() } ] # 도ꡬ μ‹€ν–‰ result = await server_instance.execute_tool("get_market_breadth", { "market": "KOSPI", "period": "1d" }) # κ²°κ³Ό 검증 assert len(result) == 1 import json data = json.loads(result[0].text) assert "breadth_data" in data assert "summary" in data assert len(data["breadth_data"]) == 1 assert data["breadth_data"][0]["advancing"] == 850 finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_sector_analysis_integration(self, server): """μ„Ήν„° 뢄석 도ꡬ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # Mock 데이터 μ„€μ • mock_cache.get.return_value = None mock_db.fetch_all.return_value = [ { "sector_name": "IT", "sector_code": "IT001", "market_cap": 450000000000000, "total_volume": 280000000000, "change_rate": 2.35, "advancing_stocks": 85, "declining_stocks": 45, "unchanged_stocks": 12, "total_stocks": 142, "top_performer": "μ‚Όμ„±μ „μž", "top_performer_change": 3.8, "worst_performer": "LGμœ ν”ŒλŸ¬μŠ€", "worst_performer_change": -2.1, "date": datetime.now().date(), "timestamp": datetime.now() } ] # 도ꡬ μ‹€ν–‰ result = await server_instance.execute_tool("get_sector_analysis", { "market": "ALL", "sector": "ALL" }) # κ²°κ³Ό 검증 assert len(result) == 1 import json data = json.loads(result[0].text) assert "sector_analysis" in data assert "market_summary" in data assert len(data["sector_analysis"]) == 1 assert data["sector_analysis"][0]["sector_name"] == "IT" finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_sequential_tool_execution(self, server): """μ—¬λŸ¬ 도ꡬ 순차 μ‹€ν–‰ ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # λͺ¨λ“  도ꡬ에 λŒ€ν•œ Mock 데이터 μ„€μ • mock_cache.get.return_value = None mock_db.fetch_all.side_effect = [ # μ‹œμž₯ κ°œμš” 데이터 [{"index_code": "KOSPI", "current_value": 2650.50, "change": 15.30, "change_rate": 0.58, "volume": 450000000, "market_cap": 1850000000000000, "timestamp": datetime.now()}], # 투자자 동ν–₯ 데이터 [{"date": datetime.now().date(), "investor_type": "개인", "buy_amount": 1500000000000, "sell_amount": 1200000000000, "net_amount": 300000000000, "market": "KOSPI"}], # μ‹œμž₯ 폭 데이터 [{"date": datetime.now().date(), "market": "KOSPI", "advancing": 850, "declining": 680, "unchanged": 120, "total_issues": 1650, "advance_decline_ratio": 1.25, "advance_volume": 2800000000000, "decline_volume": 1900000000000, "timestamp": datetime.now()}], # μ„Ήν„° 뢄석 데이터 [{"sector_name": "IT", "sector_code": "IT001", "market_cap": 450000000000000, "total_volume": 280000000000, "change_rate": 2.35, "advancing_stocks": 85, "declining_stocks": 45, "unchanged_stocks": 12, "total_stocks": 142, "top_performer": "μ‚Όμ„±μ „μž", "top_performer_change": 3.8, "worst_performer": "LGμœ ν”ŒλŸ¬μŠ€", "worst_performer_change": -2.1, "date": datetime.now().date(), "timestamp": datetime.now()}] ] # 순차적으둜 λͺ¨λ“  도ꡬ μ‹€ν–‰ tools = [ ("get_market_overview", {"market": "KOSPI"}), ("get_investor_flows", {"market": "KOSPI", "period": "1d"}), ("get_market_breadth", {"market": "KOSPI", "period": "1d"}), ("get_sector_analysis", {"market": "ALL", "sector": "ALL"}) ] results = [] for tool_name, args in tools: result = await server_instance.execute_tool(tool_name, args) results.append(result) # λͺ¨λ“  κ²°κ³Ό 검증 assert len(results) == 4 for result in results: assert len(result) == 1 assert result[0].type == "text" # JSON νŒŒμ‹± κ°€λŠ₯ν•œμ§€ 확인 import json data = json.loads(result[0].text) assert "timestamp" in data finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_error_handling_integration(self, server): """μ—λŸ¬ 처리 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 도ꡬ 호좜 with pytest.raises(KeyError): await server_instance.execute_tool("nonexistent_tool", {}) # 도ꡬ μ‹€ν–‰ 쀑 μ—λŸ¬ mock_cache.get.return_value = None mock_db.fetch_all.side_effect = Exception("Database error") with pytest.raises(Exception): await server_instance.execute_tool("get_market_overview", {"market": "KOSPI"}) finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_cache_integration(self, server): """μΊμ‹œ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # μΊμ‹œ 히트 μ‹œλ‚˜λ¦¬μ˜€ cached_data = { "timestamp": datetime.now().isoformat(), "market_summary": {"total_market_cap": 2000000000000000}, "indices": [{"index_code": "KOSPI", "current_value": 2650.50}] } mock_cache.get.return_value = cached_data # 도ꡬ μ‹€ν–‰ result = await server_instance.execute_tool("get_market_overview", {"market": "KOSPI"}) # μΊμ‹œ 데이터 λ°˜ν™˜ 확인 import json data = json.loads(result[0].text) assert data == cached_data # λ°μ΄ν„°λ² μ΄μŠ€ 호좜이 μ—†μ—ˆλŠ”μ§€ 확인 mock_db.fetch_all.assert_not_called() finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_health_check_integration(self, server): """ν—¬μŠ€μ²΄ν¬ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server await server_instance.startup() try: # 성곡 μ‹œλ‚˜λ¦¬μ˜€ mock_db.health_check.return_value = True mock_cache.health_check.return_value = True health_status = await server_instance.health_check() assert health_status["status"] == "healthy" assert health_status["database"] == "connected" assert health_status["cache"] == "connected" # DB μ‹€νŒ¨ μ‹œλ‚˜λ¦¬μ˜€ mock_db.health_check.return_value = False health_status = await server_instance.health_check() assert health_status["status"] == "unhealthy" finally: await server_instance.shutdown() @pytest.mark.asyncio async def test_server_startup_shutdown_integration(self, server): """μ„œλ²„ μ‹œμž‘/μ’…λ£Œ 톡합 ν…ŒμŠ€νŠΈ""" server_instance, mock_db, mock_cache = server # 초기 μƒνƒœ 확인 assert server_instance.is_running is False # μ‹œμž‘ await server_instance.startup() assert server_instance.is_running is True # μ’…λ£Œ await server_instance.shutdown() assert server_instance.is_running is False # μž¬μ‹œμž‘ ν…ŒμŠ€νŠΈ await server_instance.startup() assert server_instance.is_running is True await server_instance.shutdown() assert server_instance.is_running is False

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/whdghk1907/mcp-market-statistics'

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