mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-10-02 19:21:50 +00:00
lib/enrichment.py now owns the worker, and it stays imported for the whole session while the `server` fixtures pop-and-reimport `server` — so the cancel Event / status dict / caches would leak across tests, and a stale `_enrich_cancel` could short-circuit a later direct `_background_enrich()`. An autouse conftest fixture clears that process-global state before each test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
"""Shared pytest fixtures for the feedBack test suite."""
|
|
|
|
import logging
|
|
|
|
import pytest
|
|
import structlog
|
|
|
|
|
|
_LOGGING_NAMES = ("feedBack", "uvicorn", "uvicorn.error", "uvicorn.access")
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _reset_enrichment_state():
|
|
"""Reset the enrichment worker's process-global state between tests.
|
|
|
|
The `server` fixtures pop-and-reimport `server`, but `lib/enrichment.py`
|
|
(which now owns the worker) stays imported for the whole session, so its
|
|
module globals — the cancel Event, the status dict, the caches — would
|
|
otherwise leak across tests. A test that set `_enrich_cancel` (or a stale
|
|
`running` status) could silently short-circuit a later direct
|
|
`_background_enrich()` call. Clear it up front so each test starts clean.
|
|
"""
|
|
try:
|
|
import enrichment
|
|
except Exception:
|
|
yield
|
|
return
|
|
enrichment._enrich_cancel.clear()
|
|
enrichment._enrich_pending_pass = False
|
|
enrichment._enrich_status.update(
|
|
{"running": False, "processed": 0, "last_pass_at": None,
|
|
"total": 0, "matched": 0, "current": None})
|
|
enrichment._enrich_last_fetch = 0.0
|
|
enrichment._artist_alias_cache.clear()
|
|
enrichment._caa_index_locks.clear()
|
|
yield
|
|
|
|
|
|
@pytest.fixture()
|
|
def isolate_logging():
|
|
"""Restore feedBack / uvicorn logger state after each test.
|
|
|
|
Saves handlers, level, and propagate flag before the test runs and
|
|
restores all three on teardown. Import into any test module that calls
|
|
configure_logging() so mutations don't bleed across tests.
|
|
"""
|
|
saved = {}
|
|
for name in _LOGGING_NAMES:
|
|
lg = logging.getLogger(name)
|
|
saved[name] = (
|
|
list(lg.handlers), # snapshot the handler list
|
|
lg.level,
|
|
lg.propagate,
|
|
)
|
|
yield
|
|
for name in _LOGGING_NAMES:
|
|
lg = logging.getLogger(name)
|
|
original_handlers, original_level, original_propagate = saved[name]
|
|
|
|
# Close and remove any handlers that were added during the test.
|
|
for h in list(lg.handlers):
|
|
if h not in original_handlers:
|
|
lg.removeHandler(h)
|
|
h.close()
|
|
# Remove any original handlers that may have been removed during the test
|
|
# so we can add them back cleanly.
|
|
for h in list(lg.handlers):
|
|
lg.removeHandler(h)
|
|
# Reattach the original handlers.
|
|
for h in original_handlers:
|
|
lg.addHandler(h)
|
|
|
|
lg.setLevel(original_level)
|
|
lg.propagate = original_propagate
|
|
structlog.reset_defaults()
|