milvus/shards/mishards/test_server.py
Jin Hai 0323aa1aad
Merge 080 (#1940)
* #1910 C++ SDK GetIDsInSegment could not work for large dataset (#1911)

Signed-off-by: groot <yihua.mo@zilliz.com>

* #1903 Fix invalid annoy result (#1912)

Signed-off-by: shengjun.li <shengjun.li@zilliz.com>

* #1914: Partition max size should be 4096 (#1915)

Signed-off-by: jinhai <hai.jin@zilliz.com>

* add log (#1913)

* add log

Signed-off-by: groot <yihua.mo@zilliz.com>

* add log

Signed-off-by: groot <yihua.mo@zilliz.com>

* fix ut

Signed-off-by: groot <yihua.mo@zilliz.com>

* partition limit 4096

Signed-off-by: groot <yihua.mo@zilliz.com>

* fix py test

Signed-off-by: groot <yihua.mo@zilliz.com>

* update server version (#1916)

Signed-off-by: zw <zw@zilliz.com>

* Update to 0.8.0 (#1918)

* Create new branch 0.8.0 and change preload_table to preload_collection

Signed-off-by: jinhai <hai.jin@zilliz.com>

* Fix format

Signed-off-by: JinHai-CN <hai.jin@zilliz.com>

* Update CHANGELOG

Signed-off-by: jinhai <hai.jin@zilliz.com>

* Update CHANGELOG

Signed-off-by: jinhai <hai.jin@zilliz.com>

* update helm version

Signed-off-by: zw <zw@zilliz.com>

* Update CHANGELOG

Signed-off-by: jinhai <hai.jin@zilliz.com>

Co-authored-by: zw <zw@zilliz.com>

* fix issue 1901 (#1920)

* fix issue 1901

Signed-off-by: cmli <chengming.li@zilliz.com>

* update change log

Signed-off-by: cmli <chengming.li@zilliz.com>

Co-authored-by: cmli <chengming.li@zilliz.com>

* #1900 (#1923)

* add log

Signed-off-by: yhmo <yihua.mo@zilliz.com>

* fix #1900

Signed-off-by: groot <yihua.mo@zilliz.com>

* Upgrade mishards to 0.8.0 (#1933)

* update grpc server of milvus & rename table name to collection

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* update changlog

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* [skip ci] Skip CI

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* [skip ci] Update changlog

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* Caiyd 1883 fix rw (#1926)

* #1883 use DiskIO

Signed-off-by: yudong.cai <yudong.cai@zilliz.com>

* fix logic error

Signed-off-by: yudong.cai <yudong.cai@zilliz.com>

* update changelog

Signed-off-by: yudong.cai <yudong.cai@zilliz.com>

* retry CI

Signed-off-by: yudong.cai <yudong.cai@zilliz.com>

* Update CHANGELOG

Signed-off-by: JinHai-CN <hai.jin@zilliz.com>

* update changelog

Signed-off-by: yudong.cai <yudong.cai@zilliz.com>

Co-authored-by: JinHai-CN <hai.jin@zilliz.com>

* #1928 Too many data and uid copies when loading files (#1931)

Signed-off-by: shengjun.li <shengjun.li@zilliz.com>

Co-authored-by: Jin Hai <hai.jin@zilliz.com>

* Update mishards configure files (#1938)

* Update web readme

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* [skip ci] update configure files

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* [skip ci] rename table to collection

Signed-off-by: Yhz <yinghao.zou@zilliz.com>

* Update test.groovy

Signed-off-by: jinhai <hai.jin@zilliz.com>

* Update test.groovy

Signed-off-by: jinhai <hai.jin@zilliz.com>

* Fix lint

Signed-off-by: JinHai-CN <hai.jin@zilliz.com>

* Fix compiling error

Signed-off-by: jinhai <hai.jin@zilliz.com>

Co-authored-by: groot <yhmo@zeronedata.com>
Co-authored-by: shengjun.li <49774184+shengjun1985@users.noreply.github.com>
Co-authored-by: del-zhenwu <56623710+del-zhenwu@users.noreply.github.com>
Co-authored-by: zw <zw@zilliz.com>
Co-authored-by: op-hunter <ophunter52@gmail.com>
Co-authored-by: cmli <chengming.li@zilliz.com>
Co-authored-by: BossZou <40255591+BossZou@users.noreply.github.com>
Co-authored-by: Cai Yudong <yudong.cai@zilliz.com>
2020-04-15 21:32:20 +08:00

281 lines
12 KiB
Python

import logging
import pytest
import mock
import datetime
import random
import faker
import inspect
from milvus import Milvus
from milvus.client.types import Status, IndexType, MetricType
from milvus.client.abstract import IndexParam, CollectionSchema
from milvus.grpc_gen import status_pb2, milvus_pb2
from mishards import db, create_app, settings
from mishards.service_handler import ServiceHandler
from mishards.grpc_utils.grpc_args_parser import GrpcArgsParser as Parser
from mishards.factories import TableFilesFactory, TablesFactory, TableFiles, Tables
from mishards.router import RouterMixin
from mishards.connections import (ConnectionMgr, Connection,
ConnectionPool, ConnectionTopology, ConnectionGroup)
logger = logging.getLogger(__name__)
OK = Status(code=Status.SUCCESS, message='Success')
BAD = Status(code=Status.PERMISSION_DENIED, message='Fail')
@pytest.mark.usefixtures('started_app')
class TestServer:
@property
def client(self):
m = Milvus()
m.connect(host='localhost', port=settings.SERVER_TEST_PORT)
return m
def test_cmd(self, started_app):
ServiceHandler._get_server_version = mock.MagicMock(return_value=(OK,
''))
status, _ = self.client.server_version()
assert status.OK()
Parser.parse_proto_Command = mock.MagicMock(return_value=(BAD, 'cmd'))
status, _ = self.client.server_version()
assert not status.OK()
def test_drop_index(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
ServiceHandler._drop_index = mock.MagicMock(return_value=OK)
status = self.client.drop_index(collection_name)
assert status.OK()
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status = self.client.drop_index(collection_name)
assert not status.OK()
def test_describe_index(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
index_type = IndexType.FLAT
params = {'nlist': 1}
index_param = IndexParam(collection_name=collection_name,
index_type=index_type,
params=params)
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_name))
ServiceHandler._describe_index = mock.MagicMock(
return_value=(OK, index_param))
status, ret = self.client.describe_index(collection_name)
assert status.OK()
assert ret._collection_name == index_param._collection_name
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status, _ = self.client.describe_index(collection_name)
assert not status.OK()
def test_preload(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_name))
ServiceHandler._preload_collection = mock.MagicMock(return_value=OK)
status = self.client.preload_collection(collection_name)
assert status.OK()
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status = self.client.preload_collection(collection_name)
assert not status.OK()
@pytest.mark.skip
def test_delete_by_range(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
unpacked = collection_name, datetime.datetime.today(
), datetime.datetime.today()
Parser.parse_proto_DeleteByRangeParam = mock.MagicMock(
return_value=(OK, unpacked))
ServiceHandler._delete_by_range = mock.MagicMock(return_value=OK)
status = self.client.delete_vectors_by_range(
*unpacked)
assert status.OK()
Parser.parse_proto_DeleteByRangeParam = mock.MagicMock(
return_value=(BAD, unpacked))
status = self.client.delete_vectors_by_range(
*unpacked)
assert not status.OK()
def test_count_collection(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
count = random.randint(100, 200)
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_name))
ServiceHandler._count_collection = mock.MagicMock(return_value=(OK, count))
status, ret = self.client.count_collection(collection_name)
assert status.OK()
assert ret == count
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status, _ = self.client.count_collection(collection_name)
assert not status.OK()
def test_show_collections(self, started_app):
collections = ['t1', 't2']
ServiceHandler._show_collections = mock.MagicMock(return_value=(OK, collections))
status, ret = self.client.show_collections()
assert status.OK()
assert ret == collections
def test_describe_collection(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
dimension = 128
nlist = 1
collection_schema = CollectionSchema(collection_name=collection_name,
index_file_size=100,
metric_type=MetricType.L2,
dimension=dimension)
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_schema.collection_name))
ServiceHandler._describe_collection = mock.MagicMock(
return_value=(OK, collection_schema))
status, _ = self.client.describe_collection(collection_name)
assert status.OK()
ServiceHandler._describe_collection = mock.MagicMock(
return_value=(BAD, collection_schema))
status, _ = self.client.describe_collection(collection_name)
assert not status.OK()
Parser.parse_proto_CollectionName = mock.MagicMock(return_value=(BAD,
'cmd'))
status, ret = self.client.describe_collection(collection_name)
assert not status.OK()
def test_insert(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
vectors = [[random.random() for _ in range(16)] for _ in range(10)]
ids = [random.randint(1000000, 20000000) for _ in range(10)]
ServiceHandler._add_vectors = mock.MagicMock(return_value=(OK, ids))
status, ret = self.client.add_vectors(
collection_name=collection_name, records=vectors)
assert status.OK()
assert ids == ret
def test_create_index(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
unpacks = collection_name, None
Parser.parse_proto_IndexParam = mock.MagicMock(return_value=(OK,
unpacks))
ServiceHandler._create_index = mock.MagicMock(return_value=OK)
status = self.client.create_index(collection_name=collection_name)
assert status.OK()
Parser.parse_proto_IndexParam = mock.MagicMock(return_value=(BAD,
None))
status = self.client.create_index(collection_name=collection_name)
assert not status.OK()
def test_drop_collection(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_name))
ServiceHandler._drop_collection = mock.MagicMock(return_value=OK)
status = self.client.drop_collection(collection_name=collection_name)
assert status.OK()
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status = self.client.drop_collection(collection_name=collection_name)
assert not status.OK()
def test_has_collection(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(OK, collection_name))
ServiceHandler._has_collection = mock.MagicMock(return_value=(OK, True))
has = self.client.has_collection(collection_name=collection_name)
assert has
Parser.parse_proto_CollectionName = mock.MagicMock(
return_value=(BAD, collection_name))
status, has = self.client.has_collection(collection_name=collection_name)
assert not status.OK()
assert not has
def test_create_collection(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
dimension = 128
collection_schema = dict(collection_name=collection_name,
index_file_size=100,
metric_type=MetricType.L2,
dimension=dimension)
ServiceHandler._create_collection = mock.MagicMock(return_value=OK)
status = self.client.create_collection(collection_schema)
assert status.OK()
Parser.parse_proto_CollectionSchema = mock.MagicMock(return_value=(BAD,
None))
status = self.client.create_collection(collection_schema)
assert not status.OK()
def random_data(self, n, dimension):
return [[random.random() for _ in range(dimension)] for _ in range(n)]
@pytest.mark.skip
def test_search(self, started_app):
collection_name = inspect.currentframe().f_code.co_name
to_index_cnt = random.randint(10, 20)
collection = TablesFactory(collection_id=collection_name, state=Tables.NORMAL)
to_index_files = TableFilesFactory.create_batch(
to_index_cnt, collection=collection, file_type=TableFiles.FILE_TYPE_TO_INDEX)
topk = random.randint(5, 10)
nq = random.randint(5, 10)
param = {
'collection_name': collection_name,
'query_records': self.random_data(nq, collection.dimension),
'top_k': topk,
'params': {'nprobe': 2049}
}
result = [
milvus_pb2.TopKQueryResult(query_result_arrays=[
milvus_pb2.QueryResult(id=i, distance=random.random())
for i in range(topk)
]) for i in range(nq)
]
mock_results = milvus_pb2.TopKQueryResultList(status=status_pb2.Status(
error_code=status_pb2.SUCCESS, reason="Success"),
topk_query_result=result)
collection_schema = CollectionSchema(collection_name=collection_name,
index_file_size=collection.index_file_size,
metric_type=collection.metric_type,
dimension=collection.dimension)
status, _ = self.client.search_vectors(**param)
assert status.code == Status.ILLEGAL_ARGUMENT
param['params']['nprobe'] = 2048
RouterMixin.connection = mock.MagicMock(return_value=Milvus())
RouterMixin.query_conn.conn = mock.MagicMock(return_value=Milvus())
Milvus.describe_collection = mock.MagicMock(return_value=(BAD,
collection_schema))
status, ret = self.client.search_vectors(**param)
assert status.code == Status.COLLECTION_NOT_EXISTS
Milvus.describe_collection = mock.MagicMock(return_value=(OK, collection_schema))
Milvus.search_vectors_in_files = mock.MagicMock(
return_value=mock_results)
status, ret = self.client.search_vectors(**param)
assert status.OK()
assert len(ret) == nq