mirror of
https://github.com/hoshikawa2/compass_backoffice.git
synced 2026-07-09 22:04:20 +00:00
first commit
This commit is contained in:
439
tests_original_develop/unit/test_config.py
Normal file
439
tests_original_develop/unit/test_config.py
Normal file
@@ -0,0 +1,439 @@
|
||||
"""
|
||||
Unit tests for configuration module.
|
||||
|
||||
Tests specific examples and edge cases for configuration loading and validation.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
from pydantic import ValidationError
|
||||
|
||||
from src.core.config import Settings, LLMConfig, AgentConfig
|
||||
|
||||
|
||||
class TestSettings:
|
||||
"""Test Settings class."""
|
||||
|
||||
def test_settings_with_required_fields(self):
|
||||
"""Test that Settings can be created with required fields."""
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4"
|
||||
)
|
||||
|
||||
assert settings.LLM_PROVIDER == "openai"
|
||||
assert settings.LLM_MODEL == "gpt-4"
|
||||
assert settings.APP_NAME == "Agent Microservice" # default value
|
||||
assert settings.DEBUG is False # default value
|
||||
assert settings.CLASSIFICATION_LLM_MODEL == "bo_gptoss20b_dev"
|
||||
assert settings.CLASSIFICATION_LLM_TEMPERATURE == 0.3
|
||||
|
||||
def test_settings_classification_custom_values(self):
|
||||
"""Test that Settings can be created with custom classification LLM values."""
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
CLASSIFICATION_LLM_MODEL="custom_model",
|
||||
CLASSIFICATION_LLM_TEMPERATURE=0.5,
|
||||
CLASSIFICATION_LLM_MAX_TOKENS=512,
|
||||
CLASSIFICATION_LLM_TOP_P=0.9
|
||||
)
|
||||
|
||||
assert settings.CLASSIFICATION_LLM_MODEL == "custom_model"
|
||||
assert settings.CLASSIFICATION_LLM_TEMPERATURE == 0.5
|
||||
assert settings.CLASSIFICATION_LLM_MAX_TOKENS == 512
|
||||
assert settings.CLASSIFICATION_LLM_TOP_P == 0.9
|
||||
|
||||
def test_settings_missing_required_field_llm_provider(self):
|
||||
"""Test that missing LLM_PROVIDER raises ValidationError."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Settings(LLM_MODEL="gpt-4")
|
||||
|
||||
errors = exc_info.value.errors()
|
||||
assert any(error['loc'] == ('LLM_PROVIDER',) for error in errors)
|
||||
|
||||
def test_settings_missing_required_field_llm_model(self):
|
||||
"""Test that missing LLM_MODEL raises ValidationError."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Settings(LLM_PROVIDER="openai")
|
||||
|
||||
errors = exc_info.value.errors()
|
||||
assert any(error['loc'] == ('LLM_MODEL',) for error in errors)
|
||||
|
||||
def test_settings_invalid_llm_provider(self):
|
||||
"""Test that invalid LLM_PROVIDER raises ValidationError."""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Settings(
|
||||
LLM_PROVIDER="invalid_provider",
|
||||
LLM_MODEL="gpt-4"
|
||||
)
|
||||
|
||||
errors = exc_info.value.errors()
|
||||
assert any("LLM_PROVIDER" in str(error) for error in errors)
|
||||
|
||||
def test_settings_valid_providers(self):
|
||||
"""Test that valid providers are accepted."""
|
||||
for provider in ["openai", "anthropic"]:
|
||||
settings = Settings(
|
||||
LLM_PROVIDER=provider,
|
||||
LLM_MODEL="test-model"
|
||||
)
|
||||
assert settings.LLM_PROVIDER == provider
|
||||
|
||||
def test_settings_temperature_validation(self):
|
||||
"""Test temperature validation."""
|
||||
# Valid temperature
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LLM_TEMPERATURE=1.5
|
||||
)
|
||||
assert settings.LLM_TEMPERATURE == 1.5
|
||||
|
||||
# Temperature too low
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LLM_TEMPERATURE=-0.1
|
||||
)
|
||||
|
||||
# Temperature too high
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LLM_TEMPERATURE=2.1
|
||||
)
|
||||
|
||||
def test_settings_from_yaml_valid(self):
|
||||
"""Test loading settings from valid YAML file."""
|
||||
yaml_content = """
|
||||
APP_NAME: "Test Agent"
|
||||
VERSION: "2.0.0"
|
||||
DEBUG: true
|
||||
LLM_PROVIDER: "openai"
|
||||
LLM_MODEL: "gpt-3.5-turbo"
|
||||
LLM_TEMPERATURE: 0.5
|
||||
HOST: "127.0.0.1"
|
||||
PORT: 9000
|
||||
LOG_LEVEL: "DEBUG"
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
|
||||
f.write(yaml_content)
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
settings = Settings.from_yaml(temp_path)
|
||||
|
||||
assert settings.APP_NAME == "Test Agent"
|
||||
assert settings.VERSION == "2.0.0"
|
||||
assert settings.DEBUG is True
|
||||
assert settings.LLM_PROVIDER == "openai"
|
||||
assert settings.LLM_MODEL == "gpt-3.5-turbo"
|
||||
assert settings.LLM_TEMPERATURE == 0.5
|
||||
assert settings.HOST == "127.0.0.1"
|
||||
assert settings.PORT == 9000
|
||||
assert settings.LOG_LEVEL == "DEBUG"
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_settings_from_yaml_missing_required(self):
|
||||
"""Test that loading YAML without required fields raises error."""
|
||||
yaml_content = """
|
||||
APP_NAME: "Test Agent"
|
||||
VERSION: "2.0.0"
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
|
||||
f.write(yaml_content)
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
with pytest.raises(ValidationError):
|
||||
Settings.from_yaml(temp_path)
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_settings_from_yaml_file_not_found(self):
|
||||
"""Test that loading from non-existent file raises FileNotFoundError."""
|
||||
with pytest.raises(FileNotFoundError):
|
||||
Settings.from_yaml("/nonexistent/path/config.yaml")
|
||||
|
||||
def test_settings_from_yaml_empty_file(self):
|
||||
"""Test loading from empty YAML file."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
|
||||
f.write("")
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
with pytest.raises(ValidationError):
|
||||
Settings.from_yaml(temp_path)
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_settings_log_level_validation(self):
|
||||
"""Test log level validation."""
|
||||
# Valid log levels
|
||||
for level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_LEVEL=level
|
||||
)
|
||||
assert settings.LOG_LEVEL == level
|
||||
|
||||
# Case insensitive
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_LEVEL="debug"
|
||||
)
|
||||
assert settings.LOG_LEVEL == "DEBUG"
|
||||
|
||||
# Invalid log level
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_LEVEL="INVALID"
|
||||
)
|
||||
|
||||
def test_settings_log_format_validation(self):
|
||||
"""Test log format validation."""
|
||||
# Valid formats
|
||||
for fmt in ["json", "text"]:
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_FORMAT=fmt
|
||||
)
|
||||
assert settings.LOG_FORMAT == fmt
|
||||
|
||||
# Case insensitive
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_FORMAT="JSON"
|
||||
)
|
||||
assert settings.LOG_FORMAT == "json"
|
||||
|
||||
# Invalid format
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LOG_FORMAT="xml"
|
||||
)
|
||||
|
||||
def test_settings_port_validation(self):
|
||||
"""Test port number validation."""
|
||||
# Valid port
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
PORT=8080
|
||||
)
|
||||
assert settings.PORT == 8080
|
||||
|
||||
# Port too low
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
PORT=0
|
||||
)
|
||||
|
||||
# Port too high
|
||||
with pytest.raises(ValidationError):
|
||||
Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
PORT=65536
|
||||
)
|
||||
|
||||
|
||||
class TestLLMConfig:
|
||||
"""Test LLMConfig model."""
|
||||
|
||||
def test_llm_config_valid(self):
|
||||
"""Test creating valid LLMConfig."""
|
||||
config = LLMConfig(
|
||||
provider="openai",
|
||||
model="gpt-4",
|
||||
temperature=0.8,
|
||||
max_tokens=1000
|
||||
)
|
||||
|
||||
assert config.provider == "openai"
|
||||
assert config.model == "gpt-4"
|
||||
assert config.temperature == 0.8
|
||||
assert config.max_tokens == 1000
|
||||
|
||||
def test_llm_config_default_temperature(self):
|
||||
"""Test default temperature value."""
|
||||
config = LLMConfig(
|
||||
provider="openai",
|
||||
model="gpt-4"
|
||||
)
|
||||
|
||||
assert config.temperature == 0.7
|
||||
|
||||
def test_llm_config_invalid_provider(self):
|
||||
"""Test that invalid provider raises error."""
|
||||
with pytest.raises(ValidationError):
|
||||
LLMConfig(
|
||||
provider="invalid",
|
||||
model="gpt-4"
|
||||
)
|
||||
|
||||
def test_llm_config_temperature_bounds(self):
|
||||
"""Test temperature boundary validation."""
|
||||
# Valid boundaries
|
||||
LLMConfig(provider="openai", model="gpt-4", temperature=0.0)
|
||||
LLMConfig(provider="openai", model="gpt-4", temperature=2.0)
|
||||
|
||||
# Invalid boundaries
|
||||
with pytest.raises(ValidationError):
|
||||
LLMConfig(provider="openai", model="gpt-4", temperature=-0.1)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
LLMConfig(provider="openai", model="gpt-4", temperature=2.1)
|
||||
|
||||
def test_llm_config_max_tokens_validation(self):
|
||||
"""Test max_tokens validation."""
|
||||
# Valid max_tokens
|
||||
config = LLMConfig(
|
||||
provider="openai",
|
||||
model="gpt-4",
|
||||
max_tokens=100
|
||||
)
|
||||
assert config.max_tokens == 100
|
||||
|
||||
# None is valid
|
||||
config = LLMConfig(
|
||||
provider="openai",
|
||||
model="gpt-4",
|
||||
max_tokens=None
|
||||
)
|
||||
assert config.max_tokens is None
|
||||
|
||||
# Zero or negative is invalid
|
||||
with pytest.raises(ValidationError):
|
||||
LLMConfig(
|
||||
provider="openai",
|
||||
model="gpt-4",
|
||||
max_tokens=0
|
||||
)
|
||||
|
||||
|
||||
class TestAgentConfig:
|
||||
"""Test AgentConfig model."""
|
||||
|
||||
def test_agent_config_valid(self):
|
||||
"""Test creating valid AgentConfig."""
|
||||
config = AgentConfig(
|
||||
name="Test Agent",
|
||||
description="A test agent",
|
||||
system_prompt="You are a test assistant",
|
||||
tools=["tool1", "tool2"],
|
||||
max_iterations=5
|
||||
)
|
||||
|
||||
assert config.name == "Test Agent"
|
||||
assert config.description == "A test agent"
|
||||
assert config.system_prompt == "You are a test assistant"
|
||||
assert config.tools == ["tool1", "tool2"]
|
||||
assert config.max_iterations == 5
|
||||
|
||||
def test_agent_config_default_tools(self):
|
||||
"""Test default empty tools list."""
|
||||
config = AgentConfig(
|
||||
name="Test Agent",
|
||||
description="A test agent",
|
||||
system_prompt="You are a test assistant"
|
||||
)
|
||||
|
||||
assert config.tools == []
|
||||
|
||||
def test_agent_config_default_max_iterations(self):
|
||||
"""Test default max_iterations value."""
|
||||
config = AgentConfig(
|
||||
name="Test Agent",
|
||||
description="A test agent",
|
||||
system_prompt="You are a test assistant"
|
||||
)
|
||||
|
||||
assert config.max_iterations == 10
|
||||
|
||||
def test_agent_config_max_iterations_validation(self):
|
||||
"""Test max_iterations must be positive."""
|
||||
# Valid
|
||||
AgentConfig(
|
||||
name="Test Agent",
|
||||
description="A test agent",
|
||||
system_prompt="You are a test assistant",
|
||||
max_iterations=1
|
||||
)
|
||||
|
||||
# Invalid
|
||||
with pytest.raises(ValidationError):
|
||||
AgentConfig(
|
||||
name="Test Agent",
|
||||
description="A test agent",
|
||||
system_prompt="You are a test assistant",
|
||||
max_iterations=0
|
||||
)
|
||||
|
||||
|
||||
class TestSettingsConversion:
|
||||
"""Test Settings conversion methods."""
|
||||
|
||||
def test_to_llm_config(self):
|
||||
"""Test converting Settings to LLMConfig."""
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
LLM_TEMPERATURE=0.9,
|
||||
LLM_MAX_TOKENS=2000
|
||||
)
|
||||
|
||||
llm_config = settings.to_llm_config()
|
||||
|
||||
assert isinstance(llm_config, LLMConfig)
|
||||
assert llm_config.provider == "openai"
|
||||
assert llm_config.model == "gpt-4"
|
||||
assert llm_config.temperature == 0.9
|
||||
assert llm_config.max_tokens == 2000
|
||||
|
||||
def test_to_agent_config_with_all_fields(self):
|
||||
"""Test converting Settings to AgentConfig when all fields present."""
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4",
|
||||
AGENT_NAME="My Agent",
|
||||
AGENT_DESCRIPTION="My agent description",
|
||||
AGENT_SYSTEM_PROMPT="You are my agent",
|
||||
AGENT_MAX_ITERATIONS=15
|
||||
)
|
||||
|
||||
agent_config = settings.to_agent_config()
|
||||
|
||||
assert agent_config is not None
|
||||
assert isinstance(agent_config, AgentConfig)
|
||||
assert agent_config.name == "My Agent"
|
||||
assert agent_config.description == "My agent description"
|
||||
assert agent_config.system_prompt == "You are my agent"
|
||||
assert agent_config.max_iterations == 15
|
||||
|
||||
def test_to_agent_config_missing_fields(self):
|
||||
"""Test that to_agent_config returns None when fields missing."""
|
||||
settings = Settings(
|
||||
LLM_PROVIDER="openai",
|
||||
LLM_MODEL="gpt-4"
|
||||
)
|
||||
|
||||
agent_config = settings.to_agent_config()
|
||||
|
||||
assert agent_config is None
|
||||
Reference in New Issue
Block a user