Skip to main content
Glama

MCP Server for Odoo

by ivnvxd
Mozilla Public License 2.0
88
  • Apple
  • Linux
conftest.py•6.32 kB
"""Pytest configuration and fixtures for Odoo MCP Server tests.""" import os import socket import xmlrpc.client import pytest from dotenv import load_dotenv from mcp_server_odoo.config import OdooConfig # Load .env file for tests load_dotenv() # Import model discovery helper try: from tests.helpers.model_discovery import ModelDiscovery MODEL_DISCOVERY_AVAILABLE = True except ImportError: MODEL_DISCOVERY_AVAILABLE = False def is_odoo_server_available(host: str = "localhost", port: int = 8069) -> bool: """Check if Odoo server is available at the given host and port.""" try: # Try to connect to the server sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) result = sock.connect_ex((host, port)) sock.close() if result != 0: return False # Try to access the XML-RPC endpoint try: proxy = xmlrpc.client.ServerProxy(f"http://{host}:{port}/xmlrpc/2/common") proxy.version() return True except Exception: return False except Exception: return False # Global flag for Odoo server availability ODOO_SERVER_AVAILABLE = is_odoo_server_available() def pytest_configure(config): """Configure pytest with custom markers.""" config.addinivalue_line( "markers", "odoo_required: mark test as requiring a running Odoo server" ) def pytest_collection_modifyitems(config, items): """Modify test collection to skip tests that require Odoo when it's not available.""" if ODOO_SERVER_AVAILABLE: # Server is available, don't skip anything return skip_odoo = pytest.mark.skip(reason="Odoo server not available at localhost:8069") for item in items: # Skip tests marked with 'integration' when server is not available if "integration" in item.keywords: item.add_marker(skip_odoo) # Skip tests marked with 'odoo_required' when server is not available if "odoo_required" in item.keywords: item.add_marker(skip_odoo) # Also check for specific test names that indicate they need a real server test_name = item.name.lower() if any(keyword in test_name for keyword in ["real_server", "integration"]): item.add_marker(skip_odoo) @pytest.fixture(autouse=True) def rate_limit_delay(request): """Add a delay between tests to avoid rate limiting (only when needed).""" # Add delay BEFORE integration tests that hit the real server test_name = request.node.name.lower() if hasattr(request.node, "name") else "" class_name = request.cls.__name__ if request.cls else "" # Check if this is an integration test that needs rate limit protection if ( "integration" in request.keywords or "Integration" in class_name or "integration" in test_name or "real_" in test_name ): import time time.sleep(2.0) # 2 second delay BEFORE integration tests to avoid rate limiting yield @pytest.fixture def odoo_server_required(): """Fixture that skips test if Odoo server is not available.""" if not ODOO_SERVER_AVAILABLE: pytest.skip("Odoo server not available at localhost:8069") @pytest.fixture def handle_rate_limit(): """Fixture that handles rate limiting errors gracefully.""" import urllib.error try: yield except Exception as e: # Check if this is a rate limit error if isinstance(e, urllib.error.HTTPError) and e.code == 429: pytest.skip("Skipping due to rate limiting") elif "429" in str(e) or "TOO MANY REQUESTS" in str(e): pytest.skip("Skipping due to rate limiting") else: raise @pytest.fixture def test_config_with_server_check(odoo_server_required) -> OdooConfig: """Create test configuration, but skip if server not available.""" # Require environment variables to be set if not os.getenv("ODOO_URL"): pytest.skip("ODOO_URL environment variable not set. Please configure .env file.") if not os.getenv("ODOO_API_KEY"): pytest.skip("ODOO_API_KEY environment variable not set. Please configure .env file.") return OdooConfig( url=os.getenv("ODOO_URL"), api_key=os.getenv("ODOO_API_KEY"), database=os.getenv("ODOO_DB"), # DB can be auto-detected log_level=os.getenv("ODOO_MCP_LOG_LEVEL", "INFO"), default_limit=int(os.getenv("ODOO_MCP_DEFAULT_LIMIT", "10")), max_limit=int(os.getenv("ODOO_MCP_MAX_LIMIT", "100")), ) # MCP Model Discovery Fixtures # These fixtures help make tests model-agnostic by discovering # and adapting to whatever models are currently available @pytest.fixture def model_discovery(): """Create a model discovery helper. Creates a fresh discovery instance for each test. """ if not MODEL_DISCOVERY_AVAILABLE: pytest.skip("Model Discovery not available") if not ODOO_SERVER_AVAILABLE: pytest.skip("Odoo server not available") # Create config for discovery config = OdooConfig( url=os.getenv("ODOO_URL"), api_key=os.getenv("ODOO_API_KEY"), database=os.getenv("ODOO_DB"), ) discovery = ModelDiscovery(config) return discovery @pytest.fixture def readable_model(model_discovery): """Get a model with read permission. Skips test if no readable models are available. """ return model_discovery.require_readable_model() @pytest.fixture def writable_model(model_discovery): """Get a model with write permission. Skips test if no writable models are available. """ return model_discovery.require_writable_model() @pytest.fixture def disabled_model(model_discovery): """Get a model name that is NOT enabled. Returns a model that should fail access checks. """ return model_discovery.get_disabled_model() @pytest.fixture def test_models(model_discovery): """Get commonly available models for testing. Returns a list of models that are commonly enabled, or skips if none are available. """ models = model_discovery.get_common_models() if not models: models = [model_discovery.require_readable_model()] return models

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/ivnvxd/mcp-server-odoo'

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