TradingAgents/tests/test_logging.py

170 lines
7.1 KiB
Python

import json
import logging
import os
import tempfile
import pytest
from unittest.mock import patch
class TestLoggingModule:
@pytest.fixture(autouse=True)
def setup_and_teardown(self):
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
tradingagents_logger = logging.getLogger("tradingagents")
for handler in tradingagents_logger.handlers[:]:
tradingagents_logger.removeHandler(handler)
tradingagents_logger.setLevel(logging.NOTSET)
yield
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
tradingagents_logger = logging.getLogger("tradingagents")
for handler in tradingagents_logger.handlers[:]:
tradingagents_logger.removeHandler(handler)
def test_setup_logging_initializes_handlers_based_on_env_vars(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "DEBUG",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "false",
"TRADINGAGENTS_LOG_FILE": "true",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
root_logger = log_module.setup_logging()
assert root_logger is not None
assert root_logger.name == "tradingagents"
assert root_logger.level == logging.DEBUG
has_file_handler = any(
hasattr(h, "baseFilename") for h in root_logger.handlers
)
assert has_file_handler, "File handler should be present when LOG_FILE=true"
def test_get_logger_returns_properly_configured_logger_with_hierarchy(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "INFO",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "false",
"TRADINGAGENTS_LOG_FILE": "true",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
log_module.setup_logging()
child_logger = log_module.get_logger("tradingagents.dataflows.interface")
assert child_logger.name == "tradingagents.dataflows.interface"
assert child_logger.parent.name == "tradingagents.dataflows" or child_logger.parent.name == "tradingagents"
def test_json_file_handler_writes_valid_json_with_required_fields(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "DEBUG",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "false",
"TRADINGAGENTS_LOG_FILE": "true",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
logger = log_module.setup_logging()
logger.info("Test message for JSON validation")
for handler in logger.handlers:
handler.flush()
log_file_path = os.path.join(tmpdir, "tradingagents.log")
assert os.path.exists(log_file_path), f"Log file should exist at {log_file_path}"
with open(log_file_path, "r") as f:
log_content = f.read().strip()
assert log_content, "Log file should not be empty"
log_entry = json.loads(log_content.split("\n")[0])
required_fields = ["timestamp", "level", "logger", "message", "filename", "funcName", "lineno"]
for field in required_fields:
assert field in log_entry, f"JSON log should contain '{field}' field"
assert "T" in log_entry["timestamp"], "Timestamp should be in ISO 8601 format"
assert log_entry["level"] == "INFO"
assert log_entry["message"] == "Test message for JSON validation"
def test_log_rotation_triggers_at_configured_file_size(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "DEBUG",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "false",
"TRADINGAGENTS_LOG_FILE": "true",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
logger = log_module.setup_logging()
file_handler = None
for handler in logger.handlers:
if hasattr(handler, "maxBytes"):
file_handler = handler
break
assert file_handler is not None, "RotatingFileHandler should be configured"
assert file_handler.maxBytes == 10 * 1024 * 1024, "Max file size should be 10MB"
assert file_handler.backupCount == 5, "Backup count should be 5"
def test_console_handler_disabled_when_env_var_false(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "INFO",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "false",
"TRADINGAGENTS_LOG_FILE": "true",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
logger = log_module.setup_logging()
from rich.logging import RichHandler
has_rich_handler = any(isinstance(h, RichHandler) for h in logger.handlers)
assert not has_rich_handler, "RichHandler should NOT be present when LOG_CONSOLE=false"
def test_console_handler_enabled_when_env_var_true(self):
with tempfile.TemporaryDirectory() as tmpdir:
env_vars = {
"TRADINGAGENTS_LOG_LEVEL": "INFO",
"TRADINGAGENTS_LOG_DIR": tmpdir,
"TRADINGAGENTS_LOG_CONSOLE": "true",
"TRADINGAGENTS_LOG_FILE": "false",
}
with patch.dict(os.environ, env_vars, clear=False):
import importlib
import tradingagents.logging as log_module
importlib.reload(log_module)
logger = log_module.setup_logging()
from rich.logging import RichHandler
has_rich_handler = any(isinstance(h, RichHandler) for h in logger.handlers)
assert has_rich_handler, "RichHandler should be present when LOG_CONSOLE=true"