"""Unit tests for config module.""" import os import re from unittest.mock import patch import pytest from haproxy_mcp.config import ( DOMAIN_PATTERN, BACKEND_NAME_PATTERN, NON_ALNUM_PATTERN, StatField, StateField, POOL_COUNT, MAX_SLOTS, MAX_RESPONSE_SIZE, SOCKET_TIMEOUT, MAX_BULK_SERVERS, ) class TestDomainPattern: """Tests for DOMAIN_PATTERN regex.""" def test_simple_domain(self): """Match simple domain.""" assert DOMAIN_PATTERN.match("example.com") is not None def test_subdomain(self): """Match subdomain.""" assert DOMAIN_PATTERN.match("api.example.com") is not None def test_deep_subdomain(self): """Match deep subdomain.""" assert DOMAIN_PATTERN.match("a.b.c.d.example.com") is not None def test_hyphenated_domain(self): """Match domain with hyphens.""" assert DOMAIN_PATTERN.match("my-api.example-site.com") is not None def test_numeric_labels(self): """Match domain with numeric labels.""" assert DOMAIN_PATTERN.match("api123.example.com") is not None def test_invalid_starts_with_hyphen(self): """Reject domain starting with hyphen.""" assert DOMAIN_PATTERN.match("-example.com") is None def test_invalid_ends_with_hyphen(self): """Reject label ending with hyphen.""" assert DOMAIN_PATTERN.match("example-.com") is None def test_invalid_underscore(self): """Reject domain with underscore.""" assert DOMAIN_PATTERN.match("my_api.example.com") is None class TestBackendNamePattern: """Tests for BACKEND_NAME_PATTERN regex.""" def test_pool_name(self): """Match pool backend names.""" assert BACKEND_NAME_PATTERN.match("pool_1") is not None assert BACKEND_NAME_PATTERN.match("pool_100") is not None def test_alphanumeric(self): """Match alphanumeric names.""" assert BACKEND_NAME_PATTERN.match("backend123") is not None def test_underscore(self): """Match names with underscores.""" assert BACKEND_NAME_PATTERN.match("my_backend") is not None def test_hyphen(self): """Match names with hyphens.""" assert BACKEND_NAME_PATTERN.match("my-backend") is not None def test_mixed(self): """Match mixed character names.""" assert BACKEND_NAME_PATTERN.match("api_example-com_backend") is not None def test_invalid_dot(self): """Reject names with dots.""" assert BACKEND_NAME_PATTERN.match("my.backend") is None def test_invalid_special_chars(self): """Reject names with special characters.""" assert BACKEND_NAME_PATTERN.match("my@backend") is None assert BACKEND_NAME_PATTERN.match("my/backend") is None class TestNonAlnumPattern: """Tests for NON_ALNUM_PATTERN regex.""" def test_replace_dots(self): """Replace dots.""" result = NON_ALNUM_PATTERN.sub("_", "example.com") assert result == "example_com" def test_replace_hyphens(self): """Replace hyphens.""" result = NON_ALNUM_PATTERN.sub("_", "my-api") assert result == "my_api" def test_preserve_alphanumeric(self): """Preserve alphanumeric characters.""" result = NON_ALNUM_PATTERN.sub("_", "abc123") assert result == "abc123" def test_complex_replacement(self): """Complex domain replacement.""" result = NON_ALNUM_PATTERN.sub("_", "api.my-site.example.com") assert result == "api_my_site_example_com" class TestStatField: """Tests for StatField constants.""" def test_field_indices(self): """Verify stat field indices.""" assert StatField.PXNAME == 0 assert StatField.SVNAME == 1 assert StatField.SCUR == 4 assert StatField.SMAX == 6 assert StatField.STATUS == 17 assert StatField.WEIGHT == 18 assert StatField.CHECK_STATUS == 36 class TestStateField: """Tests for StateField constants.""" def test_field_indices(self): """Verify state field indices.""" assert StateField.BE_ID == 0 assert StateField.BE_NAME == 1 assert StateField.SRV_ID == 2 assert StateField.SRV_NAME == 3 assert StateField.SRV_ADDR == 4 assert StateField.SRV_OP_STATE == 5 assert StateField.SRV_ADMIN_STATE == 6 assert StateField.SRV_PORT == 18 class TestConfigConstants: """Tests for configuration constants.""" def test_pool_count(self): """Pool count has expected value.""" assert POOL_COUNT == 100 def test_max_slots(self): """Max slots has expected value.""" assert MAX_SLOTS == 10 def test_max_response_size(self): """Max response size is reasonable.""" assert MAX_RESPONSE_SIZE == 10 * 1024 * 1024 # 10 MB def test_socket_timeout(self): """Socket timeout is reasonable.""" assert SOCKET_TIMEOUT == 5 def test_max_bulk_servers(self): """Max bulk servers is reasonable.""" assert MAX_BULK_SERVERS == 10 class TestEnvironmentVariables: """Tests for environment variable configuration.""" def test_default_mcp_host(self): """Default MCP host is 0.0.0.0.""" # Import fresh to get defaults with patch.dict(os.environ, {}, clear=True): # Re-import to test defaults from importlib import reload import haproxy_mcp.config as config reload(config) # Note: Due to Python's module caching, this test verifies the # default values are what we expect from the source code assert config.MCP_HOST == "0.0.0.0" def test_default_mcp_port(self): """Default MCP port is 8000.""" from haproxy_mcp.config import MCP_PORT assert MCP_PORT == 8000 def test_default_haproxy_host(self): """Default HAProxy host is localhost.""" from haproxy_mcp.config import HAPROXY_HOST assert HAPROXY_HOST == "localhost" def test_default_haproxy_port(self): """Default HAProxy port is 9999.""" from haproxy_mcp.config import HAPROXY_PORT assert HAPROXY_PORT == 9999