# Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. """Tests for anta.logger.""" from __future__ import annotations import logging from unittest.mock import patch import pytest from anta.logger import anta_log_exception, exc_to_str, tb_to_str @pytest.mark.parametrize( ("exception", "message", "calling_logger", "debug_value", "expected_message"), [ pytest.param( ValueError("exception message"), None, None, False, "ValueError: exception message", id="exception only", ), pytest.param( ValueError("exception message"), "custom message", None, False, "custom message\nValueError: exception message", id="custom message", ), pytest.param( ValueError("exception message"), "custom logger", logging.getLogger("custom"), False, "custom logger\nValueError: exception message", id="custom logger", ), pytest.param( ValueError("exception message"), "Use with custom message", None, True, "Use with custom message\nValueError: exception message", id="__DEBUG__ on", ), ], ) def test_anta_log_exception( caplog: pytest.LogCaptureFixture, exception: Exception, message: str | None, calling_logger: logging.Logger | None, debug_value: bool, expected_message: str, ) -> None: # pylint: disable=too-many-arguments """Test anta_log_exception.""" if calling_logger is not None: # https://github.com/pytest-dev/pytest/issues/3697 calling_logger.propagate = True caplog.set_level(logging.ERROR, logger=calling_logger.name) else: caplog.set_level(logging.ERROR) # Need to raise to trigger nice stacktrace for __DEBUG__ == True try: raise exception except ValueError as exc: with patch("anta.logger.__DEBUG__", new=debug_value): anta_log_exception(exc, message=message, calling_logger=calling_logger) # Two log captured if debug_value: assert len(caplog.record_tuples) == 2 else: assert len(caplog.record_tuples) == 1 logger, level, message = caplog.record_tuples[0] if calling_logger is not None: assert calling_logger.name == logger else: assert logger == "anta.logger" assert level == logging.CRITICAL assert message == expected_message # the only place where we can see the stracktrace is in the capture.text if debug_value: assert "Traceback" in caplog.text def my_raising_function(exception: Exception) -> None: """Raise Exception.""" raise exception @pytest.mark.parametrize( ("exception", "expected_output"), [(ValueError("test"), "ValueError: test"), (ValueError(), "ValueError")], ) def test_exc_to_str(exception: Exception, expected_output: str) -> None: """Test exc_to_str.""" assert exc_to_str(exception) == expected_output def test_tb_to_str() -> None: """Test tb_to_str.""" try: my_raising_function(ValueError("test")) except ValueError as exc: output = tb_to_str(exc) assert "Traceback" in output assert 'my_raising_function(ValueError("test"))' in output