#!/usr/bin/env python3 """ Tests for the debug functionality of the SSL Manager. This module contains tests for the debug logging functionality. """ import os import sys import json import tempfile import unittest import logging from unittest.mock import patch, MagicMock from io import StringIO # Add the src directory to the Python path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from src.ssl_manager import setup_logging, load_config, SSLManager class TestDebugLogging(unittest.TestCase): """Test cases for debug logging functionality.""" def setUp(self): """Set up test fixtures.""" # Create a temporary directory for test files self.temp_dir = tempfile.TemporaryDirectory() # Sample config for testing self.test_config = { "cert_dir": "~/test-certs", "default_port": 8443, "connection_timeout": 5.0, "default_validity_days": 730, "key_size": 4096, "debug": True } # Create a temporary config file self.config_path = os.path.join(self.temp_dir.name, "test_config.json") with open(self.config_path, 'w') as f: json.dump(self.test_config, f) def tearDown(self): """Tear down test fixtures.""" # Clean up the temporary directory self.temp_dir.cleanup() def test_setup_logging_debug_enabled(self): """Test that setup_logging configures logging correctly when debug is enabled.""" # Capture log output log_capture = StringIO() handler = logging.StreamHandler(log_capture) # Patch the logging.basicConfig to use our handler with patch('logging.basicConfig') as mock_basic_config: # Call setup_logging with debug=True setup_logging(True) # Verify that logging was configured with DEBUG level mock_basic_config.assert_called_once() args, kwargs = mock_basic_config.call_args self.assertEqual(kwargs['level'], logging.DEBUG) # Verify that the format includes filename and line number self.assertIn('%(filename)s:%(lineno)d', kwargs['format']) def test_setup_logging_debug_disabled(self): """Test that setup_logging configures logging correctly when debug is disabled.""" # Patch the logging.basicConfig with patch('logging.basicConfig') as mock_basic_config: # Call setup_logging with debug=False setup_logging(False) # Verify that logging was configured with INFO level mock_basic_config.assert_called_once() args, kwargs = mock_basic_config.call_args self.assertEqual(kwargs['level'], logging.INFO) # Verify that the format does not include filename and line number self.assertNotIn('%(filename)s:%(lineno)d', kwargs['format']) def test_load_config_with_debug_enabled(self): """Test loading a configuration file with debug enabled.""" # Load the config config = load_config(self.config_path) # Verify the debug setting self.assertTrue(config["debug"]) @patch('sys.stdout', new_callable=StringIO) @patch('sys.stderr', new_callable=StringIO) def test_debug_output_format(self, mock_stderr, mock_stdout): """Test that debug output includes line numbers and file names.""" # Set up logging to capture output setup_logging(True) # Generate a debug log message logging.debug("Test debug message") # Get the captured output output = mock_stderr.getvalue() # Verify that the output includes the filename and line number self.assertIn('test_debug.py:', output) self.assertIn(' - Test debug message', output) if __name__ == '__main__': unittest.main()