mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-07-12 15:05:08 +00:00
refactor(search): replace context manager smell with explicit open/close lifecycle
TantivyBackend now uses open()/close()/_ensure_open() instead of __enter__/__exit__. get_backend() tracks _backend_path and auto-reinitializes when settings.INDEX_DIR changes, fixing the xdist/override_settings isolation bug where parallel workers would share a stale singleton pointing at a deleted index directory. Test fixtures use in-memory indices (path=None) for speed and isolation. Singleton behavior covered by TestSingleton in test_backend.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,8 +23,11 @@ def index_dir(tmp_path: Path, settings: SettingsWrapper) -> Path:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def backend(index_dir: Path) -> Generator[TantivyBackend, None, None]:
|
||||
b = TantivyBackend()
|
||||
with b:
|
||||
def backend() -> Generator[TantivyBackend, None, None]:
|
||||
b = TantivyBackend() # path=None → in-memory index
|
||||
b.open()
|
||||
try:
|
||||
yield b
|
||||
reset_backend()
|
||||
finally:
|
||||
b.close()
|
||||
reset_backend()
|
||||
|
||||
@@ -6,6 +6,8 @@ from documents.models import CustomFieldInstance
|
||||
from documents.models import Document
|
||||
from documents.models import Note
|
||||
from documents.search._backend import TantivyBackend
|
||||
from documents.search._backend import get_backend
|
||||
from documents.search._backend import reset_backend
|
||||
|
||||
pytestmark = [pytest.mark.search, pytest.mark.django_db]
|
||||
|
||||
@@ -161,6 +163,37 @@ class TestMoreLikeThis:
|
||||
assert 50 not in returned_ids # Original document excluded
|
||||
|
||||
|
||||
class TestSingleton:
|
||||
"""Test get_backend() and reset_backend() singleton lifecycle."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _clean(self):
|
||||
reset_backend()
|
||||
yield
|
||||
reset_backend()
|
||||
|
||||
def test_returns_same_instance_on_repeated_calls(self, index_dir):
|
||||
assert get_backend() is get_backend()
|
||||
|
||||
def test_reinitializes_when_index_dir_changes(self, tmp_path, settings):
|
||||
settings.INDEX_DIR = tmp_path / "a"
|
||||
(tmp_path / "a").mkdir()
|
||||
b1 = get_backend()
|
||||
|
||||
settings.INDEX_DIR = tmp_path / "b"
|
||||
(tmp_path / "b").mkdir()
|
||||
b2 = get_backend()
|
||||
|
||||
assert b1 is not b2
|
||||
assert b2._path == tmp_path / "b"
|
||||
|
||||
def test_reset_forces_new_instance(self, index_dir):
|
||||
b1 = get_backend()
|
||||
reset_backend()
|
||||
b2 = get_backend()
|
||||
assert b1 is not b2
|
||||
|
||||
|
||||
class TestFieldHandling:
|
||||
"""Test handling of various document fields."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user