Multi-instance failover, exponential-backoff retry, SQLite cache, batch mode, domain filter, cross-engine dedup, result sorting, CSV export, structured logging, enhanced Markdown conversion, 155 pytest tests, Gitea Actions CI
121 lines
3.4 KiB
Python
121 lines
3.4 KiB
Python
"""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
|