-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_config_validation.py
More file actions
188 lines (142 loc) · 5.59 KB
/
test_config_validation.py
File metadata and controls
188 lines (142 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""
Tests for configuration validation (HIGH-010).
Tests cover:
- Valid configuration acceptance
- Invalid value rejection with clear errors
- Type coercion
- Range validation
- Production mode restrictions
"""
import pytest
import os
from unittest.mock import patch
from app.config import (
OllamaConfig,
RateLimitConfig,
FileLimitsConfig,
RAGConfig,
HITLConfig,
DatabaseConfig,
AppSettings,
load_settings_from_env,
)
class TestOllamaConfig:
"""Tests for Ollama configuration."""
def test_valid_config(self):
config = OllamaConfig(host="http://localhost:11434", model="gemma2:2b")
assert config.host == "http://localhost:11434"
assert config.model == "gemma2:2b"
def test_https_host(self):
config = OllamaConfig(host="https://ollama.example.com")
assert config.host == "https://ollama.example.com"
def test_invalid_host_no_scheme(self):
with pytest.raises(ValueError) as exc_info:
OllamaConfig(host="localhost:11434")
assert "must start with http://" in str(exc_info.value)
def test_host_trailing_slash_removed(self):
config = OllamaConfig(host="http://localhost:11434/")
assert config.host == "http://localhost:11434"
def test_timeout_boundaries(self):
# Valid range
config = OllamaConfig(timeout=60)
assert config.timeout == 60
# Below minimum
with pytest.raises(ValueError):
OllamaConfig(timeout=5)
# Above maximum
with pytest.raises(ValueError):
OllamaConfig(timeout=700)
class TestRateLimitConfig:
"""Tests for rate limiting configuration."""
def test_valid_config(self):
config = RateLimitConfig(requests_per_minute=100)
assert config.requests_per_minute == 100
def test_below_minimum(self):
with pytest.raises(ValueError):
RateLimitConfig(requests_per_minute=0)
def test_above_maximum(self):
with pytest.raises(ValueError):
RateLimitConfig(requests_per_minute=1001)
class TestFileLimitsConfig:
"""Tests for file limits configuration."""
def test_valid_config(self):
config = FileLimitsConfig(
max_file_size=5 * 1024 * 1024, # 5MB
max_text_length=20 * 1024 * 1024, # 20MB
)
assert config.max_file_size == 5 * 1024 * 1024
def test_file_size_below_minimum(self):
with pytest.raises(ValueError):
FileLimitsConfig(max_file_size=100) # Below 1KB minimum
def test_file_size_above_maximum(self):
with pytest.raises(ValueError):
FileLimitsConfig(max_file_size=200 * 1024 * 1024) # Above 100MB max
class TestHITLConfig:
"""Tests for HITL configuration."""
def test_valid_threshold(self):
config = HITLConfig(confidence_threshold=0.9)
assert config.confidence_threshold == 0.9
def test_threshold_below_zero(self):
with pytest.raises(ValueError):
HITLConfig(confidence_threshold=-0.1)
def test_threshold_above_one(self):
with pytest.raises(ValueError):
HITLConfig(confidence_threshold=1.5)
class TestDatabaseConfig:
"""Tests for database configuration."""
def test_sqlite_url(self):
config = DatabaseConfig(url="sqlite:///./test.db")
assert "sqlite" in config.url
def test_postgres_url(self):
config = DatabaseConfig(url="postgresql://user:pass@localhost/db")
assert "postgresql" in config.url
def test_invalid_url_scheme(self):
with pytest.raises(ValueError) as exc_info:
DatabaseConfig(url="invalid://localhost/db")
assert "must start with" in str(exc_info.value)
class TestAppSettings:
"""Tests for main application settings."""
def test_valid_development_settings(self):
settings = AppSettings(
environment="development",
debug=True,
)
assert settings.environment == "development"
assert settings.debug is True
def test_environment_normalization(self):
settings = AppSettings(environment="PRODUCTION", debug=False)
assert settings.environment == "production"
def test_invalid_environment(self):
with pytest.raises(ValueError) as exc_info:
AppSettings(environment="invalid")
assert "must be one of" in str(exc_info.value)
def test_production_debug_blocked(self):
"""Debug must be disabled in production."""
with pytest.raises(ValueError) as exc_info:
AppSettings(environment="production", debug=True)
assert "Debug mode must be disabled" in str(exc_info.value)
class TestLoadSettingsFromEnv:
"""Tests for environment variable loading."""
@patch.dict(os.environ, {
"ENVIRONMENT": "development",
"OLLAMA_MODEL": "gemma2:2b",
"RATE_LIMIT_PER_MINUTE": "120",
}, clear=False)
def test_loads_from_environment(self):
# Clear cache for fresh load
import app.config as config_module
config_module._settings_cache = None
settings = load_settings_from_env()
assert settings.environment == "development"
assert settings.ollama.model == "gemma2:2b"
assert settings.rate_limit.requests_per_minute == 120
@patch.dict(os.environ, {
"MAX_FILE_SIZE": "not_a_number",
}, clear=False)
def test_invalid_type_raises_error(self):
import app.config as config_module
config_module._settings_cache = None
with pytest.raises(Exception):
load_settings_from_env()
if __name__ == "__main__":
pytest.main([__file__, "-v"])