1
1
"""Tests for the server module."""
2
2
3
3
import os
4
- from unittest .mock import MagicMock , patch , AsyncMock
4
+ from pathlib import Path
5
+ from unittest .mock import AsyncMock , MagicMock , patch
5
6
6
7
import pytest
8
+ from click .testing import CliRunner
7
9
from fastapi .middleware .cors import CORSMiddleware
8
10
from fastapi .testclient import TestClient
9
11
from httpx import AsyncClient
12
+ from uvicorn .config import Config as UvicornConfig
10
13
11
14
from codegate import __version__
12
15
from codegate .pipeline .factory import PipelineFactory
13
16
from codegate .pipeline .secrets .manager import SecretsManager
14
17
from codegate .providers .registry import ProviderRegistry
15
18
from codegate .server import init_app
16
- from src .codegate .cli import UvicornServer
17
- from src .codegate .cli import cli
18
- from src .codegate .codegate_logging import LogLevel , LogFormat
19
- from uvicorn .config import Config as UvicornConfig
20
- from click .testing import CliRunner
21
- from pathlib import Path
19
+ from src .codegate .cli import UvicornServer , cli
20
+ from src .codegate .codegate_logging import LogFormat , LogLevel
22
21
23
22
24
23
@pytest .fixture
@@ -176,12 +175,12 @@ def mock_app():
176
175
@pytest .fixture
177
176
def uvicorn_config (mock_app ):
178
177
# Assuming mock_app is defined to simulate ASGI application
179
- return UvicornConfig (app = mock_app , host = ' localhost' , port = 8000 , log_level = ' info' )
178
+ return UvicornConfig (app = mock_app , host = " localhost" , port = 8000 , log_level = " info" )
180
179
181
180
182
181
@pytest .fixture
183
182
def server_instance (uvicorn_config ):
184
- with patch (' src.codegate.cli.Server' , autospec = True ) as mock_server_class :
183
+ with patch (" src.codegate.cli.Server" , autospec = True ) as mock_server_class :
185
184
mock_server_instance = mock_server_class .return_value
186
185
mock_server_instance .serve = AsyncMock ()
187
186
yield UvicornServer (uvicorn_config , mock_server_instance )
@@ -200,20 +199,22 @@ def cli_runner():
200
199
201
200
@pytest .fixture
202
201
def mock_logging (mocker ):
203
- return mocker .patch (' your_cli_module.structlog.get_logger' )
202
+ return mocker .patch (" your_cli_module.structlog.get_logger" )
204
203
205
204
206
205
@pytest .fixture
207
206
def mock_setup_logging (mocker ):
208
- return mocker .patch (' your_cli_module.setup_logging' )
207
+ return mocker .patch (" your_cli_module.setup_logging" )
209
208
210
209
211
210
def test_serve_default_options (cli_runner ):
212
211
"""Test serve command with default options."""
213
212
# Use patches for run_servers and logging setup
214
- with patch ("src.codegate.cli.run_servers" ) as mock_run , \
215
- patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging , \
216
- patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging :
213
+ with (
214
+ patch ("src.codegate.cli.run_servers" ) as mock_run ,
215
+ patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging ,
216
+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
217
+ ):
217
218
218
219
logger_instance = MagicMock ()
219
220
mock_logging .return_value = logger_instance
@@ -236,9 +237,11 @@ def test_serve_default_options(cli_runner):
236
237
237
238
def test_serve_custom_options (cli_runner ):
238
239
"""Test serve command with custom options."""
239
- with patch ("src.codegate.cli.run_servers" ) as mock_run , \
240
- patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging , \
241
- patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging :
240
+ with (
241
+ patch ("src.codegate.cli.run_servers" ) as mock_run ,
242
+ patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging ,
243
+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
244
+ ):
242
245
243
246
logger_instance = MagicMock ()
244
247
mock_logging .return_value = logger_instance
@@ -248,15 +251,24 @@ def test_serve_custom_options(cli_runner):
248
251
cli ,
249
252
[
250
253
"serve" ,
251
- "--port" , "8989" ,
252
- "--host" , "localhost" ,
253
- "--log-level" , "DEBUG" ,
254
- "--log-format" , "TEXT" ,
255
- "--certs-dir" , "./custom-certs" ,
256
- "--ca-cert" , "custom-ca.crt" ,
257
- "--ca-key" , "custom-ca.key" ,
258
- "--server-cert" , "custom-server.crt" ,
259
- "--server-key" , "custom-server.key" ,
254
+ "--port" ,
255
+ "8989" ,
256
+ "--host" ,
257
+ "localhost" ,
258
+ "--log-level" ,
259
+ "DEBUG" ,
260
+ "--log-format" ,
261
+ "TEXT" ,
262
+ "--certs-dir" ,
263
+ "./custom-certs" ,
264
+ "--ca-cert" ,
265
+ "custom-ca.crt" ,
266
+ "--ca-key" ,
267
+ "custom-ca.key" ,
268
+ "--server-cert" ,
269
+ "custom-server.crt" ,
270
+ "--server-key" ,
271
+ "custom-server.key" ,
260
272
],
261
273
)
262
274
@@ -289,8 +301,9 @@ def test_serve_custom_options(cli_runner):
289
301
290
302
# Check if Config object attributes match the expected values
291
303
for key , expected_value in expected_values .items ():
292
- assert getattr (config_arg , key ) == expected_value , \
293
- f"{ key } does not match expected value"
304
+ assert (
305
+ getattr (config_arg , key ) == expected_value
306
+ ), f"{ key } does not match expected value"
294
307
295
308
296
309
def test_serve_invalid_port (cli_runner ):
@@ -310,21 +323,25 @@ def test_serve_invalid_log_level(cli_runner):
310
323
@pytest .fixture
311
324
def temp_config_file (tmp_path ):
312
325
config_path = tmp_path / "config.yaml"
313
- config_path .write_text ("""
326
+ config_path .write_text (
327
+ """
314
328
log_level: DEBUG
315
329
log_format: JSON
316
330
port: 8989
317
331
host: localhost
318
332
certs_dir: ./test-certs
319
- """ )
333
+ """
334
+ )
320
335
return config_path
321
336
322
337
323
338
def test_serve_with_config_file (cli_runner , temp_config_file ):
324
339
"""Test serve command with config file."""
325
- with patch ("src.codegate.cli.run_servers" ) as mock_run , \
326
- patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging , \
327
- patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging :
340
+ with (
341
+ patch ("src.codegate.cli.run_servers" ) as mock_run ,
342
+ patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging ,
343
+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
344
+ ):
328
345
329
346
logger_instance = MagicMock ()
330
347
mock_logging .return_value = logger_instance
@@ -352,8 +369,9 @@ def test_serve_with_config_file(cli_runner, temp_config_file):
352
369
353
370
# Check if passed arguments match the expected values
354
371
for key , expected_value in expected_values .items ():
355
- assert getattr (config_arg , key ) == expected_value , \
356
- f"{ key } does not match expected value"
372
+ assert (
373
+ getattr (config_arg , key ) == expected_value
374
+ ), f"{ key } does not match expected value"
357
375
358
376
359
377
def test_serve_with_nonexistent_config_file (cli_runner : CliRunner ) -> None :
@@ -366,10 +384,12 @@ def test_serve_with_nonexistent_config_file(cli_runner: CliRunner) -> None:
366
384
def test_serve_priority_resolution (cli_runner : CliRunner , temp_config_file : Path ) -> None :
367
385
"""Test serve command respects configuration priority."""
368
386
# Set up environment variables and ensure they get cleaned up after the test
369
- with patch .dict (os .environ , {'LOG_LEVEL' : 'INFO' , 'PORT' : '9999' }, clear = True ), \
370
- patch ('src.codegate.cli.run_servers' ) as mock_run , \
371
- patch ('src.codegate.cli.structlog.get_logger' ) as mock_logging , \
372
- patch ('src.codegate.cli.setup_logging' ) as mock_setup_logging :
387
+ with (
388
+ patch .dict (os .environ , {"LOG_LEVEL" : "INFO" , "PORT" : "9999" }, clear = True ),
389
+ patch ("src.codegate.cli.run_servers" ) as mock_run ,
390
+ patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging ,
391
+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
392
+ ):
373
393
# Set up mock logger
374
394
logger_instance = MagicMock ()
375
395
mock_logging .return_value = logger_instance
@@ -406,7 +426,7 @@ def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path
406
426
assert result .exit_code == 0
407
427
408
428
# Ensure logging setup was called with the highest priority settings (CLI arguments)
409
- mock_setup_logging .assert_called_once_with (' ERROR' , ' TEXT' )
429
+ mock_setup_logging .assert_called_once_with (" ERROR" , " TEXT" )
410
430
mock_logging .assert_called_with ("codegate" )
411
431
412
432
# Verify that the run_servers was called with the overridden settings
@@ -415,8 +435,8 @@ def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path
415
435
expected_values = {
416
436
"port" : 8080 ,
417
437
"host" : "example.com" ,
418
- "log_level" : ' ERROR' ,
419
- "log_format" : ' TEXT' ,
438
+ "log_level" : " ERROR" ,
439
+ "log_format" : " TEXT" ,
420
440
"certs_dir" : "./cli-certs" ,
421
441
"ca_cert" : "cli-ca.crt" ,
422
442
"ca_key" : "cli-ca.key" ,
@@ -426,15 +446,18 @@ def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path
426
446
427
447
# Verify if Config object attributes match the expected values from CLI arguments
428
448
for key , expected_value in expected_values .items ():
429
- assert getattr (config_arg , key ) == expected_value , \
430
- f"{ key } does not match expected value"
449
+ assert (
450
+ getattr (config_arg , key ) == expected_value
451
+ ), f"{ key } does not match expected value"
431
452
432
453
433
454
def test_serve_certificate_options (cli_runner : CliRunner ) -> None :
434
455
"""Test serve command with certificate options."""
435
- with patch ('src.codegate.cli.run_servers' ) as mock_run , \
436
- patch ('src.codegate.cli.structlog.get_logger' ) as mock_logging , \
437
- patch ('src.codegate.cli.setup_logging' ) as mock_setup_logging :
456
+ with (
457
+ patch ("src.codegate.cli.run_servers" ) as mock_run ,
458
+ patch ("src.codegate.cli.structlog.get_logger" ) as mock_logging ,
459
+ patch ("src.codegate.cli.setup_logging" ) as mock_setup_logging ,
460
+ ):
438
461
# Set up mock logger
439
462
logger_instance = MagicMock ()
440
463
mock_logging .return_value = logger_instance
@@ -461,7 +484,7 @@ def test_serve_certificate_options(cli_runner: CliRunner) -> None:
461
484
assert result .exit_code == 0
462
485
463
486
# Ensure logging setup was called with expected arguments
464
- mock_setup_logging .assert_called_once_with (' INFO' , ' JSON' )
487
+ mock_setup_logging .assert_called_once_with (" INFO" , " JSON" )
465
488
mock_logging .assert_called_with ("codegate" )
466
489
467
490
# Verify that run_servers was called with the provided certificate options
@@ -477,14 +500,16 @@ def test_serve_certificate_options(cli_runner: CliRunner) -> None:
477
500
478
501
# Check if Config object attributes match the expected values
479
502
for key , expected_value in expected_values .items ():
480
- assert getattr (config_arg , key ) == expected_value , \
481
- f"{ key } does not match expected value"
503
+ assert (
504
+ getattr (config_arg , key ) == expected_value
505
+ ), f"{ key } does not match expected value"
482
506
483
507
484
508
def test_main_function () -> None :
485
509
"""Test main function."""
486
510
with patch ("sys.argv" , ["cli" ]), patch ("codegate.cli.cli" ) as mock_cli :
487
511
from codegate .cli import main
512
+
488
513
main ()
489
514
mock_cli .assert_called_once ()
490
515
@@ -501,8 +526,10 @@ def mock_uvicorn_server():
501
526
502
527
@pytest .mark .asyncio
503
528
async def test_uvicorn_server_cleanup (mock_uvicorn_server ):
504
- with patch ("asyncio.get_running_loop" ), \
505
- patch .object (mock_uvicorn_server .server , 'shutdown' , AsyncMock ()):
529
+ with (
530
+ patch ("asyncio.get_running_loop" ),
531
+ patch .object (mock_uvicorn_server .server , "shutdown" , AsyncMock ()),
532
+ ):
506
533
# Mock the loop or other components as needed
507
534
508
535
# Start the server or trigger the condition you want to test
0 commit comments