Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit 367323e

Browse files
committed
add complete testsuite
1 parent 2848b27 commit 367323e

File tree

1 file changed

+159
-2
lines changed

1 file changed

+159
-2
lines changed

tests/test_cli.py

Lines changed: 159 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for the server module."""
22

3+
import os
34
from unittest.mock import MagicMock, patch, AsyncMock
45

56
import pytest
@@ -16,6 +17,7 @@
1617
from src.codegate.codegate_logging import LogLevel, LogFormat
1718
from uvicorn.config import Config as UvicornConfig
1819
from click.testing import CliRunner
20+
from pathlib import Path
1921

2022

2123
@pytest.fixture
@@ -277,7 +279,8 @@ def test_serve_custom_options(cli_runner):
277279

278280
# Check if Config object attributes match the expected values
279281
for key, expected_value in expected_values.items():
280-
assert getattr(config_arg, key) == expected_value, f"{key} does not match expected value"
282+
assert getattr(config_arg, key) == expected_value, \
283+
f"{key} does not match expected value"
281284

282285

283286
def test_serve_invalid_port(cli_runner):
@@ -326,7 +329,7 @@ def test_serve_with_config_file(cli_runner, temp_config_file):
326329

327330
# Validate that run_servers was called with the expected configuration
328331
mock_run.assert_called_once()
329-
config_arg = mock_run.call_args[0][0] # Assuming Config object is the first positional argument
332+
config_arg = mock_run.call_args[0][0]
330333

331334
# Define expected values based on the temp_config_file content
332335
expected_values = {
@@ -338,6 +341,160 @@ def test_serve_with_config_file(cli_runner, temp_config_file):
338341
}
339342

340343
# Check if passed arguments match the expected values
344+
for key, expected_value in expected_values.items():
345+
assert getattr(config_arg, key) == expected_value, \
346+
f"{key} does not match expected value"
347+
348+
349+
def test_serve_with_nonexistent_config_file(cli_runner: CliRunner) -> None:
350+
"""Test serve command with nonexistent config file."""
351+
result = cli_runner.invoke(cli, ["serve", "--config", "nonexistent.yaml"])
352+
assert result.exit_code == 2
353+
assert "does not exist" in result.output
354+
355+
356+
def test_serve_priority_resolution(cli_runner: CliRunner, temp_config_file: Path) -> None:
357+
"""Test serve command respects configuration priority."""
358+
# Set up environment variables and ensure they get cleaned up after the test
359+
with patch.dict(os.environ, {'LOG_LEVEL': 'INFO', 'PORT': '9999'}, clear=True), \
360+
patch('src.codegate.cli.run_servers') as mock_run, \
361+
patch('src.codegate.cli.structlog.get_logger') as mock_logging, \
362+
patch('src.codegate.cli.setup_logging') as mock_setup_logging:
363+
# Set up mock logger
364+
logger_instance = MagicMock()
365+
mock_logging.return_value = logger_instance
366+
367+
# Execute CLI command with specific options overriding environment and config file settings
368+
result = cli_runner.invoke(
369+
cli,
370+
[
371+
"serve",
372+
"--config",
373+
str(temp_config_file),
374+
"--port",
375+
"8080",
376+
"--host",
377+
"example.com",
378+
"--log-level",
379+
"ERROR",
380+
"--log-format",
381+
"TEXT",
382+
"--certs-dir",
383+
"./cli-certs",
384+
"--ca-cert",
385+
"cli-ca.crt",
386+
"--ca-key",
387+
"cli-ca.key",
388+
"--server-cert",
389+
"cli-server.crt",
390+
"--server-key",
391+
"cli-server.key",
392+
],
393+
)
394+
395+
# Check the result of the command
396+
assert result.exit_code == 0
397+
398+
# Ensure logging setup was called with the highest priority settings (CLI arguments)
399+
mock_setup_logging.assert_called_once_with('ERROR', 'TEXT')
400+
mock_logging.assert_called_with("codegate")
401+
402+
# Verify that the run_servers was called with the overridden settings
403+
config_arg = mock_run.call_args[0][0] # Assuming Config is the first positional arg
404+
405+
expected_values = {
406+
"port": 8080,
407+
"host": "example.com",
408+
"log_level": 'ERROR',
409+
"log_format": 'TEXT',
410+
"certs_dir": "./cli-certs",
411+
"ca_cert": "cli-ca.crt",
412+
"ca_key": "cli-ca.key",
413+
"server_cert": "cli-server.crt",
414+
"server_key": "cli-server.key",
415+
}
416+
417+
# Verify if Config object attributes match the expected values from CLI arguments
341418
for key, expected_value in expected_values.items():
342419
assert getattr(config_arg, key) == expected_value, f"{key} does not match expected value"
343420

421+
422+
def test_serve_certificate_options(cli_runner: CliRunner) -> None:
423+
"""Test serve command with certificate options."""
424+
with patch('src.codegate.cli.run_servers') as mock_run, \
425+
patch('src.codegate.cli.structlog.get_logger') as mock_logging, \
426+
patch('src.codegate.cli.setup_logging') as mock_setup_logging:
427+
# Set up mock logger
428+
logger_instance = MagicMock()
429+
mock_logging.return_value = logger_instance
430+
431+
# Execute CLI command with certificate options
432+
result = cli_runner.invoke(
433+
cli,
434+
[
435+
"serve",
436+
"--certs-dir",
437+
"./custom-certs",
438+
"--ca-cert",
439+
"custom-ca.crt",
440+
"--ca-key",
441+
"custom-ca.key",
442+
"--server-cert",
443+
"custom-server.crt",
444+
"--server-key",
445+
"custom-server.key",
446+
],
447+
)
448+
449+
# Check the result of the command
450+
assert result.exit_code == 0
451+
452+
# Ensure logging setup was called with expected arguments
453+
mock_setup_logging.assert_called_once_with('INFO', 'JSON')
454+
mock_logging.assert_called_with("codegate")
455+
456+
# Verify that run_servers was called with the provided certificate options
457+
config_arg = mock_run.call_args[0][0] # Assuming Config is the first positional arg
458+
459+
expected_values = {
460+
"certs_dir": "./custom-certs",
461+
"ca_cert": "custom-ca.crt",
462+
"ca_key": "custom-ca.key",
463+
"server_cert": "custom-server.crt",
464+
"server_key": "custom-server.key",
465+
}
466+
467+
# Check if Config object attributes match the expected values
468+
for key, expected_value in expected_values.items():
469+
assert getattr(config_arg, key) == expected_value, f"{key} does not match expected value"
470+
471+
472+
def test_main_function() -> None:
473+
"""Test main function."""
474+
with patch("sys.argv", ["cli"]), patch("codegate.cli.cli") as mock_cli:
475+
from codegate.cli import main
476+
main()
477+
mock_cli.assert_called_once()
478+
479+
480+
@pytest.fixture
481+
def mock_uvicorn_server():
482+
mock_config = MagicMock() # Setup the configuration mock
483+
mock_server = MagicMock(spec=UvicornServer)
484+
mock_server.shutdown = AsyncMock() # Ensure shutdown is an async mock
485+
486+
uvicorn_server = UvicornServer(config=mock_config, server=mock_server)
487+
return uvicorn_server
488+
489+
490+
@pytest.mark.asyncio
491+
async def test_uvicorn_server_cleanup(mock_uvicorn_server):
492+
with patch("asyncio.get_running_loop"), \
493+
patch.object(mock_uvicorn_server.server, 'shutdown', AsyncMock()):
494+
# Mock the loop or other components as needed
495+
496+
# Start the server or trigger the condition you want to test
497+
await mock_uvicorn_server.cleanup() # This should now complete without error
498+
499+
# Verify that the shutdown was called
500+
mock_uvicorn_server.server.shutdown.assert_awaited_once()

0 commit comments

Comments
 (0)