"""Tests for the shared logging configuration (setup_logging). Verifies: * Default level is INFO (matches previous print-to-stderr behavior). * --verbose sets DEBUG. * --quiet sets WARNING. * All log output goes to stderr, never stdout. * Repeated setup calls don't stack duplicate handlers. * Child loggers (searxng.search, searxng.fetch, searxng.common) inherit the root searxng logger's level. """ import logging import sys from common import setup_logging _ROOT = logging.getLogger("searxng") def _reset_logger(): """Clear the searxng logger so each test starts fresh.""" _ROOT.handlers.clear() _ROOT.setLevel(logging.NOTSET) def test_setup_logging_default_info(): _reset_logger() setup_logging() assert _ROOT.level == logging.INFO def test_setup_logging_verbose_debug(): _reset_logger() setup_logging(verbose=True) assert _ROOT.level == logging.DEBUG def test_setup_logging_quiet_warning(): _reset_logger() setup_logging(quiet=True) assert _ROOT.level == logging.WARNING def test_setup_logging_verbose_overrides_quiet(): """If both --verbose and --quiet are passed, verbose wins (checked first).""" _reset_logger() setup_logging(verbose=True, quiet=True) assert _ROOT.level == logging.DEBUG def test_setup_logging_no_duplicate_handlers(): _reset_logger() setup_logging() setup_logging() setup_logging() assert len(_ROOT.handlers) == 1 def test_setup_logging_output_to_stderr(capsys): """Log messages must go to stderr, never stdout.""" _reset_logger() setup_logging() log = logging.getLogger("searxng.search") log.info("test message") captured = capsys.readouterr() assert "test message" in captured.err assert captured.out == "" def test_child_logger_inherits_level(): """Child loggers (searxng.search, searxng.fetch, searxng.common) must see the level set on the root searxng logger.""" _reset_logger() setup_logging(verbose=True) for name in ("searxng.search", "searxng.fetch", "searxng.common"): child = logging.getLogger(name) assert child.getEffectiveLevel() == logging.DEBUG def test_quiet_suppresses_info(capsys): """In quiet mode, INFO messages are NOT written to stderr.""" _reset_logger() setup_logging(quiet=True) log = logging.getLogger("searxng.search") log.info("this should be hidden") log.warning("this should be visible") captured = capsys.readouterr() assert "this should be hidden" not in captured.err assert "this should be visible" in captured.err def test_verbose_shows_debug(capsys): """In verbose mode, DEBUG messages ARE written to stderr.""" _reset_logger() setup_logging(verbose=True) log = logging.getLogger("searxng.fetch") log.debug("debug detail") captured = capsys.readouterr() assert "debug detail" in captured.err def test_default_hides_debug(capsys): """In default (INFO) mode, DEBUG messages are NOT written to stderr.""" _reset_logger() setup_logging() log = logging.getLogger("searxng.search") log.debug("hidden debug") log.info("visible info") captured = capsys.readouterr() assert "hidden debug" not in captured.err assert "visible info" in captured.err def test_propagate_disabled(): """The searxng logger must not propagate to the root logger (avoids duplicate output via the root handler).""" _reset_logger() setup_logging() assert _ROOT.propagate is False