From b90cda2e5de062cd98e2ee4cb929a3d2c325e05f Mon Sep 17 00:00:00 2001 From: yanliang567 <82361606+yanliang567@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:29:24 +0800 Subject: [PATCH] test: [cherry pick]Add upsert in row test (#36855) related issue: https://github.com/milvus-io/milvus/issues/36710 pr: #36820 --------- Signed-off-by: yanliang567 --- .../test_milvus_client_insert.py | 63 +++++++++---------- tests/python_client/requirements.txt | 4 +- tests/python_client/testcases/test_insert.py | 23 ++++--- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/tests/python_client/milvus_client/test_milvus_client_insert.py b/tests/python_client/milvus_client/test_milvus_client_insert.py index fa47d7101d..d1aba2cb2f 100644 --- a/tests/python_client/milvus_client/test_milvus_client_insert.py +++ b/tests/python_client/milvus_client/test_milvus_client_insert.py @@ -64,7 +64,6 @@ class TestMilvusClientInsertInvalid(TestcaseBase): """ @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1883") def test_milvus_client_insert_column_data(self): """ target: test insert column data @@ -78,7 +77,7 @@ class TestMilvusClientInsertInvalid(TestcaseBase): # 2. insert vectors = [[random.random() for _ in range(default_dim)] for _ in range(default_nb)] data = [[i for i in range(default_nb)], vectors] - error = {ct.err_code: 1, ct.err_msg: "Unexpected error, message=<'list' object has no attribute 'items'"} + error = {ct.err_code: 999, ct.err_msg: "Input data type is inconsistent with defined schema, please check it."} client_w.insert(client, collection_name, data, check_task=CheckTasks.err_res, check_items=error) client_w.drop_collection(client, collection_name) @@ -95,7 +94,7 @@ class TestMilvusClientInsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"`collection_name` value {collection_name} is illegal"} + error = {ct.err_code: 999, ct.err_msg: f"`collection_name` value {collection_name} is illegal"} client_w.insert(client, collection_name, rows, check_task=CheckTasks.err_res, check_items=error) @@ -152,7 +151,6 @@ class TestMilvusClientInsertInvalid(TestcaseBase): check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1894") @pytest.mark.parametrize("data", ["12-s", "12 s", "(mn)", "中文", "%$#", " "]) def test_milvus_client_insert_data_invalid_type(self, data): """ @@ -165,12 +163,12 @@ class TestMilvusClientInsertInvalid(TestcaseBase): # 1. create collection client_w.create_collection(client, collection_name, default_dim, consistency_level="Strong") # 2. insert - error = {ct.err_code: 1, ct.err_msg: f"None rows, please provide valid row data."} + error = {ct.err_code: 999, ct.err_msg: f"wrong type of argument 'data',expected 'Dict' or list of 'Dict', got 'str'"} client_w.insert(client, collection_name, data, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1895") + # @pytest.mark.xfail(reason="pymilvus issue 1895") def test_milvus_client_insert_data_empty(self): """ target: test high level api: client.create_collection @@ -182,8 +180,9 @@ class TestMilvusClientInsertInvalid(TestcaseBase): # 1. create collection client_w.create_collection(client, collection_name, default_dim, consistency_level="Strong") # 2. insert - error = {ct.err_code: 1, ct.err_msg: f"None rows, please provide valid row data."} - client_w.insert(client, collection_name, data= "") + error = {ct.err_code: 999, ct.err_msg: f"wrong type of argument 'data',expected 'Dict' or list of 'Dict', got 'str'"} + client_w.insert(client, collection_name, data="", + check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) def test_milvus_client_insert_data_vector_field_missing(self): @@ -200,8 +199,8 @@ class TestMilvusClientInsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Field vector don't match in entities[0]"} - client_w.insert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"Field vector don't match in entities[0]"} + client_w.insert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) @@ -219,8 +218,8 @@ class TestMilvusClientInsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Field id don't match in entities[0]"} - client_w.insert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"Field id don't match in entities[0]"} + client_w.insert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) @@ -238,9 +237,9 @@ class TestMilvusClientInsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Attempt to insert an unexpected field " - f"to collection without enabling dynamic field"} - client_w.insert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"Attempt to insert an unexpected field `{default_float_field_name}`" + f" to collection without enabling dynamic field"} + client_w.insert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) @@ -277,9 +276,8 @@ class TestMilvusClientInsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: str(i), default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"The Input data type is inconsistent with defined schema, " - f"please check it."} - client_w.insert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"The Input data type is inconsistent with defined schema"} + client_w.insert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) @@ -535,7 +533,6 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): """ @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1883") def test_milvus_client_upsert_column_data(self): """ target: test insert column data @@ -549,7 +546,7 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): # 2. insert vectors = [[random.random() for _ in range(default_dim)] for _ in range(default_nb)] data = [[i for i in range(default_nb)], vectors] - error = {ct.err_code: 1, ct.err_msg: "Unexpected error, message=<'list' object has no attribute 'items'"} + error = {ct.err_code: 999, ct.err_msg: "Input data type is inconsistent with defined schema, please check it."} client_w.upsert(client, collection_name, data, check_task=CheckTasks.err_res, check_items=error) client_w.drop_collection(client, collection_name) @@ -566,7 +563,7 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"`collection_name` value {collection_name} is illegal"} + error = {ct.err_code: 999, ct.err_msg: f"`collection_name` value {collection_name} is illegal"} client_w.upsert(client, collection_name, rows, check_task=CheckTasks.err_res, check_items=error) @@ -623,7 +620,6 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1894") @pytest.mark.parametrize("data", ["12-s", "12 s", "(mn)", "中文", "%$#", " "]) def test_milvus_client_upsert_data_invalid_type(self, data): """ @@ -636,12 +632,11 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): # 1. create collection client_w.create_collection(client, collection_name, default_dim, consistency_level="Strong") # 2. insert - error = {ct.err_code: 1, ct.err_msg: f"None rows, please provide valid row data."} + error = {ct.err_code: 999, ct.err_msg: f"wrong type of argument 'data',expected 'Dict' or list of 'Dict', got 'str'"} client_w.upsert(client, collection_name, data, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) - @pytest.mark.xfail(reason="pymilvus issue 1895") def test_milvus_client_upsert_data_empty(self): """ target: test high level api: client.create_collection @@ -653,8 +648,9 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): # 1. create collection client_w.create_collection(client, collection_name, default_dim, consistency_level="Strong") # 2. insert - error = {ct.err_code: 1, ct.err_msg: f"None rows, please provide valid row data."} - client_w.upsert(client, collection_name, data= "") + error = {ct.err_code: 999, ct.err_msg: f"wrong type of argument 'data',expected 'Dict' or list of 'Dict', got 'str'"} + client_w.upsert(client, collection_name, data="", + check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) def test_milvus_client_upsert_data_vector_field_missing(self): @@ -671,7 +667,7 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Field vector don't match in entities[0]"} + error = {ct.err_code: 999, ct.err_msg: f"float vector field 'vector' is illegal, array type mismatch"} client_w.upsert(client, collection_name, data= rows, check_task=CheckTasks.err_res, check_items=error) @@ -690,8 +686,8 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Field id don't match in entities[0]"} - client_w.upsert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"not support vector field as PrimaryField"} + client_w.upsert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) @@ -709,8 +705,8 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: i, default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"Attempt to insert an unexpected field " - f"to collection without enabling dynamic field"} + error = {ct.err_code: 999, ct.err_msg: f"Attempt to insert an unexpected field `{default_float_field_name}` " + f"to collection without enabling dynamic field"} client_w.upsert(client, collection_name, data= rows, check_task=CheckTasks.err_res, check_items=error) @@ -748,9 +744,8 @@ class TestMilvusClientUpsertInvalid(TestcaseBase): rng = np.random.default_rng(seed=19530) rows = [{default_primary_key_field_name: str(i), default_vector_field_name: list(rng.random((1, default_dim))[0]), default_float_field_name: i * 1.0, default_string_field_name: str(i)} for i in range(default_nb)] - error = {ct.err_code: 1, ct.err_msg: f"The Input data type is inconsistent with defined schema, " - f"please check it."} - client_w.upsert(client, collection_name, data= rows, + error = {ct.err_code: 999, ct.err_msg: f"The Input data type is inconsistent with defined schema"} + client_w.upsert(client, collection_name, data=rows, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L1) diff --git a/tests/python_client/requirements.txt b/tests/python_client/requirements.txt index 8af89ea24f..00de4c1f1d 100644 --- a/tests/python_client/requirements.txt +++ b/tests/python_client/requirements.txt @@ -12,8 +12,8 @@ allure-pytest==2.7.0 pytest-print==0.2.1 pytest-level==0.1.1 pytest-xdist==2.5.0 -pymilvus==2.4.7 -pymilvus[bulk_writer]==2.4.7 +pymilvus==2.4.8 +pymilvus[bulk_writer]==2.4.8 pytest-rerunfailures==9.1.1 git+https://github.com/Projectplace/pytest-tags ndg-httpsclient diff --git a/tests/python_client/testcases/test_insert.py b/tests/python_client/testcases/test_insert.py index 72ede8c79b..1f6349b2c8 100644 --- a/tests/python_client/testcases/test_insert.py +++ b/tests/python_client/testcases/test_insert.py @@ -1819,23 +1819,30 @@ class TestUpsertValid(TestcaseBase): assert res[0]["count(*)"] == upsert_nb * 10 - step * 9 @pytest.mark.tags(CaseLabel.L2) - def test_upsert_enable_dynamic_field(self): + @pytest.mark.parametrize("auto_id", [True, False]) + def test_upsert_in_row_with_enable_dynamic_field(self, auto_id): """ - target: test upsert when enable dynamic field is True + target: test upsert in rows when enable dynamic field is True method: 1. create a collection and insert data - 2. upsert - expected: not raise exception + 2. upsert in rows + expected: upsert successfully """ upsert_nb = ct.default_nb start = ct.default_nb // 2 - collection_w = self.init_collection_general(pre_upsert, True, enable_dynamic_field=True)[0] + collection_w = self.init_collection_general(pre_upsert, insert_data=True, auto_id=auto_id, + enable_dynamic_field=True)[0] upsert_data = cf.gen_default_rows_data(start=start) for i in range(start, start + upsert_nb): upsert_data[i - start]["new"] = [i, i + 1] collection_w.upsert(data=upsert_data) - exp = f"int64 >= {start} && int64 <= {upsert_nb + start}" - res = collection_w.query(exp, output_fields=["new"])[0] - assert len(res[0]["new"]) == 2 + expr = f"float >= {start} && float <= {upsert_nb + start}" + extra_num = start if auto_id is True else 0 # upsert equals insert in this case if auto_id is True + res = collection_w.query(expr=expr, output_fields=['count(*)'])[0] + assert res[0].get('count(*)') == upsert_nb + extra_num + res = collection_w.query(expr, output_fields=["new"])[0] + assert len(res[upsert_nb + extra_num - 1]["new"]) == 2 + res = collection_w.query(expr="", output_fields=['count(*)'])[0] + assert res[0].get('count(*)') == start + upsert_nb + extra_num @pytest.mark.tags(CaseLabel.L1) @pytest.mark.skip("not support default_value now")