mirror of https://github.com/milvus-io/milvus.git
Add test cases of integer overflow" (#26645)
Signed-off-by: nico <cheng.yuan@zilliz.com>pull/26730/head
parent
6069a7d42b
commit
a8e5dc3517
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue