|
1 | 1 | """Tests for MCPConfigBuilder.""" |
2 | 2 |
|
3 | 3 | import os |
| 4 | +import tempfile |
4 | 5 | from datetime import timedelta |
5 | 6 | from unittest.mock import patch |
6 | 7 |
|
|
10 | 11 | StdioTransportConfig, |
11 | 12 | StreamableHttpTransportConfig, |
12 | 13 | ) |
13 | | -from ols.src.tools.mcp_config_builder import K8S_AUTH_HEADER, MCPConfigBuilder |
| 14 | +from ols.src.tools.mcp_config_builder import KUBERNETES_PLACEHOLDER, MCPConfigBuilder |
14 | 15 |
|
15 | 16 |
|
16 | 17 | def test_mcp_config_builder_dump_client_config(): |
@@ -145,66 +146,42 @@ def test_missing_kubeconfig_and_kubernetes_service(caplog): |
145 | 146 | assert mcp_config == expected |
146 | 147 | assert "Missing necessary KUBECONFIG/KUBERNETES_SERVICE_* envs" in caplog.text |
147 | 148 |
|
148 | | - @staticmethod |
149 | | - def test_include_auth_header(): |
150 | | - """Test include_auth_header method.""" |
151 | | - user_token = "fake-token" # noqa: S105 |
152 | | - config = {} |
153 | | - |
154 | | - result = MCPConfigBuilder.include_auth_header(user_token, config) |
155 | | - |
156 | | - assert "headers" in result |
157 | | - assert result["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
158 | | - |
159 | | - @staticmethod |
160 | | - def test_include_auth_header_existing_headers(): |
161 | | - """Test include_auth_header with existing headers.""" |
162 | | - user_token = "fake-token" # noqa: S105 |
163 | | - config = {"headers": {"Content-Type": "application/json"}} |
164 | | - |
165 | | - result = MCPConfigBuilder.include_auth_header(user_token, config) |
166 | | - |
167 | | - assert result["headers"]["Content-Type"] == "application/json" |
168 | | - assert result["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
169 | | - |
170 | | - @staticmethod |
171 | | - def test_include_auth_header_existing_auth(caplog): |
172 | | - """Test include_auth_header with existing auth header.""" |
173 | | - user_token = "fake-token" # noqa: S105 |
174 | | - config = {"headers": {K8S_AUTH_HEADER: "old-token"}} |
175 | | - |
176 | | - result = MCPConfigBuilder.include_auth_header(user_token, config) |
177 | | - |
178 | | - assert result["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
179 | | - assert ( |
180 | | - "Kubernetes auth header is already set, overriding with actual user token" |
181 | | - in caplog.text |
182 | | - ) |
183 | | - |
184 | 149 | @staticmethod |
185 | 150 | def test_dump_client_config_with_sse(): |
186 | 151 | """Test dump_client_config with SSE configuration.""" |
187 | | - mcp_server_configs = [ |
188 | | - MCPServerConfig( |
189 | | - name="sse-server", |
190 | | - transport="sse", |
191 | | - sse=SseTransportConfig( |
192 | | - url="https://example.com/events", |
193 | | - headers={"X-Custom-Header": "value"}, |
| 152 | + file_descriptor, file_path = tempfile.mkstemp(suffix=".tmp") |
| 153 | + try: |
| 154 | + with os.fdopen(file_descriptor, "w") as open_file: |
| 155 | + open_file.write("value") |
| 156 | + mcp_server_configs = [ |
| 157 | + MCPServerConfig( |
| 158 | + name="sse-server", |
| 159 | + transport="sse", |
| 160 | + sse=SseTransportConfig( |
| 161 | + url="https://example.com/events", |
| 162 | + headers={ |
| 163 | + "X-Custom-Header": file_path, |
| 164 | + "kubernetes": KUBERNETES_PLACEHOLDER, |
| 165 | + }, |
| 166 | + ), |
194 | 167 | ), |
195 | | - ), |
196 | | - ] |
197 | | - user_token = "fake-token" # noqa: S105 |
198 | | - |
199 | | - builder = MCPConfigBuilder(user_token, mcp_server_configs) |
200 | | - result = builder.dump_client_config() |
| 168 | + ] |
| 169 | + user_token = "fake-token" # noqa: S105 |
201 | 170 |
|
202 | | - assert result["sse-server"]["transport"] == "sse" |
203 | | - assert result["sse-server"]["url"] == "https://example.com/events" |
204 | | - assert result["sse-server"]["headers"]["X-Custom-Header"] == "value" |
205 | | - assert ( |
206 | | - result["sse-server"]["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
207 | | - ) |
| 171 | + builder = MCPConfigBuilder(user_token, mcp_server_configs) |
| 172 | + try: |
| 173 | + result = builder.dump_client_config() |
| 174 | + except Exception as e: |
| 175 | + print(f"failed creating config {e}") |
| 176 | + assert False |
| 177 | + assert result["sse-server"]["transport"] == "sse" |
| 178 | + assert result["sse-server"]["url"] == "https://example.com/events" |
| 179 | + assert result["sse-server"]["headers"]["X-Custom-Header"] == "value" |
| 180 | + assert ( |
| 181 | + result["sse-server"]["headers"]["kubernetes"] == f"Bearer {user_token}" |
| 182 | + ) |
| 183 | + finally: |
| 184 | + os.unlink(file_path) |
208 | 185 |
|
209 | 186 | @staticmethod |
210 | 187 | def test_dump_client_config_with_mixed_transports(): |
@@ -237,40 +214,52 @@ def test_dump_client_config_with_mixed_transports(): |
237 | 214 | assert result["openshift"]["transport"] == "stdio" |
238 | 215 | assert result["sse-server"]["transport"] == "sse" |
239 | 216 | assert result["openshift"]["env"]["OC_USER_TOKEN"] == user_token |
240 | | - assert ( |
241 | | - result["sse-server"]["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
242 | | - ) |
243 | 217 |
|
244 | 218 | @staticmethod |
245 | 219 | def test_dump_client_config_with_streamable_http(): |
246 | 220 | """Test dump_client_config with streamable HTTP configuration.""" |
247 | | - mcp_server_configs = [ |
248 | | - MCPServerConfig( |
249 | | - name="streamable-server", |
250 | | - transport="streamable_http", |
251 | | - streamable_http=StreamableHttpTransportConfig( |
252 | | - url="https://example.com/stream", |
253 | | - headers={"X-Custom-Header": "value"}, |
254 | | - timeout=30, |
255 | | - sse_read_timeout=60, |
| 221 | + file_descriptor, file_path = tempfile.mkstemp(suffix=".tmp") |
| 222 | + try: |
| 223 | + with os.fdopen(file_descriptor, "w") as open_file: |
| 224 | + open_file.write("value") |
| 225 | + mcp_server_configs = [ |
| 226 | + MCPServerConfig( |
| 227 | + name="streamable-server", |
| 228 | + transport="streamable_http", |
| 229 | + streamable_http=StreamableHttpTransportConfig( |
| 230 | + url="https://example.com/stream", |
| 231 | + headers={ |
| 232 | + "X-Custom-Header": file_path, |
| 233 | + "kubernetes": KUBERNETES_PLACEHOLDER, |
| 234 | + }, |
| 235 | + timeout=30, |
| 236 | + sse_read_timeout=60, |
| 237 | + ), |
256 | 238 | ), |
257 | | - ), |
258 | | - ] |
259 | | - user_token = "fake-token" # noqa: S105 |
260 | | - |
261 | | - builder = MCPConfigBuilder(user_token, mcp_server_configs) |
262 | | - result = builder.dump_client_config() |
| 239 | + ] |
| 240 | + user_token = "fake-token" # noqa: S105 |
263 | 241 |
|
264 | | - assert result["streamable-server"]["transport"] == "streamable_http" |
265 | | - assert result["streamable-server"]["url"] == "https://example.com/stream" |
266 | | - assert result["streamable-server"]["headers"]["X-Custom-Header"] == "value" |
267 | | - assert ( |
268 | | - result["streamable-server"]["headers"][K8S_AUTH_HEADER] |
269 | | - == f"Bearer {user_token}" |
270 | | - ) |
271 | | - # Verify that timeout values are converted to timedelta objects |
272 | | - assert result["streamable-server"]["timeout"] == timedelta(seconds=30) |
273 | | - assert result["streamable-server"]["sse_read_timeout"] == timedelta(seconds=60) |
| 242 | + builder = MCPConfigBuilder(user_token, mcp_server_configs) |
| 243 | + try: |
| 244 | + result = builder.dump_client_config() |
| 245 | + except Exception as e: |
| 246 | + print(f"failed creating config {e}") |
| 247 | + assert False |
| 248 | + |
| 249 | + assert result["streamable-server"]["transport"] == "streamable_http" |
| 250 | + assert result["streamable-server"]["url"] == "https://example.com/stream" |
| 251 | + assert result["streamable-server"]["headers"]["X-Custom-Header"] == "value" |
| 252 | + assert ( |
| 253 | + result["streamable-server"]["headers"]["kubernetes"] |
| 254 | + == f"Bearer {user_token}" |
| 255 | + ) |
| 256 | + # Verify that timeout values are converted to timedelta objects |
| 257 | + assert result["streamable-server"]["timeout"] == timedelta(seconds=30) |
| 258 | + assert result["streamable-server"]["sse_read_timeout"] == timedelta( |
| 259 | + seconds=60 |
| 260 | + ) |
| 261 | + finally: |
| 262 | + os.unlink(file_path) |
274 | 263 |
|
275 | 264 | @staticmethod |
276 | 265 | def test_dump_client_config_with_all_transports(): |
@@ -312,10 +301,3 @@ def test_dump_client_config_with_all_transports(): |
312 | 301 | assert result["sse-server"]["transport"] == "sse" |
313 | 302 | assert result["streamable-server"]["transport"] == "streamable_http" |
314 | 303 | assert result["openshift"]["env"]["OC_USER_TOKEN"] == user_token |
315 | | - assert ( |
316 | | - result["sse-server"]["headers"][K8S_AUTH_HEADER] == f"Bearer {user_token}" |
317 | | - ) |
318 | | - assert ( |
319 | | - result["streamable-server"]["headers"][K8S_AUTH_HEADER] |
320 | | - == f"Bearer {user_token}" |
321 | | - ) |
0 commit comments