Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add restful v2 api testcases #39558

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
test: add restful v2 api testcases
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
  • Loading branch information
zhuwenxing committed Jan 23, 2025
commit 49f2128e0e13f60c60e7e465b7f5e1d8502ad999
89 changes: 73 additions & 16 deletions tests/restful_client_v2/api/milvus.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,13 +549,11 @@ def alter_field_properties(self, collection_name, field_name, field_params, db_n
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def alter_index_properties(self, collection_name, index_name, properties, db_name="default"):
"""Alter index properties"""
url = f"{self.endpoint}/v2/vectordb/indexes/alter_properties"
def flush(self, collection_name, db_name="default"):
"""Flush collection"""
url = f"{self.endpoint}/v2/vectordb/collections/flush"
payload = {
"collectionName": collection_name,
"indexName": index_name,
"properties": properties
"collectionName": collection_name
}
if self.db_name is not None:
payload["dbName"] = self.db_name
Expand All @@ -564,13 +562,24 @@ def alter_index_properties(self, collection_name, index_name, properties, db_nam
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def drop_index_properties(self, collection_name, index_name, delete_keys, db_name="default"):
"""Drop index properties"""
url = f"{self.endpoint}/v2/vectordb/indexes/drop_properties"
def compact(self, collection_name, db_name="default"):
"""Compact collection"""
url = f"{self.endpoint}/v2/vectordb/collections/compact"
payload = {
"collectionName": collection_name,
"indexName": index_name,
"propertyKeys": delete_keys
"collectionName": collection_name
}
if self.db_name is not None:
payload["dbName"] = self.db_name
if db_name != "default":
payload["dbName"] = db_name
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def get_compaction_state(self, collection_name, db_name="default"):
"""Get compaction state"""
url = f"{self.endpoint}/v2/vectordb/collections/get_compaction_state"
payload = {
"collectionName": collection_name
}
if self.db_name is not None:
payload["dbName"] = self.db_name
Expand Down Expand Up @@ -882,6 +891,36 @@ def index_drop(self, payload, db_name="default"):
res = response.json()
return res

def alter_index_properties(self, collection_name, index_name, properties, db_name="default"):
"""Alter index properties"""
url = f"{self.endpoint}/v2/vectordb/indexes/alter_properties"
payload = {
"collectionName": collection_name,
"indexName": index_name,
"properties": properties
}
if self.db_name is not None:
db_name = self.db_name
if db_name != "default":
payload["dbName"] = db_name
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def drop_index_properties(self, collection_name, index_name, delete_keys, db_name="default"):
"""Drop index properties"""
url = f"{self.endpoint}/v2/vectordb/indexes/drop_properties"
payload = {
"collectionName": collection_name,
"indexName": index_name,
"propertyKeys": delete_keys
}
if self.db_name is not None:
db_name = self.db_name
if db_name != "default":
payload["dbName"] = db_name
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()


class AliasClient(Requests):

Expand Down Expand Up @@ -1047,10 +1086,28 @@ def database_alter(self, payload):
def database_drop(self, payload):
"""Drop a database"""
url = f"{self.endpoint}/v2/vectordb/databases/drop"
rsp = self.post(url, data=payload).json()
if rsp['code'] == 0 and payload['dbName'] in self.db_names:
self.db_names.remove(payload['dbName'])
return rsp
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def alter_database_properties(self, db_name, properties):
"""Alter database properties"""
url = f"{self.endpoint}/v2/vectordb/databases/alter"
payload = {
"dbName": db_name,
"properties": properties
}
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()

def drop_database_properties(self, db_name, property_keys):
"""Drop database properties"""
url = f"{self.endpoint}/v2/vectordb/databases/drop_properties"
payload = {
"dbName": db_name,
"propertyKeys": property_keys
}
response = self.post(url, headers=self.update_headers(), data=payload)
return response.json()


class StorageClient():
Expand Down
108 changes: 105 additions & 3 deletions tests/restful_client_v2/testcases/test_collection_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import time
from utils.util_log import test_log as logger
from utils.utils import gen_collection_name
from utils.utils import gen_collection_name, gen_vector
import pytest
from api.milvus import CollectionClient
from base.testbase import TestBase
Expand Down Expand Up @@ -956,7 +956,6 @@ def test_get_collections_stats(self):
"metricType": "L2",
"dimension": dim,
}
time.sleep(1)
rsp = client.collection_create(payload)
assert rsp['code'] == 0
# describe collection
Expand Down Expand Up @@ -1409,7 +1408,6 @@ def test_create_collections_with_invalid_api_key(self):


@pytest.mark.L0
@pytest.mark.skip("skip temporarily, need fix")
class TestCollectionProperties(TestBase):
"""Test collection property operations"""

Expand Down Expand Up @@ -1559,3 +1557,107 @@ def test_alter_field_properties(self):
assert p['value'] == "100"


@pytest.mark.L0
class TestCollectionMaintenance(TestBase):
"""Test collection maintenance operations"""

def test_collection_flush(self):
"""
target: test collection flush
method: create collection, insert data multiple times and flush
expected: flush successfully
"""
# Create collection
name = gen_collection_name()
client = self.collection_client
vector_client = self.vector_client
payload = {
"collectionName": name,
"schema": {
"fields": [
{"fieldName": "book_id", "dataType": "Int64", "isPrimary": True, "elementTypeParams": {}},
{"fieldName": "my_vector", "dataType": "FloatVector", "elementTypeParams": {"dim": 128}}
]
}
}
client.collection_create(payload)

# Insert small batches of data multiple times
for i in range(3):
vectors = [gen_vector(dim=128) for _ in range(10)]
insert_data = {
"collectionName": name,
"data": [
{
"book_id": i * 10 + j,
"my_vector": vector
}
for i, vector in enumerate(vectors)
for j in range(10)
]
}
response = vector_client.vector_insert(insert_data)
assert response["code"] == 0
c = Collection(name)
num_entities_before_flush = c.num_entities
# Flush collection
response = client.flush(name)
assert response["code"] == 0
# check segments
num_entities_after_flush = c.num_entities
logger.info(f"num_entities_before_flush: {num_entities_before_flush}, num_entities_after_flush: {num_entities_after_flush}")
assert num_entities_after_flush > num_entities_before_flush

def test_collection_compact(self):
"""
target: test collection compact
method: create collection, insert data, flush multiple times, then compact
expected: compact successfully
"""
# Create collection
name = gen_collection_name()
client = self.collection_client
vector_client = self.vector_client
payload = {
"collectionName": name,
"schema": {
"fields": [
{"fieldName": "book_id", "dataType": "Int64", "isPrimary": True, "elementTypeParams": {}},
{"fieldName": "my_vector", "dataType": "FloatVector", "elementTypeParams": {"dim": 128}}
]
}
}
client.collection_create(payload)

# Insert and flush multiple times
for i in range(3):
# Insert data
vectors = [gen_vector(dim=128) for _ in range(10)]
insert_data = {
"collectionName": name,
"data": [
{
"book_id": i * 10 + j,
"my_vector": vector
}
for i, vector in enumerate(vectors)
for j in range(10)
]
}
response = vector_client.vector_insert(insert_data)
assert response["code"] == 0

# Flush after each insert
c = Collection(name)
c.flush()
# Compact collection
response = client.compact(name)
assert response["code"] == 0

# Get compaction state
response = client.get_compaction_state(name)
assert response["code"] == 0
assert "state" in response["data"]
assert "compactionID" in response["data"]
# TODO need verification by pymilvus

84 changes: 84 additions & 0 deletions tests/restful_client_v2/testcases/test_database_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,87 @@ def test_drop_default_database(self):
"""
rsp = self.database_client.database_drop({"dbName": "default"})
assert rsp["code"] != 0


@pytest.mark.L0
class TestDatabaseProperties(TestBase):
"""Test database properties operations"""

def test_alter_database_properties(self):
"""
target: test alter database properties
method: create database, alter database properties
expected: alter database properties successfully
"""
# Create database
client = self.database_client
db_name = "test_alter_props"
payload = {
"dbName": db_name
}
response = client.database_create(payload)
assert response["code"] == 0

# Alter database properties
properties = {"mmap.enabled": False}
response = client.alter_database_properties(db_name, properties)
assert response["code"] == 0

# Drop database properties
property_keys = ["mmap.enabled"]
response = client.drop_database_properties(db_name, property_keys)
assert response["code"] == 0

# Clean up
client.database_drop({"dbName": db_name})

@pytest.mark.parametrize("invalid_property", [
{"invalid_key": True},
{"mmap.enabled": "invalid_value"}
])
@pytest.mark.xfail(reason="issue: https://github.com/milvus-io/milvus/issues/39545")
def test_alter_database_properties_with_invalid_properties(self, invalid_property):
"""
target: test alter database properties with invalid properties
method: create database, alter database properties with invalid properties
expected: alter database properties failed with error
"""
# Create database
client = self.database_client
db_name = "test_alter_props_invalid"
payload = {
"dbName": db_name
}
response = client.database_create(payload)
assert response["code"] == 0

# Alter database properties with invalid property
response = client.alter_database_properties(db_name, invalid_property)
assert response["code"] == 1100

# Clean up
client.database_drop({"dbName": db_name})

@pytest.mark.xfail(reason="issue: https://github.com/milvus-io/milvus/issues/39545")
def test_drop_database_properties_with_nonexistent_key(self):
"""
target: test drop database properties with nonexistent key
method: create database, drop database properties with nonexistent key
expected: drop database properties failed with error
"""
# Create database
client = self.database_client
db_name = "test_drop_props_nonexistent"
payload = {
"dbName": db_name
}
response = client.database_create(payload)
assert response["code"] == 0

# Drop database properties with nonexistent key
property_keys = ["nonexistent.key"]
response = client.drop_database_properties(db_name, property_keys)
assert response["code"] == 1100

# Clean up
client.database_drop({"dbName": db_name})
Loading