1
+ import pytest
2
+ from unittest .mock import patch
3
+ import sys
4
+ import os
5
+
6
+ sys .path .insert (0 , os .path .join (os .path .dirname (__file__ ), '../src' ))
7
+
8
+
9
+ class TestConfig :
10
+ """Test cases for configuration module"""
11
+
12
+ @patch .dict ('os.environ' , {
13
+ 'MCP_TRANSPORT' : 'http' ,
14
+ 'SNOWFLAKE_BASE_URL' : 'https://test.snowflake.com' ,
15
+ 'SNOWFLAKE_DATABASE' : 'TEST_DB' ,
16
+ 'SNOWFLAKE_SCHEMA' : 'TEST_SCHEMA' ,
17
+ 'SNOWFLAKE_WAREHOUSE' : 'TEST_WH' ,
18
+ 'INTERNAL_GATEWAY' : 'true' ,
19
+ 'ENABLE_METRICS' : 'true' ,
20
+ 'METRICS_PORT' : '9090'
21
+ })
22
+ def test_config_from_environment (self ):
23
+ """Test configuration loading from environment variables"""
24
+ # Re-import to get fresh config with mocked environment
25
+ import importlib
26
+ import config
27
+ importlib .reload (config )
28
+
29
+ assert config .MCP_TRANSPORT == 'http'
30
+ assert config .SNOWFLAKE_BASE_URL == 'https://test.snowflake.com'
31
+ assert config .SNOWFLAKE_DATABASE == 'TEST_DB'
32
+ assert config .SNOWFLAKE_SCHEMA == 'TEST_SCHEMA'
33
+ assert config .SNOWFLAKE_WAREHOUSE == 'TEST_WH'
34
+ assert config .INTERNAL_GATEWAY == 'true'
35
+ assert config .ENABLE_METRICS is True
36
+ assert config .METRICS_PORT == 9090
37
+
38
+ @patch .dict ('os.environ' , {}, clear = True )
39
+ def test_config_defaults (self ):
40
+ """Test configuration defaults when environment variables are not set"""
41
+ import importlib
42
+ import config
43
+ importlib .reload (config )
44
+
45
+ assert config .MCP_TRANSPORT == 'stdio' # Default
46
+ assert config .SNOWFLAKE_WAREHOUSE == 'DEFAULT' # Default
47
+ assert config .INTERNAL_GATEWAY == 'false' # Default
48
+ assert config .ENABLE_METRICS is False # Default
49
+ assert config .METRICS_PORT == 8000 # Default
50
+
51
+ # These should be None when not set
52
+ assert config .SNOWFLAKE_BASE_URL is None
53
+ assert config .SNOWFLAKE_DATABASE is None
54
+ assert config .SNOWFLAKE_SCHEMA is None
55
+
56
+ @patch .dict ('os.environ' , {'MCP_TRANSPORT' : 'stdio' , 'SNOWFLAKE_TOKEN' : 'test_token' })
57
+ def test_stdio_transport_token_handling (self ):
58
+ """Test token handling for stdio transport"""
59
+ import importlib
60
+ import config
61
+ importlib .reload (config )
62
+
63
+ assert config .MCP_TRANSPORT == 'stdio'
64
+ assert config .SNOWFLAKE_TOKEN == 'test_token'
65
+
66
+ @patch .dict ('os.environ' , {'MCP_TRANSPORT' : 'http' , 'SNOWFLAKE_TOKEN' : 'test_token' })
67
+ def test_non_stdio_transport_token_handling (self ):
68
+ """Test token handling for non-stdio transport"""
69
+ import importlib
70
+ import config
71
+ importlib .reload (config )
72
+
73
+ assert config .MCP_TRANSPORT == 'http'
74
+ assert config .SNOWFLAKE_TOKEN is None # Should be None for non-stdio
75
+
76
+ @patch .dict ('os.environ' , {'ENABLE_METRICS' : 'false' })
77
+ def test_metrics_disabled (self ):
78
+ """Test metrics configuration when disabled"""
79
+ import importlib
80
+ import config
81
+ importlib .reload (config )
82
+
83
+ assert config .ENABLE_METRICS is False
84
+
85
+ @patch .dict ('os.environ' , {'ENABLE_METRICS' : 'true' })
86
+ def test_metrics_enabled (self ):
87
+ """Test metrics configuration when enabled"""
88
+ import importlib
89
+ import config
90
+ importlib .reload (config )
91
+
92
+ assert config .ENABLE_METRICS is True
93
+
94
+ @patch .dict ('os.environ' , {'ENABLE_METRICS' : 'TRUE' })
95
+ def test_metrics_case_insensitive (self ):
96
+ """Test that metrics configuration is case insensitive"""
97
+ import importlib
98
+ import config
99
+ importlib .reload (config )
100
+
101
+ assert config .ENABLE_METRICS is True
102
+
103
+ @patch .dict ('os.environ' , {'ENABLE_METRICS' : 'yes' })
104
+ def test_metrics_non_true_value (self ):
105
+ """Test that non-'true' values disable metrics"""
106
+ import importlib
107
+ import config
108
+ importlib .reload (config )
109
+
110
+ assert config .ENABLE_METRICS is False
111
+
112
+ @patch .dict ('os.environ' , {'METRICS_PORT' : 'not_a_number' })
113
+ def test_invalid_metrics_port (self ):
114
+ """Test handling of invalid metrics port"""
115
+ import importlib
116
+
117
+ with pytest .raises (ValueError ):
118
+ import config
119
+ importlib .reload (config )
120
+
121
+ def test_prometheus_availability_check (self ):
122
+ """Test Prometheus availability detection"""
123
+ import importlib
124
+ import config
125
+ importlib .reload (config )
126
+
127
+ # PROMETHEUS_AVAILABLE should be True or False
128
+ assert isinstance (config .PROMETHEUS_AVAILABLE , bool )
129
+
130
+ @patch ('config.logging.basicConfig' )
131
+ def test_logging_configuration (self , mock_basicconfig ):
132
+ """Test that logging is configured"""
133
+ import importlib
134
+ import config
135
+ importlib .reload (config )
136
+
137
+ # Verify logging.basicConfig was called
138
+ mock_basicconfig .assert_called_once ()
139
+
140
+ # Check the configuration parameters
141
+ call_args = mock_basicconfig .call_args
142
+ assert call_args [1 ]['level' ] == config .logging .INFO
143
+ assert 'format' in call_args [1 ]
144
+ assert 'handlers' in call_args [1 ]
145
+
146
+ @patch .dict ('os.environ' , {'INTERNAL_GATEWAY' : 'FALSE' })
147
+ def test_internal_gateway_case_insensitive (self ):
148
+ """Test that internal gateway configuration is case insensitive"""
149
+ import importlib
150
+ import config
151
+ importlib .reload (config )
152
+
153
+ assert config .INTERNAL_GATEWAY == 'FALSE' # Should preserve original case
154
+
155
+ @patch .dict ('os.environ' , {
156
+ 'SNOWFLAKE_BASE_URL' : '' ,
157
+ 'SNOWFLAKE_DATABASE' : '' ,
158
+ 'SNOWFLAKE_SCHEMA' : ''
159
+ })
160
+ def test_empty_string_environment_variables (self ):
161
+ """Test handling of empty string environment variables"""
162
+ import importlib
163
+ import config
164
+ importlib .reload (config )
165
+
166
+ # Empty strings should be treated as None/empty
167
+ assert config .SNOWFLAKE_BASE_URL == ''
168
+ assert config .SNOWFLAKE_DATABASE == ''
169
+ assert config .SNOWFLAKE_SCHEMA == ''
170
+
171
+ def test_config_constants_immutability (self ):
172
+ """Test that configuration values are set as expected"""
173
+ import config
174
+
175
+ # Test that we can access the configuration values
176
+ # (immutability would be tested by trying to modify them)
177
+ assert hasattr (config , 'MCP_TRANSPORT' )
178
+ assert hasattr (config , 'SNOWFLAKE_BASE_URL' )
179
+ assert hasattr (config , 'SNOWFLAKE_DATABASE' )
180
+ assert hasattr (config , 'SNOWFLAKE_SCHEMA' )
181
+ assert hasattr (config , 'SNOWFLAKE_WAREHOUSE' )
182
+ assert hasattr (config , 'INTERNAL_GATEWAY' )
183
+ assert hasattr (config , 'SNOWFLAKE_TOKEN' )
184
+ assert hasattr (config , 'ENABLE_METRICS' )
185
+ assert hasattr (config , 'METRICS_PORT' )
186
+ assert hasattr (config , 'PROMETHEUS_AVAILABLE' )
187
+
188
+ def test_prometheus_import_error (self ):
189
+ """Test handling when prometheus_client import fails"""
190
+ # Test the import check logic directly
191
+ import sys
192
+ import importlib
193
+
194
+ # Temporarily remove prometheus_client from modules if it exists
195
+ prometheus_module = sys .modules .pop ('prometheus_client' , None )
196
+
197
+ try :
198
+ # Mock the import to fail
199
+ with patch .dict ('sys.modules' , {'prometheus_client' : None }):
200
+ # Reload config to trigger the import check
201
+ import config
202
+ importlib .reload (config )
203
+
204
+ # Should detect that prometheus is not available
205
+ assert config .PROMETHEUS_AVAILABLE is False
206
+ finally :
207
+ # Restore the module if it was there
208
+ if prometheus_module is not None :
209
+ sys .modules ['prometheus_client' ] = prometheus_module
0 commit comments