Files
AI-Trader/tests/integration/test_config_override.py
Bill 14cf88f642 test: improve test coverage from 61% to 84.81%
Major improvements:
- Fixed all 42 broken tests (database connection leaks)
- Added db_connection() context manager for proper cleanup
- Created comprehensive test suites for undertested modules

New test coverage:
- tools/general_tools.py: 26 tests (97% coverage)
- tools/price_tools.py: 11 tests (validates NASDAQ symbols, date handling)
- api/price_data_manager.py: 12 tests (85% coverage)
- api/routes/results_v2.py: 3 tests (98% coverage)
- agent/reasoning_summarizer.py: 2 tests (87% coverage)
- api/routes/period_metrics.py: 2 edge case tests (100% coverage)
- agent/mock_provider: 1 test (100% coverage)

Database fixes:
- Added db_connection() context manager to prevent leaks
- Updated 16+ test files to use context managers
- Fixed drop_all_tables() to match new schema
- Added CHECK constraint for action_type
- Added ON DELETE CASCADE to trading_days foreign key

Test improvements:
- Updated SQL INSERT statements with all required fields
- Fixed date parameter handling in API integration tests
- Added edge case tests for validation functions
- Fixed import errors across test suite

Results:
- Total coverage: 84.81% (was 61%)
- Tests passing: 406 (was 364 with 42 failures)
- Total lines covered: 6364 of 7504

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 21:02:38 -05:00

122 lines
4.0 KiB
Python

"""Integration tests for config override system."""
import pytest
import json
import subprocess
import tempfile
from pathlib import Path
@pytest.fixture
def test_configs(tmp_path):
"""Create test config files."""
# Default config
default_config = {
"agent_type": "BaseAgent",
"date_range": {"init_date": "2025-10-01", "end_date": "2025-10-21"},
"models": [
{"name": "default-model", "basemodel": "openai/gpt-4", "signature": "default", "enabled": True}
],
"agent_config": {"max_steps": 30, "max_retries": 3, "base_delay": 1.0, "initial_cash": 10000.0},
"log_config": {"log_path": "./data/agent_data"}
}
configs_dir = tmp_path / "configs"
configs_dir.mkdir()
default_path = configs_dir / "default_config.json"
with open(default_path, 'w') as f:
json.dump(default_config, f, indent=2)
return configs_dir, default_config
def test_config_override_models_only(test_configs):
"""Test overriding only the models section."""
configs_dir, default_config = test_configs
# Custom config - only override models
custom_config = {
"models": [
{"name": "gpt-5", "basemodel": "openai/gpt-5", "signature": "gpt-5", "enabled": True}
]
}
user_configs_dir = configs_dir.parent / "user-configs"
user_configs_dir.mkdir()
custom_path = user_configs_dir / "config.json"
with open(custom_path, 'w') as f:
json.dump(custom_config, f, indent=2)
# Run merge
result = subprocess.run(
[
"python3", "-c",
f"import sys; sys.path.insert(0, '.'); "
f"from tools.config_merger import DEFAULT_CONFIG_PATH, CUSTOM_CONFIG_PATH, OUTPUT_CONFIG_PATH, merge_and_validate; "
f"import tools.config_merger; "
f"tools.config_merger.DEFAULT_CONFIG_PATH = '{configs_dir}/default_config.json'; "
f"tools.config_merger.CUSTOM_CONFIG_PATH = '{custom_path}'; "
f"tools.config_merger.OUTPUT_CONFIG_PATH = '{configs_dir.parent}/runtime.json'; "
f"merge_and_validate()"
],
capture_output=True,
text=True,
cwd=str(Path(__file__).resolve().parents[2])
)
assert result.returncode == 0, f"Merge failed: {result.stderr}"
# Verify merged config
runtime_path = configs_dir.parent / "runtime.json"
with open(runtime_path, 'r') as f:
merged = json.load(f)
# Models should be overridden
assert merged["models"] == custom_config["models"]
# Other sections should be from default
assert merged["agent_config"] == default_config["agent_config"]
assert merged["date_range"] == default_config["date_range"]
def test_config_validation_fails_gracefully(test_configs):
"""Test that invalid config causes exit with clear error."""
configs_dir, _ = test_configs
# Invalid custom config (no enabled models)
custom_config = {
"models": [
{"name": "test", "basemodel": "openai/gpt-4", "signature": "test", "enabled": False}
]
}
user_configs_dir = configs_dir.parent / "user-configs"
user_configs_dir.mkdir()
custom_path = user_configs_dir / "config.json"
with open(custom_path, 'w') as f:
json.dump(custom_config, f, indent=2)
# Run merge (should fail)
result = subprocess.run(
[
"python3", "-c",
f"import sys; sys.path.insert(0, '.'); "
f"from tools.config_merger import merge_and_validate; "
f"import tools.config_merger; "
f"tools.config_merger.DEFAULT_CONFIG_PATH = '{configs_dir}/default_config.json'; "
f"tools.config_merger.CUSTOM_CONFIG_PATH = '{custom_path}'; "
f"tools.config_merger.OUTPUT_CONFIG_PATH = '{configs_dir.parent}/runtime.json'; "
f"merge_and_validate()"
],
capture_output=True,
text=True,
cwd=str(Path(__file__).resolve().parents[2])
)
assert result.returncode == 1
assert "CONFIG VALIDATION FAILED" in result.stderr
assert "At least one model must be enabled" in result.stderr