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

Commit 7c4e0c9

Browse files
committed
add complete testsuite
1 parent 2848b27 commit 7c4e0c9

File tree

1 file changed

+162
-3
lines changed

1 file changed

+162
-3
lines changed

tests/test_cli.py

Lines changed: 162 additions & 3 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 = {
@@ -339,5 +342,161 @@ def test_serve_with_config_file(cli_runner, temp_config_file):
339342

340343
# Check if passed arguments match the expected values
341344
for key, expected_value in expected_values.items():
342-
assert getattr(config_arg, key) == expected_value, f"{key} does not match expected value"
345+
assert getattr(config_arg, key) == expected_value, \
346+
f"{key} does not match expected value"
343347

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

0 commit comments

Comments
 (0)