PDF-Assit_RAG / backend /tests /test_chunk_settings_concurrency.py
Param20h's picture
deploy: pure backend API with keywords fix
7c46845 unverified
Raw
History Blame Contribute Delete
3.04 kB
"""Regression tests for re-chunking a document while it is
still processing must not queue a second concurrent ingestion run.
update_chunk_settings previously reset doc.status to "pending" and
re-queued process_document.delay(...) unconditionally, with no check on
the document's current status. If a prior ingestion run for the same
document_id was still "processing", this let two ingestion runs execute
concurrently against the same document - and since store_chunks() in
vectorstore.py performs a non-atomic delete-then-batch-insert sequence,
the two runs could interleave and corrupt the vector store relative to
whatever chunk_count ends up persisted in Postgres.
"""
from app.models import Document
def test_update_chunk_settings_rejects_while_document_processing(
client, auth_headers, db_session, user, monkeypatch
):
"""A document mid-ingestion must reject a re-chunk request with 409,
not silently reset its status and re-queue a second concurrent run.
"""
document = Document(
user_id=user.id,
filename="processing.pdf",
original_name="processing.pdf",
file_size=256,
status="processing",
chunk_count=0,
page_count=0,
)
db_session.add(document)
db_session.commit()
db_session.refresh(document)
def _delay_should_not_be_called(*args, **kwargs):
raise AssertionError(
"process_document.delay was called for a document still "
"processing - the concurrency guard did not reject the request"
)
monkeypatch.setattr(
"app.routes.documents.process_document.delay",
_delay_should_not_be_called,
)
response = client.post(
f"/api/v1/documents/{document.id}/chunk_settings",
json={"chunk_size": 500, "chunk_overlap": 50},
headers=auth_headers,
)
assert response.status_code == 409
refreshed = db_session.get(Document, document.id)
assert refreshed.status == "processing"
assert refreshed.chunk_count == 0
assert refreshed.page_count == 0
def test_update_chunk_settings_allows_when_not_processing(
client, auth_headers, ready_document, db_session, monkeypatch
):
"""A document that is "ready" (i.e. not mid-ingestion) must still be
allowed to re-chunk - the guard should only block "processing".
"""
queued = {}
class _FakeTask:
id = "fake-task-id"
def _fake_delay(**kwargs):
queued.update(kwargs)
return _FakeTask()
monkeypatch.setattr("app.routes.documents.process_document.delay", _fake_delay)
response = client.post(
f"/api/v1/documents/{ready_document.id}/chunk_settings",
json={"chunk_size": 500, "chunk_overlap": 50},
headers=auth_headers,
)
assert response.status_code == 200
assert queued["document_id"] == ready_document.id
refreshed = db_session.get(Document, ready_document.id)
assert refreshed.status == "pending"
assert refreshed.chunk_size == 500
assert refreshed.chunk_overlap == 50