Skip to main content
Glama
moimran
by moimran
conftest.py9.38 kB
""" Pytest configuration and fixtures for EVE-NG MCP Server tests """ import asyncio import json import os import pytest from pathlib import Path from typing import Dict, Any, Optional from unittest.mock import Mock, AsyncMock # Add project root to Python path import sys project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from eveng_mcp_server.client import EVENGClient from eveng_mcp_server.config.settings import Settings def pytest_addoption(parser): """Add custom command line options""" parser.addoption( "--eveng-host", action="store", default="eve.local", help="EVE-NG server host" ) parser.addoption( "--eveng-user", action="store", default="admin", help="EVE-NG username" ) parser.addoption( "--eveng-pass", action="store", default="eve", help="EVE-NG password" ) parser.addoption( "--eveng-port", action="store", default=80, type=int, help="EVE-NG port" ) parser.addoption( "--eveng-protocol", action="store", default="http", help="EVE-NG protocol" ) def pytest_configure(config): """Configure pytest""" # Add custom markers config.addinivalue_line( "markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')" ) config.addinivalue_line( "markers", "integration: marks tests as integration tests" ) config.addinivalue_line( "markers", "e2e: marks tests as end-to-end tests" ) config.addinivalue_line( "markers", "performance: marks tests as performance tests" ) @pytest.fixture(scope="session") def event_loop(): """Create an instance of the default event loop for the test session.""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest.fixture(scope="session") def test_config(pytestconfig): """Test configuration from command line options""" return { "eveng": { "host": pytestconfig.getoption("--eveng-host"), "username": pytestconfig.getoption("--eveng-user"), "password": pytestconfig.getoption("--eveng-pass"), "port": pytestconfig.getoption("--eveng-port"), "protocol": pytestconfig.getoption("--eveng-protocol"), "timeout": 30, "max_retries": 3 }, "test": { "cleanup": True, "timeout": 60, "lab_prefix": "test_", "node_prefix": "test_node_" } } @pytest.fixture def mock_eveng_client(): """Mock EVE-NG client for unit tests""" client = Mock(spec=EVENGClient) client.connect = AsyncMock(return_value=True) client.disconnect = AsyncMock(return_value=True) client.test_connection = AsyncMock(return_value=True) client.get_server_info = AsyncMock(return_value={ "version": "6.2.0-4", "qemu_version": "2.4.0", "ksm": "enabled" }) client.list_labs = AsyncMock(return_value={}) client.create_lab = AsyncMock(return_value={"success": True}) client.get_lab_details = AsyncMock(return_value={ "name": "test_lab", "description": "Test lab", "author": "Test", "version": "1.0" }) client.delete_lab = AsyncMock(return_value={"success": True}) return client @pytest.fixture def sample_lab_config(): """Sample lab configuration for testing""" return { "name": "test_lab", "description": "Test lab for unit tests", "author": "Test Suite", "version": "1.0", "path": "/" } @pytest.fixture def sample_node_config(): """Sample node configuration for testing""" return { "template": "vios", "name": "test_router", "left": 25, "top": 25, "ram": 512, "ethernet": 4, "delay": 0, "console": "telnet" } @pytest.fixture def sample_network_config(): """Sample network configuration for testing""" return { "network_type": "bridge", "name": "test_network", "left": 50, "top": 75 } @pytest.fixture def mock_eveng_responses(): """Mock EVE-NG API responses""" return { "login": { "status": "success", "data": { "message": "User logged in" } }, "status": { "status": "success", "data": { "version": "6.2.0-4", "qemu_version": "2.4.0", "ksm": "enabled", "cpu": "Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz", "memory": "32GB" } }, "labs": { "status": "success", "data": {} }, "templates": { "status": "success", "data": { "vios": { "name": "Cisco vIOS", "type": "qemu", "ethernet": 16, "ram": 512, "cpu": 1 }, "linux": { "name": "Linux", "type": "qemu", "ethernet": 4, "ram": 256, "cpu": 1 } } }, "create_lab": { "status": "success", "data": { "message": "Lab created successfully" } }, "lab_details": { "status": "success", "data": { "name": "test_lab", "description": "Test lab", "author": "Test", "version": "1.0", "nodes": {}, "networks": {} } } } @pytest.fixture async def eveng_client(test_config): """Real EVE-NG client for integration tests""" client = EVENGClient() # Only connect if we're running integration tests if os.environ.get('PYTEST_CURRENT_TEST', '').find('integration') != -1: try: await client.connect( host=test_config["eveng"]["host"], username=test_config["eveng"]["username"], password=test_config["eveng"]["password"], port=test_config["eveng"]["port"], protocol=test_config["eveng"]["protocol"] ) except Exception: pytest.skip("EVE-NG server not available") yield client # Cleanup try: await client.disconnect() except Exception: pass @pytest.fixture def test_lab_name(): """Generate unique test lab name""" import uuid return f"test_lab_{uuid.uuid4().hex[:8]}" @pytest.fixture def test_node_name(): """Generate unique test node name""" import uuid return f"test_node_{uuid.uuid4().hex[:8]}" @pytest.fixture def test_network_name(): """Generate unique test network name""" import uuid return f"test_net_{uuid.uuid4().hex[:8]}" @pytest.fixture(autouse=True) def setup_test_environment(): """Setup test environment variables""" original_env = os.environ.copy() # Set test environment variables os.environ['TESTING'] = 'true' os.environ['LOG_LEVEL'] = 'DEBUG' os.environ['EVENG_SSL_VERIFY'] = 'false' yield # Restore original environment os.environ.clear() os.environ.update(original_env) @pytest.fixture def temp_lab_cleanup(eveng_client, test_config): """Cleanup test labs after test completion""" created_labs = [] def register_lab(lab_path: str): created_labs.append(lab_path) yield register_lab # Cleanup created labs if test_config["test"]["cleanup"]: for lab_path in created_labs: try: asyncio.run(eveng_client.delete_lab(lab_path)) except Exception: pass # Ignore cleanup errors @pytest.fixture def performance_timer(): """Timer for performance tests""" import time class Timer: def __init__(self): self.start_time = None self.end_time = None def start(self): self.start_time = time.time() def stop(self): self.end_time = time.time() @property def duration(self): if self.start_time and self.end_time: return self.end_time - self.start_time return None return Timer() @pytest.fixture def test_data_dir(): """Path to test data directory""" return Path(__file__).parent / "fixtures" @pytest.fixture def load_test_data(test_data_dir): """Load test data from JSON files""" def _load(filename: str) -> Dict[str, Any]: file_path = test_data_dir / filename if file_path.exists(): with open(file_path, 'r') as f: return json.load(f) return {} return _load # Async fixtures for async tests @pytest.fixture async def async_mock_eveng_client(): """Async mock EVE-NG client""" client = AsyncMock(spec=EVENGClient) client.connect.return_value = True client.disconnect.return_value = True client.test_connection.return_value = True return client

Latest Blog Posts

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/moimran/eveng-mcp'

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