Skip to main content
Glama

StarTree MCP Server for Apache Pinot

Official
by startreedata
Apache 2.0
12
  • Apple
  • Linux
test_config.py29.9 kB
import os import tempfile from unittest.mock import patch from mcp_pinot.config import ( OAuthConfig, ServerConfig, _parse_broker_url, _read_token_from_file, load_oauth_config, load_pinot_config, load_server_config, ) class TestParseBrokerUrl: """Test the _parse_broker_url function""" def test_parse_full_url(self): """Test parsing a full URL with all components""" host, port, scheme = _parse_broker_url("https://broker.example.com:8443") assert host == "broker.example.com" assert port == 8443 assert scheme == "https" def test_parse_url_without_port(self): """Test parsing URL without explicit port uses defaults""" host, port, scheme = _parse_broker_url("https://broker.example.com") assert host == "broker.example.com" assert port == 443 # Default for https assert scheme == "https" host, port, scheme = _parse_broker_url("http://broker.example.com") assert host == "broker.example.com" assert port == 80 # Default for http assert scheme == "http" def test_parse_localhost_url(self): """Test parsing localhost URLs""" host, port, scheme = _parse_broker_url("http://localhost:8099") assert host == "localhost" assert port == 8099 assert scheme == "http" def test_parse_invalid_url(self): """Test parsing invalid URL falls back to defaults""" host, port, scheme = _parse_broker_url("invalid-url") assert host == "localhost" assert port == 80 assert scheme == "http" def test_parse_url_with_path(self): """Test parsing URL with path ignores the path""" host, port, scheme = _parse_broker_url( "https://broker.example.com:8443/some/path" ) assert host == "broker.example.com" assert port == 8443 assert scheme == "https" class TestLoadPinotConfig: """Test the load_pinot_config function""" def test_individual_configs_only(self): """Test loading config with only individual broker configs""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_HOST": "broker.example.com", "PINOT_BROKER_PORT": "8099", "PINOT_BROKER_SCHEME": "http", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_host == "broker.example.com" assert config.broker_port == 8099 assert config.broker_scheme == "http" def test_broker_url_only(self): """Test loading config with only PINOT_BROKER_URL""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_URL": "https://broker.example.com:8443", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_host == "broker.example.com" assert config.broker_port == 8443 assert config.broker_scheme == "https" def test_broker_url_with_individual_overrides(self): """Test that individual configs override URL values""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_URL": "https://broker.example.com:8443", "PINOT_BROKER_HOST": "override.example.com", "PINOT_BROKER_PORT": "9000", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_host == "override.example.com" assert config.broker_port == 9000 assert config.broker_scheme == "https" # From URL, not overridden def test_broker_url_with_scheme_override(self): """Test that PINOT_BROKER_SCHEME overrides URL scheme""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_URL": "https://broker.example.com:8443", "PINOT_BROKER_SCHEME": "http", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_host == "broker.example.com" assert config.broker_port == 8443 assert config.broker_scheme == "http" # Overridden def test_no_broker_config(self): """Test default values when no broker config is provided""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.controller_url == "http://controller:9000" assert config.broker_host == "localhost" assert config.broker_port == 8000 assert config.broker_scheme == "http" def test_quickstart_defaults(self): """Test that quickstart defaults are used when no config is provided""" env_vars = {} # No config at all with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.controller_url == "http://localhost:9000" assert config.broker_host == "localhost" assert config.broker_port == 8000 assert config.broker_scheme == "http" def test_broker_url_default_ports(self): """Test that URL parsing uses correct default ports""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_URL": "http://broker.example.com", # No port specified } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_host == "broker.example.com" assert config.broker_port == 80 # Default for http assert config.broker_scheme == "http" # Test HTTPS default env_vars["PINOT_BROKER_URL"] = "https://broker.example.com" with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.broker_port == 443 # Default for https def test_all_config_fields_present(self): """Test that all expected config fields are present""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_BROKER_URL": "https://broker.example.com:8443", "PINOT_USERNAME": "testuser", "PINOT_PASSWORD": "testpass", "PINOT_TOKEN": "testtoken", "PINOT_DATABASE": "testdb", "PINOT_USE_MSQE": "true", "PINOT_REQUEST_TIMEOUT": "30", "PINOT_CONNECTION_TIMEOUT": "20", "PINOT_QUERY_TIMEOUT": "40", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.controller_url == "http://controller:9000" assert config.broker_host == "broker.example.com" assert config.broker_port == 8443 assert config.broker_scheme == "https" assert config.username == "testuser" assert config.password == "testpass" # noqa: S105 assert config.token == "testtoken" # noqa: S105 assert config.database == "testdb" assert config.use_msqe is True assert config.request_timeout == 30 assert config.connection_timeout == 20 assert config.query_timeout == 40 class TestServerConfig: """Test the ServerConfig class and load_server_config function""" def test_server_config_defaults(self): """Test ServerConfig default values""" config = ServerConfig() assert config.transport == "http" assert config.host == "0.0.0.0" assert config.port == 8080 assert config.ssl_keyfile is None assert config.ssl_certfile is None assert config.oauth_enabled is False def test_server_config_custom_values(self): """Test ServerConfig with custom values""" config = ServerConfig( transport="http", host="127.0.0.1", port=9090, ssl_keyfile="/path/to/key.pem", ssl_certfile="/path/to/cert.pem", oauth_enabled=True, ) assert config.transport == "http" assert config.host == "127.0.0.1" assert config.port == 9090 assert config.ssl_keyfile == "/path/to/key.pem" assert config.ssl_certfile == "/path/to/cert.pem" assert config.oauth_enabled is True class TestLoadServerConfig: """Test the load_server_config function""" def test_load_server_config_defaults(self): """Test loading server config with default values""" with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, {}, clear=True): config = load_server_config() assert config.transport == "http" assert config.host == "0.0.0.0" assert config.port == 8080 assert config.ssl_keyfile is None assert config.ssl_certfile is None assert config.oauth_enabled is False def test_load_server_config_from_env(self): """Test loading server config from environment variables""" env_vars = { "MCP_TRANSPORT": "http", "MCP_HOST": "192.168.1.100", "MCP_PORT": "9999", "MCP_SSL_KEYFILE": "/etc/ssl/private/server.key", "MCP_SSL_CERTFILE": "/etc/ssl/certs/server.crt", "OAUTH_ENABLED": "true", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_server_config() assert config.transport == "http" assert config.host == "192.168.1.100" assert config.port == 9999 assert config.ssl_keyfile == "/etc/ssl/private/server.key" assert config.ssl_certfile == "/etc/ssl/certs/server.crt" assert config.oauth_enabled is True def test_load_server_config_transport_case_insensitive(self): """Test that transport value is converted to lowercase""" env_vars = {"MCP_TRANSPORT": "HTTP"} with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_server_config() assert config.transport == "http" def test_load_server_config_partial_env(self): """Test loading server config with only some env vars set""" env_vars = {"MCP_TRANSPORT": "http", "MCP_PORT": "3000"} with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_server_config() assert config.transport == "http" assert config.host == "0.0.0.0" # default assert config.port == 3000 assert config.ssl_keyfile is None # default assert config.ssl_certfile is None # default assert config.oauth_enabled is False # default def test_load_server_config_invalid_port(self): """Test that invalid port values raise ValueError""" env_vars = {"MCP_PORT": "not_a_number"} with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): try: load_server_config() assert False, "Should have raised ValueError for invalid port" except ValueError: pass # Expected behavior def test_load_server_config_oauth_enabled(self): """Test loading server config with OAuth enabled""" env_vars = {"OAUTH_ENABLED": "true"} with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_server_config() assert config.oauth_enabled is True def test_load_server_config_all_transport_types(self): """Test all valid transport types""" for transport in ["stdio", "http", "streamable-http"]: env_vars = {"MCP_TRANSPORT": transport} with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_server_config() assert config.transport == transport class TestOAuthConfig: """Test the OAuthConfig class and load_oauth_config function""" def test_oauth_config_defaults(self): """Test OAuthConfig default values""" config = OAuthConfig( client_id="test_client", client_secret="test_secret", base_url="http://localhost:8000", upstream_authorization_endpoint="http://auth.example.com/authorize", upstream_token_endpoint="http://auth.example.com/token", jwks_uri="http://auth.example.com/.well-known/jwks.json", issuer="http://auth.example.com", ) assert config.client_id == "test_client" assert config.client_secret == "test_secret" assert config.base_url == "http://localhost:8000" assert ( config.upstream_authorization_endpoint == "http://auth.example.com/authorize" ) assert config.upstream_token_endpoint == "http://auth.example.com/token" assert config.jwks_uri == "http://auth.example.com/.well-known/jwks.json" assert config.issuer == "http://auth.example.com" assert config.audience is None assert config.extra_authorize_params is None def test_oauth_config_with_audience(self): """Test OAuthConfig with audience""" config = OAuthConfig( client_id="test_client", client_secret="test_secret", base_url="http://localhost:8000", upstream_authorization_endpoint="http://auth.example.com/authorize", upstream_token_endpoint="http://auth.example.com/token", jwks_uri="http://auth.example.com/.well-known/jwks.json", issuer="http://auth.example.com", audience="test_audience", ) assert config.audience == "test_audience" def test_oauth_config_with_extra_params(self): """Test OAuthConfig with extra authorization parameters""" extra_params = {"scope": "read write", "response_type": "code"} config = OAuthConfig( client_id="test_client", client_secret="test_secret", base_url="http://localhost:8000", upstream_authorization_endpoint="http://auth.example.com/authorize", upstream_token_endpoint="http://auth.example.com/token", jwks_uri="http://auth.example.com/.well-known/jwks.json", issuer="http://auth.example.com", extra_authorize_params=extra_params, ) assert config.extra_authorize_params == extra_params class TestLoadOAuthConfig: """Test the load_oauth_config function""" def test_load_oauth_config_defaults(self): """Test loading OAuth config with default values""" env_vars = { "OAUTH_CLIENT_ID": "test_client", "OAUTH_CLIENT_SECRET": "test_secret", "OAUTH_BASE_URL": "http://localhost:8000", "OAUTH_AUTHORIZATION_ENDPOINT": "http://auth.example.com/authorize", "OAUTH_TOKEN_ENDPOINT": "http://auth.example.com/token", "OAUTH_JWKS_URI": "http://auth.example.com/.well-known/jwks.json", "OAUTH_ISSUER": "http://auth.example.com", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_oauth_config() assert config.client_id == "test_client" assert config.client_secret == "test_secret" assert config.base_url == "http://localhost:8000" assert ( config.upstream_authorization_endpoint == "http://auth.example.com/authorize" ) assert config.upstream_token_endpoint == "http://auth.example.com/token" assert ( config.jwks_uri == "http://auth.example.com/.well-known/jwks.json" ) assert config.issuer == "http://auth.example.com" assert config.audience is None assert config.extra_authorize_params is None def test_load_oauth_config_with_audience(self): """Test loading OAuth config with audience""" env_vars = { "OAUTH_CLIENT_ID": "test_client", "OAUTH_CLIENT_SECRET": "test_secret", "OAUTH_BASE_URL": "http://localhost:8000", "OAUTH_AUTHORIZATION_ENDPOINT": "http://auth.example.com/authorize", "OAUTH_TOKEN_ENDPOINT": "http://auth.example.com/token", "OAUTH_JWKS_URI": "http://auth.example.com/.well-known/jwks.json", "OAUTH_ISSUER": "http://auth.example.com", "OAUTH_AUDIENCE": "test_audience", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_oauth_config() assert config.audience == "test_audience" def test_load_oauth_config_with_extra_params(self): """Test loading OAuth config with extra authorization parameters""" env_vars = { "OAUTH_CLIENT_ID": "test_client", "OAUTH_CLIENT_SECRET": "test_secret", "OAUTH_BASE_URL": "http://localhost:8000", "OAUTH_AUTHORIZATION_ENDPOINT": "http://auth.example.com/authorize", "OAUTH_TOKEN_ENDPOINT": "http://auth.example.com/token", "OAUTH_JWKS_URI": "http://auth.example.com/.well-known/jwks.json", "OAUTH_ISSUER": "http://auth.example.com", "OAUTH_EXTRA_AUTH_PARAMS": ( '{"scope": "read write", "response_type": "code"}' ), } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_oauth_config() assert config.extra_authorize_params == { "scope": "read write", "response_type": "code", } def test_load_oauth_config_invalid_extra_params(self): """Test loading OAuth config with invalid extra authorization parameters""" env_vars = { "OAUTH_CLIENT_ID": "test_client", "OAUTH_CLIENT_SECRET": "test_secret", "OAUTH_BASE_URL": "http://localhost:8000", "OAUTH_AUTHORIZATION_ENDPOINT": "http://auth.example.com/authorize", "OAUTH_TOKEN_ENDPOINT": "http://auth.example.com/token", "OAUTH_JWKS_URI": "http://auth.example.com/.well-known/jwks.json", "OAUTH_ISSUER": "http://auth.example.com", "OAUTH_EXTRA_AUTH_PARAMS": "invalid_json", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_oauth_config() assert config.extra_authorize_params is None def test_load_oauth_config_extra_params_not_dict(self): """Test loading OAuth config with extra params that are not a dict""" env_vars = { "OAUTH_CLIENT_ID": "test_client", "OAUTH_CLIENT_SECRET": "test_secret", "OAUTH_BASE_URL": "http://localhost:8000", "OAUTH_AUTHORIZATION_ENDPOINT": "http://auth.example.com/authorize", "OAUTH_TOKEN_ENDPOINT": "http://auth.example.com/token", "OAUTH_JWKS_URI": "http://auth.example.com/.well-known/jwks.json", "OAUTH_ISSUER": "http://auth.example.com", "OAUTH_EXTRA_AUTH_PARAMS": '"not_a_dict"', } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_oauth_config() assert config.extra_authorize_params is None class TestReadTokenFromFile: """Test the _read_token_from_file function""" def test_read_token_from_valid_file(self): """Test reading token from a valid file""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("test_token_123") temp_file = f.name try: token = _read_token_from_file(temp_file) assert token == "Bearer test_token_123" finally: os.unlink(temp_file) def test_read_token_from_file_with_whitespace(self): """Test reading token from file with leading/trailing whitespace""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(" \n test_token_123 \n ") temp_file = f.name try: token = _read_token_from_file(temp_file) assert token == "Bearer test_token_123" finally: os.unlink(temp_file) def test_read_token_from_nonexistent_file(self): """Test reading token from non-existent file""" token = _read_token_from_file("/nonexistent/file/path") assert token is None def test_read_token_from_directory(self): """Test reading token from directory (should fail)""" with tempfile.TemporaryDirectory() as temp_dir: token = _read_token_from_file(temp_dir) assert token is None def test_read_token_from_empty_file(self): """Test reading token from empty file""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("") temp_file = f.name try: token = _read_token_from_file(temp_file) assert token is None finally: os.unlink(temp_file) def test_read_token_from_file_with_only_whitespace(self): """Test reading token from file with only whitespace""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(" \n\t \n ") temp_file = f.name try: token = _read_token_from_file(temp_file) assert token is None finally: os.unlink(temp_file) def test_read_token_from_file_permission_denied(self): """Test reading token from file with no read permission""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("test_token") temp_file = f.name try: # Remove read permission os.chmod(temp_file, 0o000) token = _read_token_from_file(temp_file) assert token is None finally: # Restore permissions for cleanup os.chmod(temp_file, 0o644) os.unlink(temp_file) class TestLoadPinotConfigTokenFilename: """Test token filename functionality in load_pinot_config""" def test_token_filename_only(self): """Test loading config with only token filename""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("test_token_from_file") temp_file = f.name try: env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN_FILENAME": temp_file, } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token == "Bearer test_token_from_file" finally: os.unlink(temp_file) def test_token_filename_with_direct_token(self): """Test that direct token takes precedence over token filename""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("token_from_file") temp_file = f.name try: env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN": "direct_token", "PINOT_TOKEN_FILENAME": temp_file, } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token == "direct_token" finally: os.unlink(temp_file) def test_token_filename_nonexistent_file(self): """Test loading config with non-existent token file""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN_FILENAME": "/nonexistent/file/path", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token is None def test_token_filename_empty_file(self): """Test loading config with empty token file""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("") temp_file = f.name try: env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN_FILENAME": temp_file, } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token is None finally: os.unlink(temp_file) def test_token_filename_with_username_password(self): """Test that token filename works alongside username/password""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("token_from_file") temp_file = f.name try: env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_USERNAME": "testuser", "PINOT_PASSWORD": "testpass", "PINOT_TOKEN_FILENAME": temp_file, } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token == "Bearer token_from_file" assert config.username == "testuser" assert config.password == "testpass" finally: os.unlink(temp_file) def test_no_token_config(self): """Test loading config with no token configuration""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token is None def test_token_filename_with_bearer_prefix(self): """Test that Bearer prefix is not added if already present""" with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write("Bearer existing_token") temp_file = f.name try: env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN_FILENAME": temp_file, } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() assert config.token == "Bearer existing_token" finally: os.unlink(temp_file) def test_token_filename_field_present(self): """Test that token_filename environment variable is processed correctly""" env_vars = { "PINOT_CONTROLLER_URL": "http://controller:9000", "PINOT_TOKEN_FILENAME": "/some/file/path", } with patch("mcp_pinot.config.load_dotenv"): # Disable .env loading with patch.dict(os.environ, env_vars, clear=True): config = load_pinot_config() # Token should be None since the file doesn't exist assert config.token is None

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/startreedata/mcp-pinot'

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