11"""Tests for the server module."""
22
33import os
4- from unittest .mock import MagicMock , patch , AsyncMock
4+ from pathlib import Path
5+ from unittest .mock import AsyncMock , MagicMock , patch
56
67import pytest
8+ from click .testing import CliRunner
79from fastapi .middleware .cors import CORSMiddleware
810from fastapi .testclient import TestClient
911from httpx import AsyncClient
12+ from uvicorn .config import Config as UvicornConfig
1013
1114from codegate import __version__
1215from codegate .pipeline .factory import PipelineFactory
1316from codegate .pipeline .secrets .manager import SecretsManager
1417from codegate .providers .registry import ProviderRegistry
1518from 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
2221
2322
2423@pytest .fixture
@@ -176,12 +175,12 @@ def mock_app():
176175@pytest .fixture
177176def uvicorn_config (mock_app ):
178177 # 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" )
180179
181180
182181@pytest .fixture
183182def 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 :
185184 mock_server_instance = mock_server_class .return_value
186185 mock_server_instance .serve = AsyncMock ()
187186 yield UvicornServer (uvicorn_config , mock_server_instance )
@@ -200,20 +199,22 @@ def cli_runner():
200199
201200@pytest .fixture
202201def mock_logging (mocker ):
203- return mocker .patch (' your_cli_module.structlog.get_logger' )
202+ return mocker .patch (" your_cli_module.structlog.get_logger" )
204203
205204
206205@pytest .fixture
207206def mock_setup_logging (mocker ):
208- return mocker .patch (' your_cli_module.setup_logging' )
207+ return mocker .patch (" your_cli_module.setup_logging" )
209208
210209
211210def test_serve_default_options (cli_runner ):
212211 """Test serve command with default options."""
213212 # 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+ ):
217218
218219 logger_instance = MagicMock ()
219220 mock_logging .return_value = logger_instance
@@ -236,9 +237,11 @@ def test_serve_default_options(cli_runner):
236237
237238def test_serve_custom_options (cli_runner ):
238239 """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+ ):
242245
243246 logger_instance = MagicMock ()
244247 mock_logging .return_value = logger_instance
@@ -248,15 +251,24 @@ def test_serve_custom_options(cli_runner):
248251 cli ,
249252 [
250253 "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" ,
260272 ],
261273 )
262274
@@ -289,8 +301,9 @@ def test_serve_custom_options(cli_runner):
289301
290302 # Check if Config object attributes match the expected values
291303 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"
294307
295308
296309def test_serve_invalid_port (cli_runner ):
@@ -310,21 +323,25 @@ def test_serve_invalid_log_level(cli_runner):
310323@pytest .fixture
311324def temp_config_file (tmp_path ):
312325 config_path = tmp_path / "config.yaml"
313- config_path .write_text ("""
326+ config_path .write_text (
327+ """
314328 log_level: DEBUG
315329 log_format: JSON
316330 port: 8989
317331 host: localhost
318332 certs_dir: ./test-certs
319- """ )
333+ """
334+ )
320335 return config_path
321336
322337
323338def test_serve_with_config_file (cli_runner , temp_config_file ):
324339 """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+ ):
328345
329346 logger_instance = MagicMock ()
330347 mock_logging .return_value = logger_instance
@@ -352,8 +369,9 @@ def test_serve_with_config_file(cli_runner, temp_config_file):
352369
353370 # Check if passed arguments match the expected values
354371 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"
357375
358376
359377def 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:
366384def test_serve_priority_resolution (cli_runner : CliRunner , temp_config_file : Path ) -> None :
367385 """Test serve command respects configuration priority."""
368386 # 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+ ):
373393 # Set up mock logger
374394 logger_instance = MagicMock ()
375395 mock_logging .return_value = logger_instance
@@ -406,7 +426,7 @@ def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path
406426 assert result .exit_code == 0
407427
408428 # 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" )
410430 mock_logging .assert_called_with ("codegate" )
411431
412432 # 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
415435 expected_values = {
416436 "port" : 8080 ,
417437 "host" : "example.com" ,
418- "log_level" : ' ERROR' ,
419- "log_format" : ' TEXT' ,
438+ "log_level" : " ERROR" ,
439+ "log_format" : " TEXT" ,
420440 "certs_dir" : "./cli-certs" ,
421441 "ca_cert" : "cli-ca.crt" ,
422442 "ca_key" : "cli-ca.key" ,
@@ -426,15 +446,18 @@ def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path
426446
427447 # Verify if Config object attributes match the expected values from CLI arguments
428448 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"
431452
432453
433454def test_serve_certificate_options (cli_runner : CliRunner ) -> None :
434455 """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+ ):
438461 # Set up mock logger
439462 logger_instance = MagicMock ()
440463 mock_logging .return_value = logger_instance
@@ -461,7 +484,7 @@ def test_serve_certificate_options(cli_runner: CliRunner) -> None:
461484 assert result .exit_code == 0
462485
463486 # 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" )
465488 mock_logging .assert_called_with ("codegate" )
466489
467490 # Verify that run_servers was called with the provided certificate options
@@ -477,14 +500,16 @@ def test_serve_certificate_options(cli_runner: CliRunner) -> None:
477500
478501 # Check if Config object attributes match the expected values
479502 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"
482506
483507
484508def test_main_function () -> None :
485509 """Test main function."""
486510 with patch ("sys.argv" , ["cli" ]), patch ("codegate.cli.cli" ) as mock_cli :
487511 from codegate .cli import main
512+
488513 main ()
489514 mock_cli .assert_called_once ()
490515
@@ -501,8 +526,10 @@ def mock_uvicorn_server():
501526
502527@pytest .mark .asyncio
503528async 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+ ):
506533 # Mock the loop or other components as needed
507534
508535 # Start the server or trigger the condition you want to test
0 commit comments