Skip to main content
Glama

mcp-server-tree-sitter

by wrale
MIT License
175
  • Apple
  • Linux
test_logging_handlers.py11.5 kB
"""Tests for handler level synchronization in logging configuration.""" import io import logging from contextlib import contextmanager # Import from bootstrap module rather than logging_config from mcp_server_tree_sitter.bootstrap import get_logger, update_log_levels @contextmanager def temp_logger(name="mcp_server_tree_sitter.test_handlers"): """Create a temporary logger for testing.""" logger = logging.getLogger(name) # Save original settings original_level = logger.level original_handlers = logger.handlers.copy() original_propagate = logger.propagate # Create handlers with different levels for testing debug_handler = logging.StreamHandler() debug_handler.setLevel(logging.DEBUG) info_handler = logging.StreamHandler() info_handler.setLevel(logging.INFO) warning_handler = logging.StreamHandler() warning_handler.setLevel(logging.WARNING) # Add handlers and set initial level logger.handlers = [debug_handler, info_handler, warning_handler] logger.setLevel(logging.INFO) try: yield logger finally: # Restore original settings logger.handlers = original_handlers logger.setLevel(original_level) logger.propagate = original_propagate def test_handler_level_synchronization(): """Test that handler levels are synchronized with logger's effective level.""" # Set up test environment root_logger = logging.getLogger("mcp_server_tree_sitter") original_root_level = root_logger.level original_root_handlers = root_logger.handlers.copy() # Create a non-root logger to test proper hierarchical behavior test_logger = logging.getLogger("mcp_server_tree_sitter.handlers_test") original_test_level = test_logger.level original_test_handlers = test_logger.handlers.copy() # Ensure test logger has no explicit level set (should inherit from root) test_logger.setLevel(logging.NOTSET) # Add handlers with different levels for testing debug_handler = logging.StreamHandler() debug_handler.setLevel(logging.DEBUG) info_handler = logging.StreamHandler() info_handler.setLevel(logging.INFO) warning_handler = logging.StreamHandler() warning_handler.setLevel(logging.WARNING) # Add handlers to the test logger test_logger.handlers = [debug_handler, info_handler, warning_handler] try: # Initial state verification assert test_logger.level == logging.NOTSET, "Test logger should not have explicit level" assert test_logger.getEffectiveLevel() == root_logger.level, "Effective level should be inherited from root" # Initial handler levels assert test_logger.handlers[0].level == logging.DEBUG assert test_logger.handlers[1].level == logging.INFO assert test_logger.handlers[2].level == logging.WARNING # Update root logger to DEBUG update_log_levels("DEBUG") # Child logger level should NOT be explicitly changed assert test_logger.level == logging.NOTSET, "Child logger level should NOT be explicitly set" # Effective level should now be DEBUG through inheritance assert test_logger.getEffectiveLevel() == logging.DEBUG, "Effective level should be DEBUG through inheritance" # All handlers should now be at DEBUG level (synchronized to effective level) assert test_logger.handlers[0].level == logging.DEBUG assert test_logger.handlers[1].level == logging.DEBUG assert test_logger.handlers[2].level == logging.DEBUG # Update root logger to WARNING update_log_levels("WARNING") # Child logger level should still not be explicitly changed assert test_logger.level == logging.NOTSET, "Child logger level should NOT be explicitly set" # Effective level should now be WARNING through inheritance assert test_logger.getEffectiveLevel() == logging.WARNING, ( "Effective level should be WARNING through inheritance" ) # All handlers should now be at WARNING level (synchronized to effective level) assert test_logger.handlers[0].level == logging.WARNING assert test_logger.handlers[1].level == logging.WARNING assert test_logger.handlers[2].level == logging.WARNING finally: # Restore original state root_logger.handlers = original_root_handlers root_logger.setLevel(original_root_level) test_logger.handlers = original_test_handlers test_logger.setLevel(original_test_level) def test_get_logger_handler_sync(): """Test that get_logger creates loggers with proper level inheritance and synchronized handler levels.""" # Set up test environment root_logger = logging.getLogger("mcp_server_tree_sitter") original_root_level = root_logger.level # Create a child logger with our utility logger_name = "mcp_server_tree_sitter.test_get_logger" # First, ensure we start with a clean state existing_logger = logging.getLogger(logger_name) original_level = existing_logger.level original_handlers = existing_logger.handlers.copy() existing_logger.handlers = [] existing_logger.setLevel(logging.NOTSET) # Clear any explicit level try: # Get logger with utility function test_logger = get_logger(logger_name) # Child logger should NOT have an explicit level set assert test_logger.level == logging.NOTSET, "Child logger should not have explicit level set" # Child logger should inherit level from root package logger assert test_logger.getEffectiveLevel() == root_logger.level, "Child logger should inherit level from root" # Add a handler and manually set its level to match the logger's effective level handler = logging.StreamHandler() test_logger.addHandler(handler) # Manually set handler level after adding it handler.setLevel(test_logger.getEffectiveLevel()) # Now verify that handler matches logger's effective level assert handler.level == test_logger.getEffectiveLevel(), "Handler should match logger's effective level" # Update log levels to DEBUG update_log_levels("DEBUG") # Child logger should still NOT have explicit level assert test_logger.level == logging.NOTSET, "Child logger should not have explicit level set after update" # Child logger should inherit DEBUG from root assert test_logger.getEffectiveLevel() == logging.DEBUG, "Child logger should inherit DEBUG from root" # Handler should be updated to match effective level assert handler.level == logging.DEBUG, "Handler should match logger's effective level (DEBUG)" # Update log levels to WARNING update_log_levels("WARNING") # Child logger should still NOT have explicit level assert test_logger.level == logging.NOTSET, ( "Child logger should not have explicit level set after second update" ) # Child logger should inherit WARNING from root assert test_logger.getEffectiveLevel() == logging.WARNING, "Child logger should inherit WARNING from root" # Handler should be updated to match effective level assert handler.level == logging.WARNING, "Handler should match logger's effective level (WARNING)" # Test root logger behavior root_test_logger = get_logger("mcp_server_tree_sitter") root_handler = logging.StreamHandler() root_test_logger.addHandler(root_handler) # Manually set the handler level to match the logger's level root_handler.setLevel(root_test_logger.level) # Root logger should have explicit level assert root_test_logger.level != logging.NOTSET, "Root logger should have explicit level set" # Handler should match root logger's level assert root_handler.level == root_test_logger.level, "Root logger handler should match logger level" finally: # Restore original state existing_logger.handlers = original_handlers existing_logger.setLevel(original_level) root_logger.setLevel(original_root_level) def test_multiple_handlers_with_log_streams(): """Test that multiple handlers all pass the appropriate log messages.""" # Create handlers with capture buffers debug_capture = io.StringIO() debug_handler = logging.StreamHandler(debug_capture) debug_handler.setLevel(logging.DEBUG) debug_handler.setFormatter(logging.Formatter("DEBUG_HANDLER:%(message)s")) info_capture = io.StringIO() info_handler = logging.StreamHandler(info_capture) info_handler.setLevel(logging.INFO) info_handler.setFormatter(logging.Formatter("INFO_HANDLER:%(message)s")) # Create test logger logger_name = "mcp_server_tree_sitter.test_multiple" test_logger = logging.getLogger(logger_name) # Save original settings original_level = test_logger.level original_handlers = test_logger.handlers.copy() original_propagate = test_logger.propagate # Configure logger for test test_logger.handlers = [debug_handler, info_handler] test_logger.propagate = False try: # Initial state - set to INFO test_logger.setLevel(logging.INFO) # Log messages at different levels test_logger.debug("Debug message that should be filtered") test_logger.info("Info message that should appear") test_logger.warning("Warning message that should appear") # Check debug handler - should only have INFO and WARNING messages debug_logs = debug_capture.getvalue() assert "Debug message that should be filtered" not in debug_logs assert "Info message that should appear" in debug_logs assert "Warning message that should appear" in debug_logs # Check info handler - should only have INFO and WARNING messages info_logs = info_capture.getvalue() assert "Debug message that should be filtered" not in info_logs assert "Info message that should appear" in info_logs assert "Warning message that should appear" in info_logs # Now update log levels to DEBUG and explicitly set handler levels test_logger.setLevel(logging.DEBUG) # Important: Explicitly update the handler levels after changing the logger level debug_handler.setLevel(logging.DEBUG) info_handler.setLevel(logging.DEBUG) # Clear previous captures debug_capture.truncate(0) debug_capture.seek(0) info_capture.truncate(0) info_capture.seek(0) # Log messages again test_logger.debug("Debug message that should now appear") test_logger.info("Info message that should appear") # Check debug handler - should have both messages debug_logs = debug_capture.getvalue() assert "Debug message that should now appear" in debug_logs assert "Info message that should appear" in debug_logs # Check info handler - should now also have both messages # because we explicitly set the handler levels to DEBUG info_logs = info_capture.getvalue() assert "Debug message that should now appear" in info_logs assert "Info message that should appear" in info_logs finally: # Restore original settings test_logger.handlers = original_handlers test_logger.setLevel(original_level) test_logger.propagate = original_propagate

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wrale/mcp-server-tree-sitter'

If you have feedback or need assistance with the MCP directory API, please join our Discord server