Fix migration workflow: upload as artifact instead of scp to practice EC2
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Test-suite defaults that must be set before any test module is imported.
|
||||
|
||||
`main.py` builds the entire runtime at module scope (`build_runtime(get_settings())`),
|
||||
and `tests/test_api.py` imports `main`. With the default `EMBEDDING_PROVIDER=cohere-v4`
|
||||
— or with a developer's `.env` selecting it — that construction opens a
|
||||
`QdrantClient` and calls `get_collections()` for the corpus-manifest check, so
|
||||
`pytest` fails during *collection* on any machine without a reachable Qdrant:
|
||||
|
||||
qdrant_client.http.exceptions.ResponseHandlingException:
|
||||
[WinError 10061] No connection could be made ...
|
||||
Interrupted: 1 error during collection
|
||||
|
||||
No unit test needs a live datastore: every test injects its own doubles, and
|
||||
the one suite that does need real services (`test_live_datastores.py`) gates
|
||||
itself behind `RUN_INTEGRATION=1`. Forcing the disabled provider here makes
|
||||
`pytest tests -q` work out of the box instead of requiring an undocumented
|
||||
environment variable.
|
||||
|
||||
`setdefault`, not assignment: a deliberate override (for example
|
||||
`EMBEDDING_PROVIDER=cohere-v4 pytest ...` against a local Qdrant) still wins.
|
||||
|
||||
This runs at import time, before pytest collects any module, which is the only
|
||||
point early enough — `config.get_settings()` is `lru_cache`d, so a fixture
|
||||
would already be too late.
|
||||
"""
|
||||
import os
|
||||
|
||||
os.environ.setdefault("EMBEDDING_PROVIDER", "disabled")
|
||||
@@ -1,3 +1,5 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from adapters.qdrant import QdrantRetriever, _source_refs
|
||||
|
||||
|
||||
@@ -24,6 +26,25 @@ class _FakeScrollClient:
|
||||
return [_FakePoint(p) for p in self._payloads], None
|
||||
|
||||
|
||||
class _FakeQueryPointsClient:
|
||||
"""Production qdrant-client shape (1.16+): no legacy `.search()`."""
|
||||
|
||||
def __init__(self, payloads: list[dict]) -> None:
|
||||
self._payloads = payloads
|
||||
self.kwargs = None
|
||||
|
||||
def query_points(self, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
return SimpleNamespace(points=[_FakePoint(p) for p in self._payloads])
|
||||
|
||||
|
||||
class _FakeEmbedder:
|
||||
dimensions = 3
|
||||
|
||||
def embed_query(self, text): # noqa: ARG002
|
||||
return [0.1, 0.2, 0.3]
|
||||
|
||||
|
||||
def _chi_dinh_payload(drug_id: str, text: str) -> dict:
|
||||
return {
|
||||
"chunk_id": f"{drug_id}__chi_dinh__0", "drug_id": drug_id,
|
||||
@@ -91,6 +112,20 @@ def test_find_by_indication_matches_a_drug_that_names_the_symptom():
|
||||
assert [h.document.drug_id for h in hits] == ["paracetamol_acetaminophen"]
|
||||
|
||||
|
||||
def test_dense_indication_fallback_uses_modern_query_points_api():
|
||||
client = _FakeQueryPointsClient([
|
||||
_chi_dinh_payload("colchicin", "Điều trị đợt cấp bệnh gút."),
|
||||
])
|
||||
retriever = QdrantRetriever(client, "duocthu_v1", _FakeEmbedder())
|
||||
|
||||
hits = retriever.search_indication("gút cấp", limit=4)
|
||||
|
||||
assert [hit.document.drug_id for hit in hits] == ["colchicin"]
|
||||
assert client.kwargs["collection_name"] == "duocthu_v1"
|
||||
assert client.kwargs["query"] == [0.1, 0.2, 0.3]
|
||||
assert client.kwargs["limit"] == 16
|
||||
|
||||
|
||||
def test_find_by_indication_requires_the_whole_phrase_not_a_scattered_match():
|
||||
""""sốt xuất huyết" (dengue) must not match a chunk that only says "sốt"
|
||||
— the phrase itself has to appear, not just each of its words somewhere."""
|
||||
|
||||
Reference in New Issue
Block a user