mirror of
https://github.com/qdrant/qdrant.git
synced 2026-07-23 11:11:00 -05:00
Collection name under test is equal to the test module name, without `.py` suffix. * Helps by debugging/tracing failed tests and find relevant logs lines in qdrant log files * Opens up a possibility to run tests in parallel, given that there are no data sharing between test modules Change details: * defined module scoped `collection_name` fixture in `conftest.py` * removed `collection_name` module variable * each test signature modified to declare the dependency to `collection_name` fixture * `@pytest.mark.parametrize` migrated to `@pytest-cases.parametrize` in cases when `collection_name` was used as the value
362 lines
10 KiB
Python
362 lines
10 KiB
Python
from operator import itemgetter
|
|
|
|
import pytest
|
|
|
|
from .helpers.collection_setup import basic_collection_setup, drop_collection
|
|
from .helpers.helpers import request_with_validation
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def setup(on_disk_vectors, on_disk_payload, collection_name):
|
|
basic_collection_setup(collection_name=collection_name, on_disk_vectors=on_disk_vectors,
|
|
on_disk_payload=on_disk_payload)
|
|
yield
|
|
drop_collection(collection_name=collection_name)
|
|
|
|
|
|
def assert_points(collection_name, points, nonexisting_ids=None, with_vectors=False):
|
|
ids = [point['id'] for point in points]
|
|
ids.extend(nonexisting_ids or [])
|
|
|
|
if not with_vectors:
|
|
for point in points:
|
|
point['vector'] = None
|
|
|
|
response = request_with_validation(
|
|
api='/collections/{collection_name}/points',
|
|
method='POST',
|
|
path_params={'collection_name': collection_name},
|
|
body={'ids': ids, 'with_vector': with_vectors, 'with_payload': True},
|
|
)
|
|
assert response.ok
|
|
|
|
for point, expected in zip(
|
|
sorted(response.json()['result'], key=itemgetter('id')),
|
|
sorted(points, key=itemgetter('id'))
|
|
):
|
|
assert point.get('id') == expected.get('id')
|
|
assert point.get('payload') == expected.get('payload')
|
|
assert point.get('vector') == expected.get('vector')
|
|
|
|
|
|
def test_batch_update(collection_name):
|
|
# Upsert and delete points
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"upsert": {
|
|
"points": [
|
|
{
|
|
"id": 7,
|
|
"vector": [1.0, 2.0, 3.0, 4.0],
|
|
"payload": {},
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"upsert": {
|
|
"points": [
|
|
{
|
|
"id": 8,
|
|
"vector": [1.0, 2.0, 3.0, 4.0],
|
|
"payload": {},
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{"delete": {"points": [8]}},
|
|
{
|
|
"upsert": {
|
|
"points": [
|
|
{
|
|
"id": 7,
|
|
"vector": [2.0, 1.0, 3.0, 4.0],
|
|
"payload": {},
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"upsert": {
|
|
"points": [
|
|
{
|
|
"id": 9,
|
|
"vector": {
|
|
"sparse-text": {
|
|
"indices": [123, 321],
|
|
"values": [5.5, 5.5]
|
|
}
|
|
},
|
|
"payload": {},
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{"delete": {"points": [10]}},
|
|
]
|
|
},
|
|
query_params={"wait": "true"},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 7,
|
|
"vector": [2.0, 1.0, 3.0, 4.0],
|
|
"payload": {},
|
|
}
|
|
],
|
|
nonexisting_ids=[8],
|
|
with_vectors=True,
|
|
)
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 9,
|
|
"vector": {
|
|
"sparse-text": {
|
|
"indices": [123, 321],
|
|
"values": [5.5, 5.5]
|
|
},
|
|
},
|
|
"payload": {},
|
|
}
|
|
],
|
|
nonexisting_ids=[10],
|
|
with_vectors=True,
|
|
)
|
|
|
|
# Update vector
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"update_vectors": {
|
|
"points": [
|
|
{
|
|
"id": 7,
|
|
"vector": [1.0, 2.0, 3.0, 4.0],
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"update_vectors": {
|
|
"points": [
|
|
{
|
|
"id": 7,
|
|
"vector": [9.0, 2.0, 4.0, 2.0],
|
|
},
|
|
]
|
|
}
|
|
},
|
|
]
|
|
},
|
|
query_params={"wait": "true"},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 7,
|
|
"vector": [9.0, 2.0, 4.0, 2.0],
|
|
"payload": {},
|
|
}
|
|
],
|
|
nonexisting_ids=[8],
|
|
with_vectors=True,
|
|
)
|
|
|
|
# Upsert point and delete vector
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"upsert": {
|
|
"points": [
|
|
{
|
|
"id": 9,
|
|
"vector": [0.0, 5.0, 2.0, 1.0],
|
|
"payload": {},
|
|
},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"delete_vectors": {
|
|
"points": [9],
|
|
"vector": [""],
|
|
}
|
|
},
|
|
]
|
|
},
|
|
query_params={"wait": "true"},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 7,
|
|
"vector": [9.0, 2.0, 4.0, 2.0],
|
|
"payload": {},
|
|
},
|
|
{
|
|
"id": 9,
|
|
"vector": {},
|
|
"payload": {},
|
|
}
|
|
],
|
|
nonexisting_ids=[8],
|
|
with_vectors=True,
|
|
)
|
|
|
|
|
|
def test_batch_update_payload(collection_name):
|
|
# Batch on multiple points
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"overwrite_payload": {
|
|
"payload": {
|
|
"test_payload": "1",
|
|
},
|
|
"points": [1],
|
|
},
|
|
},
|
|
{
|
|
"overwrite_payload": {
|
|
"payload": {
|
|
"test_payload": "2",
|
|
},
|
|
"points": [2],
|
|
},
|
|
},
|
|
]
|
|
},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 1,
|
|
"payload": {
|
|
"test_payload": "1",
|
|
},
|
|
"vector": None,
|
|
},
|
|
{
|
|
"id": 2,
|
|
"payload": {
|
|
"test_payload": "2",
|
|
},
|
|
"vector": None,
|
|
},
|
|
]
|
|
)
|
|
|
|
# Clear multiple
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"clear_payload": {
|
|
"points": [1],
|
|
},
|
|
},
|
|
{
|
|
"clear_payload": {
|
|
"points": [2],
|
|
},
|
|
},
|
|
]
|
|
},
|
|
query_params={"wait": "true"},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 1,
|
|
"payload": {},
|
|
},
|
|
{
|
|
"id": 2,
|
|
"payload": {},
|
|
},
|
|
]
|
|
)
|
|
|
|
# Batch update on the same point
|
|
response = request_with_validation(
|
|
api="/collections/{collection_name}/points/batch",
|
|
method="POST",
|
|
path_params={"collection_name": collection_name},
|
|
body={
|
|
"operations": [
|
|
{
|
|
"overwrite_payload": {
|
|
"payload": {
|
|
"test_payload_1": "1",
|
|
},
|
|
"points": [1],
|
|
},
|
|
},
|
|
{
|
|
"set_payload": {
|
|
"payload": {
|
|
"test_payload_2": "2",
|
|
"test_payload_3": "3",
|
|
},
|
|
"points": [1],
|
|
}
|
|
},
|
|
{
|
|
"delete_payload": {
|
|
"keys": [
|
|
"test_payload_2",
|
|
],
|
|
"points": [1],
|
|
},
|
|
},
|
|
]
|
|
},
|
|
query_params={"wait": "true"},
|
|
)
|
|
assert response.ok
|
|
|
|
assert_points(collection_name,
|
|
[
|
|
{
|
|
"id": 1,
|
|
"payload": {
|
|
"test_payload_1": "1",
|
|
"test_payload_3": "3",
|
|
},
|
|
},
|
|
]
|
|
)
|