99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
from dataclasses import FrozenInstanceError
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from tht.adapters.vector.qdrant import QdrantVectorStore
|
|
from tht.ports.vector import (
|
|
VectorReadUnavailable,
|
|
VectorStore,
|
|
VectorStoreError,
|
|
)
|
|
|
|
|
|
def test_vector_contract_is_exported_from_public_packages():
|
|
from tht.adapters.vector import QdrantVectorStore as PublicQdrantStore
|
|
from tht.ports import VectorReadUnavailable as PublicVectorReadUnavailable
|
|
from tht.ports import VectorStore as PublicVectorStore
|
|
|
|
assert PublicQdrantStore is QdrantVectorStore
|
|
assert PublicVectorStore is VectorStore
|
|
assert PublicVectorReadUnavailable is VectorReadUnavailable
|
|
|
|
capabilities = store_capabilities = QdrantVectorStore(
|
|
base_url="http://qdrant:6333",
|
|
collection="workspace-semantic",
|
|
workspace_id="demo",
|
|
expected_dimension=1024,
|
|
request=lambda *args, **kwargs: MagicMock(
|
|
ok=True,
|
|
status_code=200,
|
|
text='{"result":{"config":{"params":{"vectors":{"size":1024,"distance":"Cosine"}}},"payload_schema":{}}}',
|
|
json=lambda: {
|
|
"result": {
|
|
"config": {"params": {"vectors": {"size": 1024, "distance": "Cosine"}}},
|
|
"payload_schema": {},
|
|
}
|
|
},
|
|
),
|
|
).capabilities
|
|
assert capabilities.search is True
|
|
with pytest.raises(FrozenInstanceError):
|
|
store_capabilities.search = False
|
|
|
|
|
|
@pytest.mark.parametrize("limit", [True, False, 1.0, 0, -1])
|
|
def test_qdrant_search_requires_a_strict_positive_integer_limit(limit):
|
|
store = QdrantVectorStore(
|
|
base_url="http://qdrant:6333",
|
|
collection="workspace-semantic",
|
|
workspace_id="demo",
|
|
expected_dimension=1024,
|
|
request=lambda *args, **kwargs: MagicMock(
|
|
ok=True,
|
|
status_code=200,
|
|
text='{"result":{"points":[]}}',
|
|
json=lambda: {"result": {"points": []}},
|
|
),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="positive integer"):
|
|
store.search(["memory"], [0.1] * 1024, limit=limit)
|
|
|
|
|
|
def test_qdrant_search_rejects_dimension_mismatches_before_transport():
|
|
seen = []
|
|
store = QdrantVectorStore(
|
|
base_url="http://qdrant:6333",
|
|
collection="workspace-semantic",
|
|
workspace_id="demo",
|
|
expected_dimension=1024,
|
|
request=lambda *args, **kwargs: seen.append((args, kwargs)),
|
|
)
|
|
|
|
with pytest.raises(VectorStoreError, match="dimension"):
|
|
store.search(["memory"], [0.1], limit=1)
|
|
|
|
assert seen == []
|
|
|
|
|
|
def test_qdrant_store_is_runtime_vector_store():
|
|
store = QdrantVectorStore(
|
|
base_url="http://qdrant:6333",
|
|
collection="workspace-semantic",
|
|
workspace_id="demo",
|
|
expected_dimension=1024,
|
|
request=lambda *args, **kwargs: MagicMock(
|
|
ok=True,
|
|
status_code=200,
|
|
text='{"result":{"config":{"params":{"vectors":{"size":1024,"distance":"Cosine"}}},"payload_schema":{}}}',
|
|
json=lambda: {
|
|
"result": {
|
|
"config": {"params": {"vectors": {"size": 1024, "distance": "Cosine"}}},
|
|
"payload_schema": {},
|
|
}
|
|
},
|
|
),
|
|
)
|
|
assert isinstance(store, VectorStore)
|