From 316b6fbd4364d5f66cae8d7d92c79714a5a42ece Mon Sep 17 00:00:00 2001 From: ThreadDao Date: Mon, 31 May 2021 19:23:31 +0800 Subject: [PATCH] Add test cases of insert data (#5512) * add case of insert Signed-off-by: ThreadDao * add insert cases Signed-off-by: ThreadDao * test insert Signed-off-by: ThreadDao * test insert data Signed-off-by: ThreadDao * fix codacy Signed-off-by: ThreadDao --- tests20/python_client/base/client_request.py | 4 +- .../testcases/test_collection.py | 68 +-- .../python_client/testcases/test_insert.py | 553 +++++++++++++++++- 3 files changed, 554 insertions(+), 71 deletions(-) diff --git a/tests20/python_client/base/client_request.py b/tests20/python_client/base/client_request.py index a9478bc35..fe33ba601 100644 --- a/tests20/python_client/base/client_request.py +++ b/tests20/python_client/base/client_request.py @@ -107,8 +107,8 @@ class ApiReq(Base): def _connect(self): """ Testing func """ - self.connection.configure(check_res='', default={"host": "192.168.1.239", "port": 19530}) - res = self.connection.create_connection(alias='default') + self.connection.configure(check_res='', default={"host": "192.168.1.240", "port": 19530}) + res, _ = self.connection.create_connection(alias='default') return res def _collection(self, name=None, data=None, schema=None, check_res=None, **kwargs): diff --git a/tests20/python_client/testcases/test_collection.py b/tests20/python_client/testcases/test_collection.py index 7ca04acf8..c1c25af45 100644 --- a/tests20/python_client/testcases/test_collection.py +++ b/tests20/python_client/testcases/test_collection.py @@ -677,6 +677,7 @@ class TestCollectionParams(ApiReq): assert_default_collection(collection, c_name, exp_schema=default_binary_schema, exp_num=nb) @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5414") def test_collection_binary_with_data_list(self): """ target: test collection with data (list-like) @@ -687,8 +688,8 @@ class TestCollectionParams(ApiReq): nb = ct.default_nb c_name = cf.gen_unique_str(prefix) data = cf.gen_default_binary_list_data(nb) - collection, _ = self.collection.collection_init(c_name, schema=default_binary_schema, data=data) - assert_default_collection(collection, c_name, exp_schema=default_binary_schema, exp_num=nb) + ex, _ = self.collection.collection_init(c_name, schema=default_binary_schema, data=data) + log.debug(str(ex)) class TestCollectionOperation(ApiReq): @@ -768,22 +769,6 @@ class TestCollectionOperation(ApiReq): with pytest.raises(Exception, match="can't find collection"): collection.num_entities - @pytest.mark.tags(CaseLabel.L0) - @pytest.mark.xfail(reason="issue #5302") - def test_collection_schema_insert_dataframe(self): - """ - target: test collection create and insert dataframe - method: 1. create by schema 2. insert dataframe - expected: assert num_entities - """ - self._connect() - nb = ct.default_nb - collection = self._collection() - assert_default_collection(collection) - df = cf.gen_default_dataframe_data(nb) - self.collection.insert(data=df) - assert collection.num_entities == nb - @pytest.mark.tags(CaseLabel.L1) @pytest.mark.xfail(reason="issue #5302") def test_collection_created_by_dataframe(self): @@ -871,22 +856,6 @@ class TestCollectionOperation(ApiReq): ex, _ = self.collection.collection_init(name=c_name, schema=None, data=data) assert "Data of not pandas.DataFrame type should bepassed into the schema" in str(ex) - @pytest.mark.tags(CaseLabel.L0) - @pytest.mark.xfail(reason="issue #5302") - def test_collection_schema_insert_data(self): - """ - target: test collection create and insert list-like data - method: 1. create by schema 2. insert data - expected: assert num_entities - """ - self._connect() - nb = ct.default_nb - collection = self._collection() - assert_default_collection(collection) - data = cf.gen_default_list_data(nb) - self.collection.insert(data=data) - assert collection.num_entities == nb - @pytest.mark.tags(CaseLabel.L1) def test_collection_after_drop(self): """ @@ -903,22 +872,6 @@ class TestCollectionOperation(ApiReq): assert_default_collection(re_collection, c_name) assert self.utility.has_collection(c_name)[0] - @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="issue #5302") - def test_collection_binary_insert_dataframe(self): - """ - target: test collection create and insert dataframe - method: 1. create by schema 2. insert dataframe - expected: assert num_entities - """ - self._connect() - nb = ct.default_nb - collection = self._collection(schema=default_binary_schema) - assert_default_collection(collection, exp_schema=default_binary_schema) - df = cf.gen_default_binary_dataframe_data(nb) - self.collection.insert(data=df) - assert collection.num_entities == nb - @pytest.mark.tags(CaseLabel.L1) @pytest.mark.xfail(reason="issue #5414") def test_collection_binary_created_by_dataframe(self): @@ -948,18 +901,3 @@ class TestCollectionOperation(ApiReq): ex, _ = self.collection.collection_init(name=c_name, schema=None, data=data) assert "Data of not pandas.DataFrame type should bepassed into the schema" in str(ex) - @pytest.mark.tags(CaseLabel.L0) - @pytest.mark.xfail(reason="issue #5414") - def test_collection_binary_insert_data(self): - """ - target: test collection create and insert list-like data - method: 1. create by schema 2. insert data - expected: assert num_entities - """ - self._connect() - nb = ct.default_nb - collection = self._collection(schema=default_binary_schema) - assert_default_collection(collection, exp_schema=default_binary_schema) - data = cf.gen_default_binary_list_data(nb) - self.collection.insert(data=data) - assert collection.num_entities == nb diff --git a/tests20/python_client/testcases/test_insert.py b/tests20/python_client/testcases/test_insert.py index 36ace5334..bfb7eaf4a 100644 --- a/tests20/python_client/testcases/test_insert.py +++ b/tests20/python_client/testcases/test_insert.py @@ -1,3 +1,7 @@ +import time + +import numpy as np +import pandas as pd import pytest from base.client_request import ApiReq @@ -6,21 +10,562 @@ from common import common_func as cf from common import common_type as ct from common.common_type import CaseLabel +prefix = "insert" +default_schema = cf.gen_default_collection_schema() +default_binary_schema = cf.gen_default_binary_collection_schema() + class TestInsertParams(ApiReq): """ Test case of Insert interface """ + @pytest.fixture(scope="function", params=ct.get_invalid_strs) + def get_non_data_type(self, request): + if isinstance(request.param, list): + pytest.skip("list type is valid data type") + yield request.param + + @pytest.fixture(scope="module", params=ct.get_invalid_strs) + def get_invalid_field_name(self, request): + if isinstance(request.param, (list, dict)): + pytest.skip() + yield request.param + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5302") + def test_insert_dataframe_data(self): + """ + target: test insert DataFrame data + method: 1.create 2.insert dataframe data + expected: assert num entities + """ + self._connect() + nb = ct.default_nb + collection = self._collection() + df = cf.gen_default_dataframe_data(nb) + self.collection.insert(data=df) + assert collection.num_entities == nb + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5470") + def test_insert_list_data(self): + """ + target: test insert list-like data + method: 1.create 2.insert list data + expected: assert num entities + """ + self._connect() + nb = ct.default_nb + collection = self._collection() + data = cf.gen_default_list_data(nb) + self.collection.insert(data=data) + self.connection.connection.get_connection().flush([collection.name]) + assert collection.num_entities == nb + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_non_data_type(self, get_non_data_type): + """ + target: test insert with non-dataframe, non-list data + method: insert with data (non-dataframe and non-list type) + expected: raise exception + """ + self._collection() + ex, _ = self.collection.insert(data=get_non_data_type) + assert "Datas must be list" in str(ex) + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.parametrize("data", [[], pd.DataFrame()]) + def test_insert_empty_data(self, data): + """ + target: test insert empty data + method: insert empty + expected: raise exception + """ + self._collection() + ex, _ = self.collection.insert(data=data) + assert "Column cnt not match with schema" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_dataframe_only_columns(self): + """ + target: test insert with dataframe just columns + method: dataframe just have columns + expected: num entities is zero + """ + self._collection() + columns = [ct.default_int64_field_name, ct.default_float_vec_field_name] + df = pd.DataFrame(columns=columns) + ex, _ = self.collection.insert(data=df) + assert "Cannot infer schema from empty dataframe" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5499") + def test_insert_empty_field_name_dataframe(self): + """ + target: test insert empty field name df + method: dataframe with empty column + expected: raise exception + """ + self._collection() + df = cf.gen_default_dataframe_data(10) + df.rename(columns={ct.default_int64_field_name: ' '}, inplace=True) + ex, _ = self.collection.insert(data=df) + assert "Field name should not be empty" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5499") + def test_insert_invalid_field_name_dataframe(self, get_invalid_field_name): + """ + target: test insert with invalid dataframe data + method: insert with invalid field name dataframe + expected: raise exception + """ + self._collection() + df = cf.gen_default_dataframe_data(10) + df.rename(columns={ct.default_int64_field_name: get_invalid_field_name}, inplace=True) + log.info(df) + ex, _ = self.collection.insert(data=df) + log.error(str(ex)) + + def test_insert_dataframe_nan_value(self): + """ + target: test insert dataframe with nan value + method: insert dataframe with nan value + expected: todo + """ + pass + + def test_insert_dataframe_index(self): + """ + target: test insert dataframe with index + method: insert dataframe with index + expected: todo + """ + pass + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5445") + def test_insert_none(self): + """ + target: test insert None + method: data is None + expected: raise exception + """ + self._collection() + ex, _ = self.collection.insert(data=None) + log.info(str(ex)) + @pytest.mark.tags(CaseLabel.L0) @pytest.mark.xfail(reason="issue #5421") - def test_collection_numpy_insert_data(self): + def test_insert_numpy_data(self): """ - target: test collection create and insert list-like data - method: 1. create by schema 2. insert data + target: test insert numpy.ndarray data + method: 1.create by schema 2.insert data expected: assert num_entities """ self._connect() nb = 10 - collection = self._collection() + self._collection() data = cf.gen_numpy_data(nb) ex, _ = self.collection.insert(data=data) log.error(str(ex)) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5302") + def test_insert_binary_dataframe(self): + """ + target: test insert binary dataframe + method: 1. create by schema 2. insert dataframe + expected: assert num_entities + """ + self._connect() + nb = ct.default_nb + collection = self._collection(schema=default_binary_schema) + df = cf.gen_default_binary_dataframe_data(nb) + self.collection.insert(data=df) + assert collection.num_entities == nb + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5414") + def test_insert_binary_data(self): + """ + target: test insert list-like binary data + method: 1. create by schema 2. insert data + expected: assert num_entities + """ + self._connect() + nb = ct.default_nb + collection = self._collection(schema=default_binary_schema) + data = cf.gen_default_binary_list_data(nb) + self.collection.insert(data=data) + assert collection.num_entities == nb + + @pytest.mark.tags(CaseLabel.L0) + @pytest.mark.xfail(reason="issue #5470") + def test_insert_single(self): + """ + target: test insert single + method: insert one entity + expected: verify num + """ + conn = self._connect() + collection = self._collection() + data = cf.gen_default_list_data(nb=1) + self.collection.insert(data=data) + conn.flush([collection.name]) + assert collection.num_entities == 1 + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_dim_not_match(self): + """ + target: test insert with not match dim + method: insert data dim not equal to schema dim + expected: raise exception + """ + self._connect() + nb = ct.default_nb + collection = self._collection() + df = cf.gen_default_dataframe_data(nb, dim=129) + ex, _ = self.collection.insert(data=df) + message = "Collection field dim is {},but entities field dim is {}".format(ct.default_dim, 129) + assert message in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5499") + def test_insert_field_name_not_match(self): + """ + target: test insert field name not match + method: data field name not match schema + expected: raise exception + """ + self._collection() + df = cf.gen_default_dataframe_data(10) + df.rename(columns={ct.default_float_field_name: "int"}, inplace=True) + log.info(df) + ex, _ = self.collection.insert(data=df) + log.error(str(ex)) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_field_value_not_match(self): + """ + target: test insert data value not match + method: insert data value type not match schema + expected: raise exception + """ + self._collection() + nb = 10 + df = cf.gen_default_dataframe_data(nb) + new_float_value = pd.Series(data=[float(i) for i in range(nb)], dtype="float64") + df.iloc[:, 1] = new_float_value + ex, _ = self.collection.insert(data=df) + assert "The types of schema and data do not match" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5505") + def test_insert_value_less(self): + """ + target: test insert value less than other + method: int field value less than vec-field value + expected: raise exception + """ + self._collection() + nb = 10 + int_values = [i for i in range(nb-1)] + float_values = [np.float32(i) for i in range(nb)] + float_vec_values = cf.gen_vectors(nb, ct.default_dim) + data = [int_values, float_values, float_vec_values] + ids, _ = self.collection.insert(data=data) + log.info(ids) + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5508") + def test_insert_vector_value_less(self): + """ + target: test insert vector value less than other + method: vec field value less than int field + expected: todo + """ + self._collection() + nb = 10 + int_values = [i for i in range(nb)] + float_values = [np.float32(i) for i in range(nb)] + float_vec_values = cf.gen_vectors(nb-1, ct.default_dim) + data = [int_values, float_values, float_vec_values] + ex, _ = self.collection.insert(data=data) + log.info(str(ex)) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_fields_more(self): + """ + target: test insert with fields more + method: field more than schema fields + expected: todo + """ + self._collection() + nb = ct.default_nb + df = cf.gen_default_dataframe_data(nb) + new_values = [i for i in range(nb)] + df.insert(3, 'new', new_values) + ex, _ = self.collection.insert(data=df) + assert "Column cnt not match with schema" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_fields_less(self): + """ + target: test insert with fields less + method: fields less than schema fields + expected: raise exception + """ + self._collection() + nb = ct.default_nb + df = cf.gen_default_dataframe_data(nb) + df.drop(ct.default_float_vec_field_name, axis=1, inplace=True) + ex, _ = self.collection.insert(data=df) + assert "Column cnt not match with schema" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_list_order_inconsistent_schema(self): + """ + target: test insert data fields order inconsistent with schema + method: insert list data, data fields order inconsistent with schema + expected: raise exception + """ + self._collection() + nb = 10 + int_values = [i for i in range(nb)] + float_values = [np.float32(i) for i in range(nb)] + float_vec_values = cf.gen_vectors(nb, ct.default_dim) + data = [float_values, int_values, float_vec_values] + ex, _ = self.collection.insert(data=data) + assert "The types of schema and data do not match" in str(ex) + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_dataframe_order_inconsistent_schema(self): + """ + target: test insert with dataframe fields inconsistent with schema + method: insert dataframe, and fields order inconsistent with schema + expected: assert num entities + """ + self._collection() + nb = 10 + int_values = pd.Series(data=[i for i in range(nb)]) + float_values = pd.Series(data=[float(i) for i in range(nb)], dtype="float32") + float_vec_values = cf.gen_vectors(nb, ct.default_dim) + df = pd.DataFrame({ + ct.default_float_field_name: float_values, + ct.default_float_vec_field_name: float_vec_values, + ct.default_int64_field_name: int_values + }) + ex, _ = self.collection.insert(data=df) + assert "The types of schema and data do not match" in str(ex) + + +class TestInsertOperation(ApiReq): + """ + ****************************************************************** + The following cases are used to test insert interface operations + ****************************************************************** + """ + + def teardown_method(self): + if self.collection is not None and self.collection.collection is not None: + self.collection.drop() + + def setup_method(self): + pass + + @pytest.mark.tags(CaseLabel.L1) + def test_insert_without_connection(self): + """ + target: test insert without connection + method: insert after remove connection + expected: raise exception + """ + self._collection() + self.connection.remove_connection(ct.default_alias) + res_list, _ = self.connection.list_connections() + assert ct.default_alias not in res_list + data = cf.gen_default_list_data(10) + ex, _ = self.collection.insert(data=data) + assert "There is no connection with alias '{}'".format(ct.default_alias) in str(ex) + + def test_insert_drop_collection(self): + """ + target: test insert and drop + method: insert data and drop collection + expected: verify collection if exist + """ + collection = self._collection() + collection_list, _ = self.utility.list_collections() + assert collection.name in collection_list + self.collection.drop() + collection_list, _ = self.utility.list_collections() + assert collection.name not in collection_list + + def test_insert_create_index(self): + """ + target: test insert and create index + method: 1. insert 2. create index + expected: verify num entities and index + """ + pass + + def test_insert_after_create_index(self): + """ + target: test insert after create index + method: 1. create index 2. insert data + expected: verify index and num entities + """ + pass + + def test_insert_binary_after_index(self): + """ + target: test insert binary after index + method: 1.create index 2.insert binary data + expected: 1.index ok 2.num entities correct + """ + pass + + def test_insert_search(self): + """ + target: test insert and search + method: 1.insert data 2.search + expected: verify search result + """ + pass + + def test_insert_binary_search(self): + """ + target: test insert and search + method: 1.insert binary data 2.search + expected: search result correct + """ + pass + + def test_insert_ids(self): + """ + target: test insert with ids + method: insert with ids field value + expected: 1.verify num entities 2.verify ids + """ + schema = cf.gen_default_collection_schema(primary_field=ct.default_int64_field_name) + collection = self._collection(schema=schema) + assert not collection.auto_id + assert collection.primary_field.name == ct.default_int64_field_name + data = cf.gen_default_list_data(ct.default_nb) + self.collection.insert(data=data) + time.sleep(1) + assert collection.num_entities == ct.default_nb + # TODO assert ids + + def test_insert_ids_without_value(self): + """ + target: test insert ids value not match + method: insert without ids field value + expected: raise exception + """ + pass + + def test_insert_same_ids(self): + """ + target: test insert ids field + method: insert with same ids + expected: num entities equal to nb + """ + pass + + def test_insert_invalid_type_ids(self): + """ + target: test insert with non-int64 ids + method: insert ids field with non-int64 value + expected: raise exception + """ + pass + + def test_insert_multi_threading(self): + """ + target: test concurrent insert + method: multi threads insert + expected: verify num entities + """ + pass + + @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.xfail(reason="issue #5470") + def test_insert_multi_times(self): + """ + target: test insert multi times + method: insert data multi times + expected: verify num entities + """ + conn = self._connect() + collection = self._collection() + for _ in range(ct.default_nb): + df = cf.gen_default_dataframe_data(1) + self.collection.insert(data=df) + self.connection.connection.get_connection().flush([collection.name]) + # conn.flush([collection.name]) + assert collection.num_entities == ct.default_nb + + +class TestInsertAsync(ApiReq): + """ + ****************************************************************** + The following cases are used to test insert async + ****************************************************************** + """ + + def test_insert_sync(self): + """ + target: test async insert + method: insert with async=True + expected: verify num entities + """ + pass + + def test_insert_async_false(self): + """ + target: test insert with false async + method: async = false + expected: verify num entities + """ + pass + + def test_insert_async_callback(self): + """ + target: test insert with callback func + method: insert with callback func + expected: verify num entities + """ + pass + + def test_insert_async_long(self): + """ + target: test insert with async + method: insert 5w entities with callback func + expected: verify num entities + """ + pass + + def test_insert_async_callback_timeout(self): + """ + target: test insert async with callback + method: insert 10w entities with timeout=1 + expected: raise exception + """ + pass + + def test_insert_async_invalid_data(self): + """ + target: test insert async with invalid data + method: insert async with invalid data + expected: raise exception + """ + pass + + def test_insert_async_invalid_partition(self): + """ + target: test insert async with invalid partition + method: insert async with invalid partition + expected: raise exception + """ + pass -- GitLab