diff --git a/tests/python_client/common/common_func.py b/tests/python_client/common/common_func.py index 719e5322c0..e0ebae972c 100644 --- a/tests/python_client/common/common_func.py +++ b/tests/python_client/common/common_func.py @@ -1034,6 +1034,22 @@ def gen_normal_expressions_field(field): return expressions +def gen_integer_overflow_expressions(): + expressions = [ + "int8 < - 128", + "int8 > 127", + "int8 > -129 && int8 < 128", + "int16 < -32768", + "int16 >= 32768", + "int16 > -32769 && int16 <32768", + "int32 < -2147483648", + "int32 == 2147483648", + "int32 < 2147483648 || int32 == -2147483648", + "int8 in [-129, 1] || int16 in [32769] || int32 in [2147483650, 0]" + ] + return expressions + + def l2(x, y): return np.linalg.norm(np.array(x) - np.array(y)) diff --git a/tests/python_client/requirements.txt b/tests/python_client/requirements.txt index 2436612923..3e08f967ac 100644 --- a/tests/python_client/requirements.txt +++ b/tests/python_client/requirements.txt @@ -12,7 +12,7 @@ allure-pytest==2.7.0 pytest-print==0.2.1 pytest-level==0.1.1 pytest-xdist==2.5.0 -pymilvus==2.3.0b0.post1.dev126 +pymilvus==2.3.0b0.post1.dev127 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 249569fe0c..a7083863a8 100644 --- a/tests/python_client/testcases/test_insert.py +++ b/tests/python_client/testcases/test_insert.py @@ -864,6 +864,7 @@ class TestInsertOperation(TestcaseBase): assert collection_w.num_entities == nb @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_insert_one_field_using_default_value(self, default_value, auto_id): """ @@ -888,6 +889,7 @@ class TestInsertOperation(TestcaseBase): assert collection_w.num_entities == ct.default_nb @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_insert_multi_fields_using_default_value(self, default_value, auto_id): """ @@ -925,6 +927,7 @@ class TestInsertOperation(TestcaseBase): collection_w.insert(data1) @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.skip("not support default_value now") def test_insert_dataframe_using_default_value(self): """ target: test insert with dataframe @@ -1190,6 +1193,51 @@ class TestInsertInvalid(TestcaseBase): res = collection_w.insert(data=data)[0] assert res.insert_count == 2 + @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.parametrize("invalid_int8", [-129, 128]) + def test_insert_int8_overflow(self, invalid_int8): + """ + target: test insert int8 out of range + method: insert int8 out of range + expected: raise exception + """ + collection_w = self.init_collection_general(prefix, is_all_data_type=True)[0] + data = cf.gen_dataframe_all_data_type(nb=1) + data[ct.default_int8_field_name] = [invalid_int8] + error = {ct.err_code: 1, 'err_msg': "The data type of field int8 doesn't match, " + "expected: INT8, got INT64"} + collection_w.insert(data, check_task=CheckTasks.err_res, check_items=error) + + @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.parametrize("invalid_int16", [-32769, 32768]) + def test_insert_int16_overflow(self, invalid_int16): + """ + target: test insert int16 out of range + method: insert int16 out of range + expected: raise exception + """ + collection_w = self.init_collection_general(prefix, is_all_data_type=True)[0] + data = cf.gen_dataframe_all_data_type(nb=1) + data[ct.default_int16_field_name] = [invalid_int16] + error = {ct.err_code: 1, 'err_msg': "The data type of field int16 doesn't match, " + "expected: INT16, got INT64"} + collection_w.insert(data, check_task=CheckTasks.err_res, check_items=error) + + @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.parametrize("invalid_int32", [-2147483649, 2147483648]) + def test_insert_int32_overflow(self, invalid_int32): + """ + target: test insert int32 out of range + method: insert int32 out of range + expected: raise exception + """ + collection_w = self.init_collection_general(prefix, is_all_data_type=True)[0] + data = cf.gen_dataframe_all_data_type(nb=1) + data[ct.default_int32_field_name] = [invalid_int32] + error = {ct.err_code: 1, 'err_msg': "The data type of field int16 doesn't match, " + "expected: INT32, got INT64"} + collection_w.insert(data, check_task=CheckTasks.err_res, check_items=error) + @pytest.mark.tags(CaseLabel.L2) @pytest.mark.skip("no error code provided now") def test_insert_over_resource_limit(self): @@ -1207,6 +1255,7 @@ class TestInsertInvalid(TestcaseBase): collection_w.insert(data=data, check_task=CheckTasks.err_res, check_items=error) @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_insert_array_using_default_value(self, default_value): """ @@ -1224,6 +1273,7 @@ class TestInsertInvalid(TestcaseBase): check_items={ct.err_code: 1, ct.err_msg: "Field varchar don't match in entities[0]"}) @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_insert_tuple_using_default_value(self, default_value): """ @@ -1718,6 +1768,7 @@ class TestUpsertValid(TestcaseBase): assert res[0]["count(*)"] == upsert_nb * 10 - step * 9 @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_upsert_one_field_using_default_value(self, default_value): """ @@ -1740,6 +1791,7 @@ class TestUpsertValid(TestcaseBase): collection_w.upsert(data) @pytest.mark.tags(CaseLabel.L1) + @pytest.mark.skip("not support default_value now") @pytest.mark.parametrize("default_value", [[], None]) def test_upsert_multi_fields_using_default_value(self, default_value): """ @@ -1792,6 +1844,7 @@ class TestUpsertValid(TestcaseBase): collection_w.upsert(data1) @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.skip("not support default_value now") def test_upsert_dataframe_using_default_value(self): """ target: test upsert with dataframe diff --git a/tests/python_client/testcases/test_query.py b/tests/python_client/testcases/test_query.py index 2fe1b27616..451fbffc25 100644 --- a/tests/python_client/testcases/test_query.py +++ b/tests/python_client/testcases/test_query.py @@ -1143,6 +1143,39 @@ class TestQueryParams(TestcaseBase): error = {ct.err_code: 1, ct.err_msg: "invalid max query result window, offset [-1] is invalid, should be gte than 0"} collection_w.query("", limit=2, offset=-1, check_task=CheckTasks.err_res, check_items=error) + @pytest.mark.tags(CaseLabel.L2) + @pytest.mark.parametrize("expression", cf.gen_integer_overflow_expressions()) + def test_query_expr_out_of_range(self, expression): + """ + target: test query expression out of range + method: query empty expression with limit and offset out of range + expected: + """ + # 1. initialize with data + collection_w = self.init_collection_general(prefix, is_all_data_type=True)[0] + start = ct.default_nb // 2 + _vectors = cf.gen_dataframe_all_data_type(start=start) + + # increase the value to cover the int range + _vectors["int16"] = pd.Series(data=[np.int16(i*40) for i in range(start, start + ct.default_nb)], dtype="int16") + _vectors["int32"] = pd.Series(data=[np.int32(i*2200000) for i in range(start, start + ct.default_nb)], dtype="int32") + insert_ids = collection_w.insert(_vectors)[0].primary_keys + + # filter result with expression in collection + expression = expression.replace("&&", "and").replace("||", "or") + filter_ids = [] + for i, _id in enumerate(insert_ids): + int8 = _vectors.int8[i] + int16 = _vectors.int16[i] + int32 = _vectors.int32[i] + if not expression or eval(expression): + filter_ids.append(_id) + + # query + collection_w.load() + res = collection_w.query(expression, output_fields=["int8"])[0] + assert len(res) == len(filter_ids) + @pytest.mark.tags(CaseLabel.L1) def test_query_output_field_none_or_empty(self, enable_dynamic_field): """