test_utility.py 57.1 KB
Newer Older
T
ThreadDao 已提交
1 2
import threading

紫晴 已提交
3
import pytest
4
from base.client_base import TestcaseBase
5
from base.utility_wrapper import ApiUtilityWrapper
紫晴 已提交
6
from utils.util_log import test_log as log
D
del-zhenwu 已提交
7 8
from common import common_func as cf
from common import common_type as ct
D
del-zhenwu 已提交
9
from common.common_type import CaseLabel, CheckTasks
紫晴 已提交
10

D
del-zhenwu 已提交
11 12
prefix = "utility"
default_schema = cf.gen_default_collection_schema()
13
default_int64_field_name = ct.default_int64_field_name
D
del-zhenwu 已提交
14 15
default_field_name = ct.default_float_vec_field_name
default_index_params = {"index_type": "IVF_SQ8", "metric_type": "L2", "params": {"nlist": 64}}
16 17
default_dim = ct.default_dim
default_nb = ct.default_nb
18 19
num_loaded_entities = "num_loaded_entities"
num_total_entities = "num_total_entities"
紫晴 已提交
20 21


22
class TestUtilityParams(TestcaseBase):
D
del-zhenwu 已提交
23 24
    """ Test case of index interface """

B
binbin 已提交
25 26 27 28
    @pytest.fixture(scope="function", params=ct.get_invalid_strs)
    def get_invalid_metric_type(self, request):
        if request.param == [] or request.param == "":
            pytest.skip("metric empty is valid for distance calculation")
29 30 31 32 33 34 35 36 37 38 39 40 41 42
        if isinstance(request.param, str):
            pytest.skip("string is valid type for metric")
        yield request.param

    @pytest.fixture(scope="function", params=ct.get_invalid_strs)
    def get_invalid_metric_value(self, request):
        if request.param == [] or request.param == "":
            pytest.skip("metric empty is valid for distance calculation")
        if not isinstance(request.param, str):
            pytest.skip("Skip invalid type for metric")
        yield request.param

    @pytest.fixture(scope="function", params=["JACCARD", "Superstructure", "Substructure"])
    def get_not_support_metric(self, request):
B
binbin 已提交
43 44
        yield request.param

45 46 47 48
    @pytest.fixture(scope="function", params=["metric_type", "metric"])
    def get_support_metric_field(self, request):
        yield request.param

49 50 51 52 53 54 55 56 57
    @pytest.fixture(scope="function", params=ct.get_invalid_strs)
    def get_invalid_partition_names(self, request):
        if isinstance(request.param, list):
            if len(request.param) == 0:
                pytest.skip("empty is valid for partition")
        if request.param is None:
            pytest.skip("None is valid for partition")
        yield request.param

B
binbin 已提交
58 59 60 61 62
    """
    ******************************************************************
    #  The followings are invalid cases
    ******************************************************************
    """
63

D
del-zhenwu 已提交
64 65 66 67 68 69 70
    @pytest.mark.tags(CaseLabel.L1)
    def test_has_collection_name_invalid(self, get_invalid_collection_name):
        """
        target: test has_collection with error collection name
        method: input invalid name
        expected: raise exception
        """
D
del-zhenwu 已提交
71
        self._connect()
D
del-zhenwu 已提交
72
        c_name = get_invalid_collection_name
D
del-zhenwu 已提交
73
        if isinstance(c_name, str) and c_name:
Y
yanliang567 已提交
74 75 76 77
            self.utility_wrap.has_collection(
                c_name,
                check_task=CheckTasks.err_res,
                check_items={ct.err_code: 1, ct.err_msg: "Invalid collection name"})
D
del-zhenwu 已提交
78
        # elif not isinstance(c_name, str):
Y
yanliang567 已提交
79
        #     self.utility_wrap.has_collection(c_name, check_task=CheckTasks.err_res, check_items={ct.err_code: 1, ct.err_msg: "illegal"})
D
del-zhenwu 已提交
80 81 82 83 84 85 86 87

    @pytest.mark.tags(CaseLabel.L1)
    def test_has_partition_collection_name_invalid(self, get_invalid_collection_name):
        """
        target: test has_partition with error collection name
        method: input invalid name
        expected: raise exception
        """
D
del-zhenwu 已提交
88
        self._connect()
D
del-zhenwu 已提交
89 90
        c_name = get_invalid_collection_name
        p_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
91
        if isinstance(c_name, str) and c_name:
Y
yanliang567 已提交
92 93 94 95
            self.utility_wrap.has_partition(
                c_name, p_name,
                check_task=CheckTasks.err_res,
                check_items={ct.err_code: 1, ct.err_msg: "Invalid"})
D
del-zhenwu 已提交
96 97 98 99 100 101 102 103 104

    @pytest.mark.tags(CaseLabel.L1)
    def test_has_partition_name_invalid(self, get_invalid_partition_name):
        """
        target: test has_partition with error partition name
        method: input invalid name
        expected: raise exception
        """
        self._connect()
105
        ut = ApiUtilityWrapper()
D
del-zhenwu 已提交
106 107
        c_name = cf.gen_unique_str(prefix)
        p_name = get_invalid_partition_name
D
del-zhenwu 已提交
108
        if isinstance(p_name, str) and p_name:
Y
yanliang567 已提交
109 110 111 112
            ex, _ = ut.has_partition(
                c_name, p_name,
                check_task=CheckTasks.err_res,
                check_items={ct.err_code: 1, ct.err_msg: "Invalid"})
D
del-zhenwu 已提交
113

114 115 116 117 118 119 120
    @pytest.mark.tags(CaseLabel.L1)
    def test_drop_collection_name_invalid(self, get_invalid_collection_name):
        self._connect()
        error = f'`collection_name` value {get_invalid_collection_name} is illegal'
        self.utility_wrap.drop_collection(get_invalid_collection_name, check_task=CheckTasks.err_res,
                                          check_items={ct.err_code: 1, ct.err_msg: error})

D
del-zhenwu 已提交
121
    # TODO: enable
D
del-zhenwu 已提交
122
    @pytest.mark.tags(CaseLabel.L1)
123
    def test_list_collections_using_invalid(self):
D
del-zhenwu 已提交
124 125 126 127 128 129 130
        """
        target: test list_collections with invalid using
        method: input invalid name
        expected: raise exception
        """
        self._connect()
        using = "empty"
D
del-zhenwu 已提交
131
        ut = ApiUtilityWrapper()
132
        ex, _ = ut.list_collections(using=using, check_task=CheckTasks.err_res,
Y
yanliang567 已提交
133
                                    check_items={ct.err_code: 0, ct.err_msg: "should create connect"})
D
del-zhenwu 已提交
134 135 136 137 138 139 140 141

    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_invalid_name(self, get_invalid_collection_name):
        """
        target: test building_process
        method: input invalid name
        expected: raise exception
        """
Y
yanliang567 已提交
142 143 144 145
        pass
        # self._connect()
        # c_name = get_invalid_collection_name
        # ut = ApiUtilityWrapper()
D
del-zhenwu 已提交
146
        # if isinstance(c_name, str) and c_name:
Y
yanliang567 已提交
147
        #     ex, _ = ut.index_building_progress(c_name, check_items={ct.err_code: 1, ct.err_msg: "Invalid collection name"})
D
del-zhenwu 已提交
148 149 150 151 152 153 154 155 156 157 158 159

    # TODO: not support index name
    @pytest.mark.tags(CaseLabel.L1)
    def _test_index_process_invalid_index_name(self, get_invalid_index_name):
        """
        target: test building_process
        method: input invalid index name
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
        index_name = get_invalid_index_name
160
        ut = ApiUtilityWrapper()
D
del-zhenwu 已提交
161 162 163 164 165 166 167 168 169 170 171
        ex, _ = ut.index_building_progress(c_name, index_name)
        log.error(str(ex))
        assert "invalid" or "illegal" in str(ex)

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_index_invalid_name(self, get_invalid_collection_name):
        """
        target: test wait_index
        method: input invalid name
        expected: raise exception
        """
Y
yanliang567 已提交
172 173 174 175
        pass
        # self._connect()
        # c_name = get_invalid_collection_name
        # ut = ApiUtilityWrapper()
D
del-zhenwu 已提交
176
        # if isinstance(c_name, str) and c_name:
Y
yanliang567 已提交
177
        #     ex, _ = ut.wait_for_index_building_complete(c_name, check_items={ct.err_code: 1, ct.err_msg: "Invalid collection name"})
D
del-zhenwu 已提交
178 179

    @pytest.mark.tags(CaseLabel.L1)
180
    def _test_wait_index_invalid_index_name(self, get_invalid_index_name):
D
del-zhenwu 已提交
181 182 183 184 185 186 187 188
        """
        target: test wait_index
        method: input invalid index name
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
        index_name = get_invalid_index_name
189
        ut = ApiUtilityWrapper()
D
del-zhenwu 已提交
190 191 192 193
        ex, _ = ut.wait_for_index_building_complete(c_name, index_name)
        log.error(str(ex))
        assert "invalid" or "illegal" in str(ex)

194 195 196 197 198 199 200 201 202 203
    @pytest.mark.tags(CaseLabel.L1)
    @pytest.mark.parametrize("invalid_c_name", ["12-s", "12 s", "(mn)", "中文", "%$#"])
    def test_loading_progress_invalid_collection_name(self, invalid_c_name):
        """
        target: test loading progress with invalid collection name
        method: input invalid collection name
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
204
        df = cf.gen_default_dataframe_data()
205 206 207 208 209 210 211 212 213 214 215 216 217 218
        self.collection_wrap.construct_from_dataframe(c_name, df, primary_field=ct.default_int64_field_name)
        self.collection_wrap.load()
        error = {ct.err_code: 1, ct.err_msg: "Invalid collection name: {}".format(invalid_c_name)}
        self.utility_wrap.loading_progress(invalid_c_name, check_task=CheckTasks.err_res, check_items=error)

    @pytest.mark.tags(CaseLabel.L1)
    def test_loading_progress_not_existed_collection_name(self):
        """
        target: test loading progress with invalid collection name
        method: input invalid collection name
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
219
        df = cf.gen_default_dataframe_data()
220 221 222 223 224 225
        self.collection_wrap.construct_from_dataframe(c_name, df, primary_field=ct.default_int64_field_name)
        self.collection_wrap.load()
        error = {ct.err_code: 1, ct.err_msg: "describe collection failed: can't find collection"}
        self.utility_wrap.loading_progress("not_existed_name", check_task=CheckTasks.err_res, check_items=error)

    @pytest.mark.tag(CaseLabel.L1)
226
    @pytest.mark.xfail(reason="pymilvus issue #677")
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    def test_loading_progress_invalid_partition_names(self, get_invalid_partition_names):
        """
        target: test loading progress with invalid partition names
        method: input invalid partition names
        expected: raise an exception
        """
        collection_w = self.init_collection_general(prefix)[0]
        partition_names = get_invalid_partition_names
        err_msg = {ct.err_code: 0, ct.err_msg: "`partition_name_array` value {} is illegal".format(partition_names)}
        collection_w.load()
        self.utility_wrap.loading_progress(collection_w.name, partition_names,
                                           check_task=CheckTasks.err_res, check_items=err_msg)

    @pytest.mark.tag(CaseLabel.L1)
    @pytest.mark.parametrize("partition_names", [[ct.default_tag], [ct.default_partition_name, ct.default_tag]])
    def test_loading_progress_not_existed_partitions(self, partition_names):
        """
        target: test loading progress with not existed partitions
        method: input all or part not existed partition names
        expected: raise exception
        """
        collection_w = self.init_collection_general(prefix)[0]
        log.debug(collection_w.num_entities)
        collection_w.load()
251
        err_msg = {ct.err_code: 1, ct.err_msg: f"partitionID of partitionName:{ct.default_tag} can not be found"}
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
        self.utility_wrap.loading_progress(collection_w.name, partition_names,
                                           check_task=CheckTasks.err_res, check_items=err_msg)

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_for_loading_collection_not_existed(self):
        """
        target: test wait for loading
        method: input collection not created before
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
        self.utility_wrap.wait_for_loading_complete(
            c_name,
            check_task=CheckTasks.err_res,
            check_items={ct.err_code: 1, ct.err_msg: "can't find collection"})

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_for_loading_partition_not_existed(self):
        """
        target: test wait for loading
        method: input partition not created before
        expected: raise exception
        """
        self._connect()
        collection_w = self.init_collection_wrap()
        self.utility_wrap.wait_for_loading_complete(
            collection_w.name, partition_names=[ct.default_tag],
            check_task=CheckTasks.err_res,
            check_items={ct.err_code: 1, ct.err_msg: f'partitionID of partitionName:{ct.default_tag} can not be find'})

T
ThreadDao 已提交
283
    def test_drop_collection_not_existed(self):
284 285 286 287 288 289 290 291 292 293
        """
        target: test drop an not existed collection
        method: drop a not created collection
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
        error = {ct.err_code: 0, ct.err_msg: "describe collection failed: can't find collection:"}
        self.utility_wrap.drop_collection(c_name, check_task=CheckTasks.err_res, check_items=error)

294 295 296 297 298 299 300 301 302 303 304 305 306
    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_left_vector_invalid_type(self, get_invalid_vector_dict):
        """
        target: test calculated distance with invalid vectors
        method: input invalid vectors type
        expected: raise exception
        """
        self._connect()
        invalid_vector = get_invalid_vector_dict
        if not isinstance(invalid_vector, dict):
            self.utility_wrap.calc_distance(invalid_vector, invalid_vector,
                                            check_task=CheckTasks.err_res,
                                            check_items={"err_code": 1,
307 308
                                                         "err_msg": "vectors_left value {} "
                                                                    "is illegal".format(invalid_vector)})
309 310 311 312 313 314 315 316 317 318 319 320 321 322

    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_left_vector_invalid_value(self, get_invalid_vector_dict):
        """
        target: test calculated distance with invalid vectors
        method: input invalid vectors value
        expected: raise exception
        """
        self._connect()
        invalid_vector = get_invalid_vector_dict
        if isinstance(invalid_vector, dict):
            self.utility_wrap.calc_distance(invalid_vector, invalid_vector,
                                            check_task=CheckTasks.err_res,
                                            check_items={"err_code": 1,
323 324
                                                         "err_msg": "vectors_left value {} "
                                                                    "is illegal".format(invalid_vector)})
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_right_vector_invalid_type(self, get_invalid_vector_dict):
        """
        target: test calculated distance with invalid vectors
        method: input invalid vectors type
        expected: raise exception
        """
        self._connect()
        invalid_vector = get_invalid_vector_dict
        vector = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vector}
        if not isinstance(invalid_vector, dict):
            self.utility_wrap.calc_distance(op_l, invalid_vector,
                                            check_task=CheckTasks.err_res,
                                            check_items={"err_code": 1,
341 342
                                                         "err_msg": "vectors_right value {} "
                                                                    "is illegal".format(invalid_vector)})
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358

    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_right_vector_invalid_value(self, get_invalid_vector_dict):
        """
        target: test calculated distance with invalid vectors
        method: input invalid vectors value
        expected: raise exception
        """
        self._connect()
        invalid_vector = get_invalid_vector_dict
        vector = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vector}
        if isinstance(invalid_vector, dict):
            self.utility_wrap.calc_distance(op_l, invalid_vector,
                                            check_task=CheckTasks.err_res,
                                            check_items={"err_code": 1,
359 360
                                                         "err_msg": "vectors_right value {} "
                                                                    "is illegal".format(invalid_vector)})
361

B
binbin 已提交
362
    @pytest.mark.tags(CaseLabel.L2)
363
    def test_calc_distance_invalid_metric_type(self, get_support_metric_field, get_invalid_metric_type):
B
binbin 已提交
364 365 366 367 368 369 370 371 372 373
        """
        target: test calculated distance with invalid metric
        method: input invalid metric
        expected: raise exception
        """
        self._connect()
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
374
        metric_field = get_support_metric_field
B
binbin 已提交
375
        metric = get_invalid_metric_type
376
        params = {metric_field: metric}
377 378 379
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
380 381
                                                     "err_msg": "params value {{'metric': {}}} "
                                                                "is illegal".format(metric)})
382 383

    @pytest.mark.tags(CaseLabel.L2)
384
    def test_calc_distance_invalid_metric_value(self, get_support_metric_field, get_invalid_metric_value):
385 386 387 388 389 390 391 392 393 394
        """
        target: test calculated distance with invalid metric
        method: input invalid metric
        expected: raise exception
        """
        self._connect()
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
395
        metric_field = get_support_metric_field
396
        metric = get_invalid_metric_value
397
        params = {metric_field: metric}
398 399 400
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
401 402
                                                     "err_msg": "{} metric type is invalid for "
                                                                "float vector".format(metric)})
403 404

    @pytest.mark.tags(CaseLabel.L2)
405
    def test_calc_distance_not_support_metric(self, get_support_metric_field, get_not_support_metric):
406 407 408 409 410 411 412 413 414 415
        """
        target: test calculated distance with invalid metric
        method: input invalid metric
        expected: raise exception
        """
        self._connect()
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
416
        metric_field = get_support_metric_field
417
        metric = get_not_support_metric
418
        params = {metric_field: metric}
B
binbin 已提交
419 420 421
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
422 423
                                                     "err_msg": "{} metric type is invalid for "
                                                                "float vector".format(metric)})
B
binbin 已提交
424

425
    @pytest.mark.tags(CaseLabel.L2)
426
    def test_calc_distance_invalid_using(self, get_support_metric_field):
427 428 429 430 431 432
        """
        target: test calculated distance with invalid using
        method: input invalid using
        expected: raise exception
        """
        self._connect()
B
binbin 已提交
433 434
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
435 436
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
437 438
        metric_field = get_support_metric_field
        params = {metric_field: "L2", "sqrt": True}
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        using = "empty"
        self.utility_wrap.calc_distance(op_l, op_r, params, using=using,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
                                                     "err_msg": "should create connect"})

    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_not_match_dim(self):
        """
        target: test calculated distance with invalid vectors
        method: input invalid vectors type and value
        expected: raise exception
        """
        self._connect()
        dim = 129
        vector_l = cf.gen_vectors(default_nb, default_dim)
        vector_r = cf.gen_vectors(default_nb, dim)
        op_l = {"float_vectors": vector_l}
        op_r = {"float_vectors": vector_r}
B
binbin 已提交
458 459 460 461 462 463 464
        self.utility_wrap.calc_distance(op_l, op_r,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
                                                     "err_msg": "Cannot calculate distance between "
                                                                "vectors with different dimension"})

    @pytest.mark.tags(CaseLabel.L2)
465
    def test_calc_distance_collection_before_load(self, get_support_metric_field):
B
binbin 已提交
466 467 468 469 470 471 472 473 474 475 476 477 478 479
        """
        target: test calculated distance when entities is not ready
        method: calculate distance before load
        expected: raise exception
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb,
                                                                            is_index=True)
        middle = len(insert_ids) // 2
        op_l = {"ids": insert_ids[:middle], "collection": collection_w.name,
                "field": default_field_name}
        op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                "field": default_field_name}
480 481
        metric_field = get_support_metric_field
        params = {metric_field: "L2", "sqrt": True}
B
binbin 已提交
482 483 484
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.err_res,
                                        check_items={"err_code": 1,
485 486
                                                     "err_msg": "collection {} was not "
                                                                "loaded into memory)".format(collection_w.name)})
D
del-zhenwu 已提交
487

488

489
class TestUtilityBase(TestcaseBase):
D
del-zhenwu 已提交
490 491
    """ Test case of index interface """

492 493 494 495
    @pytest.fixture(scope="function", params=["metric_type", "metric"])
    def metric_field(self, request):
        yield request.param

496 497 498 499 500 501 502 503
    @pytest.fixture(scope="function", params=[True, False])
    def sqrt(self, request):
        yield request.param

    @pytest.fixture(scope="function", params=["L2", "IP"])
    def metric(self, request):
        yield request.param

504
    @pytest.fixture(scope="function", params=["HAMMING", "TANIMOTO"])
505 506 507
    def metric_binary(self, request):
        yield request.param

D
del-zhenwu 已提交
508 509 510 511 512 513 514
    @pytest.mark.tags(CaseLabel.L1)
    def test_has_collection(self):
        """
        target: test has_collection with collection name
        method: input collection name created before
        expected: True
        """
D
del-zhenwu 已提交
515 516
        cw = self.init_collection_wrap()
        res, _ = self.utility_wrap.has_collection(cw.name)
D
del-zhenwu 已提交
517 518
        assert res is True

Y
yanliang567 已提交
519
    @pytest.mark.tags(CaseLabel.L2)
D
del-zhenwu 已提交
520 521 522 523 524 525 526
    def test_has_collection_not_created(self):
        """
        target: test has_collection with collection name which is not created
        method: input random collection name
        expected: False
        """
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
527 528
        _ = self.init_collection_wrap()
        res, _ = self.utility_wrap.has_collection(c_name)
D
del-zhenwu 已提交
529 530 531 532 533 534 535 536 537 538
        assert res is False

    @pytest.mark.tags(CaseLabel.L1)
    def test_has_collection_after_drop(self):
        """
        target: test has_collection with collection name droped before
        method: input random collection name
        expected: False
        """
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
539 540
        cw = self.init_collection_wrap(name=c_name)
        res, _ = self.utility_wrap.has_collection(c_name)
D
del-zhenwu 已提交
541
        assert res is True
D
del-zhenwu 已提交
542 543
        cw.drop()
        res, _ = self.utility_wrap.has_collection(c_name)
D
del-zhenwu 已提交
544 545
        assert res is False

Y
yanliang567 已提交
546
    @pytest.mark.tags(CaseLabel.L2)
D
del-zhenwu 已提交
547 548 549 550 551 552 553
    def test_has_partition(self):
        """
        target: test has_partition with partition name
        method: input collection name and partition name created before
        expected: True
        """
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
554 555 556 557
        p_name = cf.gen_unique_str(prefix)
        cw = self.init_collection_wrap(name=c_name)
        self.init_partition_wrap(cw, p_name)
        res, _ = self.utility_wrap.has_partition(c_name, p_name)
D
del-zhenwu 已提交
558 559 560 561 562 563 564 565 566 567 568
        assert res is True

    @pytest.mark.tags(CaseLabel.L1)
    def test_has_partition_not_created(self):
        """
        target: test has_partition with partition name
        method: input collection name, and partition name not created before
        expected: True
        """
        c_name = cf.gen_unique_str(prefix)
        p_name = cf.gen_unique_str()
D
del-zhenwu 已提交
569 570
        self.init_collection_wrap(name=c_name)
        res, _ = self.utility_wrap.has_partition(c_name, p_name)
D
del-zhenwu 已提交
571 572 573 574 575 576 577 578 579 580 581
        assert res is False

    @pytest.mark.tags(CaseLabel.L1)
    def test_has_partition_after_drop(self):
        """
        target: test has_partition with partition name
        method: input collection name, and partition name dropped
        expected: True
        """
        c_name = cf.gen_unique_str(prefix)
        p_name = cf.gen_unique_str()
D
del-zhenwu 已提交
582 583 584
        cw = self.init_collection_wrap(name=c_name)
        pw = self.init_partition_wrap(cw, p_name)
        res, _ = self.utility_wrap.has_partition(c_name, p_name)
D
del-zhenwu 已提交
585
        assert res is True
D
del-zhenwu 已提交
586 587
        pw.drop()
        res, _ = self.utility_wrap.has_partition(c_name, p_name)
D
del-zhenwu 已提交
588 589
        assert res is False

590 591 592 593 594 595 596 597 598 599 600 601
    @pytest.mark.tags(CaseLabel.L2)
    def test_has_default_partition(self):
        """
        target: test has_partition with '_default' partition
        method: input collection name and partition name created before
        expected: True
        """
        c_name = cf.gen_unique_str(prefix)
        self.init_collection_wrap(name=c_name)
        res, _ = self.utility_wrap.has_partition(c_name, ct.default_partition_name)
        assert res is True

D
del-zhenwu 已提交
602 603 604 605 606 607 608 609
    @pytest.mark.tags(CaseLabel.L1)
    def test_list_collections(self):
        """
        target: test list_collections
        method: create collection, list_collections
        expected: in the result
        """
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
610 611
        self.init_collection_wrap(name=c_name)
        res, _ = self.utility_wrap.list_collections()
D
del-zhenwu 已提交
612 613 614 615 616 617 618 619 620 621 622
        assert c_name in res

    # TODO: make sure all collections deleted
    @pytest.mark.tags(CaseLabel.L1)
    def _test_list_collections_no_collection(self):
        """
        target: test list_collections
        method: no collection created, list_collections
        expected: length of the result equals to 0
        """
        self._connect()
D
del-zhenwu 已提交
623
        res, _ = self.utility_wrap.list_collections()
D
del-zhenwu 已提交
624 625 626 627 628 629 630 631 632 633 634
        assert len(res) == 0

    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_collection_not_existed(self):
        """
        target: test building_process
        method: input collection not created before
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
Y
yanliang567 已提交
635
        self.utility_wrap.index_building_progress(
636 637 638
            c_name,
            check_task=CheckTasks.err_res,
            check_items={ct.err_code: 1, ct.err_msg: "can't find collection"})
D
del-zhenwu 已提交
639 640 641 642 643 644 645 646 647

    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_collection_empty(self):
        """
        target: test building_process
        method: input empty collection
        expected: no exception raised
        """
        c_name = cf.gen_unique_str(prefix)
648 649 650 651 652
        cw = self.init_collection_wrap(name=c_name)
        self.index_wrap.init_index(cw.collection, default_field_name, default_index_params)
        res, _ = self.utility_wrap.index_building_progress(c_name)
        exp_res = {'total_rows': 0, 'indexed_rows': 0}
        assert res == exp_res
D
del-zhenwu 已提交
653

D
del-zhenwu 已提交
654 655 656 657 658 659 660 661 662
    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_collection_insert_no_index(self):
        """
        target: test building_process
        method: insert 1 entity, no index created
        expected: no exception raised
        """
        nb = 1
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
663
        cw = self.init_collection_wrap(name=c_name)
D
del-zhenwu 已提交
664
        data = cf.gen_default_list_data(nb)
D
del-zhenwu 已提交
665
        cw.insert(data=data)
666 667
        error = {ct.err_code: 1, ct.err_msg: "no index is created"}
        self.utility_wrap.index_building_progress(c_name, check_task=CheckTasks.err_res, check_items=error)
D
del-zhenwu 已提交
668

D
del-zhenwu 已提交
669 670 671 672
    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_collection_index(self):
        """
        target: test building_process
673 674 675
        method: 1.insert 1024 (because minSegmentSizeToEnableIndex=1024)
                2.build(server does create index) and call building_process
        expected: indexed_rows=0
D
del-zhenwu 已提交
676
        """
677
        nb = 1024
D
del-zhenwu 已提交
678
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
679
        cw = self.init_collection_wrap(name=c_name)
D
del-zhenwu 已提交
680
        data = cf.gen_default_list_data(nb)
D
del-zhenwu 已提交
681
        cw.insert(data=data)
682 683 684 685
        cw.create_index(default_field_name, default_index_params)
        res, _ = self.utility_wrap.index_building_progress(c_name)
        assert res['indexed_rows'] == 0
        assert res['total_rows'] == nb
D
del-zhenwu 已提交
686 687 688 689 690

    @pytest.mark.tags(CaseLabel.L1)
    def test_index_process_collection_indexing(self):
        """
        target: test building_process
691 692 693
        method: 1.insert 2048 entities to ensure that server will build
                2.call building_process during building
        expected: 2048 or less entities indexed
D
del-zhenwu 已提交
694
        """
695
        nb = 2048
D
del-zhenwu 已提交
696
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
697
        cw = self.init_collection_wrap(name=c_name)
D
del-zhenwu 已提交
698
        data = cf.gen_default_list_data(nb)
D
del-zhenwu 已提交
699 700 701
        cw.insert(data=data)
        cw.create_index(default_field_name, default_index_params)
        res, _ = self.utility_wrap.index_building_progress(c_name)
702 703 704 705 706 707 708 709
        assert (0 < res['indexed_rows'] <= nb)
        assert res['total_rows'] == nb
        # for _ in range(2):
        #     assert "indexed_rows" in res
        #     assert res["indexed_rows"] <= nb
        #     assert res["indexed_rows"] >= 0
        #     assert "total_rows" in res
        #     assert res["total_rows"] == nb
D
del-zhenwu 已提交
710 711 712 713 714 715 716 717 718 719

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_index_collection_not_existed(self):
        """
        target: test wait_index
        method: input collection not created before
        expected: raise exception
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
Y
yanliang567 已提交
720
        self.utility_wrap.wait_for_index_building_complete(
721 722 723
            c_name,
            check_task=CheckTasks.err_res,
            check_items={ct.err_code: 1, ct.err_msg: "can't find collection"})
D
del-zhenwu 已提交
724 725 726 727 728 729 730 731 732 733

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_index_collection_empty(self):
        """
        target: test wait_index
        method: input empty collection
        expected: no exception raised
        """
        self._connect()
        c_name = cf.gen_unique_str(prefix)
734 735 736 737 738 739
        cw = self.init_collection_wrap(name=c_name)
        cw.create_index(default_field_name, default_index_params)
        assert self.utility_wrap.wait_for_index_building_complete(c_name)[0]
        res, _ = self.utility_wrap.index_building_progress(c_name)
        exp_res = {'total_rows': 0, 'indexed_rows': 0}
        assert res == exp_res
D
del-zhenwu 已提交
740 741 742 743 744

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_index_collection_index(self):
        """
        target: test wait_index
Y
yanliang567 已提交
745 746
        method: insert 5000 entities, build and call wait_index
        expected: 5000 entity indexed
D
del-zhenwu 已提交
747
        """
Y
yanliang567 已提交
748
        nb = 5000
D
del-zhenwu 已提交
749
        c_name = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
750
        cw = self.init_collection_wrap(name=c_name)
D
del-zhenwu 已提交
751
        data = cf.gen_default_list_data(nb)
D
del-zhenwu 已提交
752 753 754
        cw.insert(data=data)
        cw.create_index(default_field_name, default_index_params)
        res, _ = self.utility_wrap.wait_for_index_building_complete(c_name)
Y
yanliang567 已提交
755
        assert res is True
D
del-zhenwu 已提交
756 757
        res, _ = self.utility_wrap.index_building_progress(c_name)
        assert res["indexed_rows"] == nb
D
del-zhenwu 已提交
758

759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
    @pytest.mark.tag(CaseLabel.L1)
    def test_loading_progress_without_loading(self):
        """
        target: test loading progress without loading
        method: insert and flush data, call loading_progress without loading
        expected: loaded entities is 0
        """
        collection_w = self.init_collection_wrap()
        df = cf.gen_default_dataframe_data()
        collection_w.insert(df)
        assert collection_w.num_entities == ct.default_nb
        exp_res = {num_loaded_entities: 0, num_total_entities: ct.default_nb}
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        assert res == exp_res

    @pytest.mark.tag(CaseLabel.L1)
    @pytest.mark.parametrize("nb", [ct.default_nb, 5000])
    def test_loading_progress_collection(self, nb):
        """
        target: test loading progress
        method: 1.insert flush and load 2.call loading_progress
        expected: all entities is loafed, because load is synchronous
        """
        # create, insert default_nb, flush and load
        collection_w = self.init_collection_general(prefix, insert_data=True, nb=nb)[0]
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        assert res[num_total_entities] == nb
        assert res[num_loaded_entities] == nb

    @pytest.mark.tag(CaseLabel.L1)
    @pytest.mark.xfail(reason="pymilvus issue #702")
    def test_loading_progress_with_async_load(self):
        """
        target: test loading progress with async collection load
        method: 1.load collection with async=True 2.loading_progress
        expected: loading part entities
        """
        collection_w = self.init_collection_wrap()
        df = cf.gen_default_dataframe_data()
        collection_w.insert(df)
        assert collection_w.num_entities == ct.default_nb
        collection_w.load(_async=True)
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        assert (0 < res[num_loaded_entities] <= ct.default_nb)

    @pytest.mark.tag(CaseLabel.L1)
    def test_loading_progress_empty_collection(self):
        """
        target: test loading_progress on a empty collection
        method: 1.create collection and no insert 2.loading_progress
        expected: 0 entities is loaded
        """
        collection_w = self.init_collection_wrap()
        collection_w.load()
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        exp_res = {num_loaded_entities: 0, num_total_entities: 0}
        assert exp_res == res

    @pytest.mark.tag(CaseLabel.L1)
    def test_loading_progress_after_release(self):
        """
        target: test loading progress without loading
        method: insert and flush data, call loading_progress without loading
        expected: loaded entities is 0
        """
        collection_w = self.init_collection_general(prefix, insert_data=True)[0]
        collection_w.release()
        exp_res = {num_loaded_entities: 0, num_total_entities: ct.default_nb}
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        assert res == exp_res

    @pytest.mark.tag(CaseLabel.L2)
    def test_loading_progress_with_release_partition(self):
        """
        target: test loading progress after release part partitions
        method: 1.insert data into two partitions and flush
                2.load collection and release onr partition
        expected: loaded one partition entities
        """
        half = ct.default_nb
        # insert entities into two partitions, collection flush and load
        collection_w, partition_w, _, _ = self.insert_entities_into_two_partitions_in_half(half)
        partition_w.release()
        res = self.utility_wrap.loading_progress(collection_w.name)[0]
        assert res[num_total_entities] == half * 2
        assert res[num_loaded_entities] == half

    @pytest.mark.tag(CaseLabel.L2)
    def test_loading_progress_with_load_partition(self):
        """
        target: test loading progress after load partition
        method: 1.insert data into two partitions and flush
                2.load one partition and loading progress
        expected: loaded one partition entities
        """
        half = ct.default_nb
        collection_w, partition_w, _, _ = self.insert_entities_into_two_partitions_in_half(half)
        collection_w.release()
        partition_w.load()
        res = self.utility_wrap.loading_progress(collection_w.name)[0]
        assert res[num_total_entities] == half * 2
        assert res[num_loaded_entities] == half

    @pytest.mark.tag(CaseLabel.L1)
    def test_loading_progress_with_partition(self):
        """
        target: test loading progress with partition
        method: 1.insert data into two partitions and flush, and load
                2.loading progress with one partition
        expected: loaded one partition entities
        """
        half = ct.default_nb
        collection_w, partition_w, _, _ = self.insert_entities_into_two_partitions_in_half(half)
        res = self.utility_wrap.loading_progress(collection_w.name, partition_names=[partition_w.name])[0]
        assert res[num_total_entities] == half
        assert res[num_loaded_entities] == half

    @pytest.mark.tags(CaseLabel.L1)
    def test_wait_loading_collection_empty(self):
        """
        target: test wait_for_loading
        method: input empty collection
        expected: no exception raised
        """
        self._connect()
        cw = self.init_collection_wrap(name=cf.gen_unique_str(prefix))
        cw.load()
        self.utility_wrap.wait_for_loading_complete(cw.name)
        res, _ = self.utility_wrap.loading_progress(cw.name)
        exp_res = {num_total_entities: 0, num_loaded_entities: 0}
        assert res == exp_res

    @pytest.mark.xfail(reason="pymilvus issue #702")
    @pytest.mark.tag(CaseLabel.L1)
    def test_wait_for_loading_complete(self):
        """
        target: test wait for loading collection
        method: insert 10000 entities and wait for loading complete
        expected: after loading complete, loaded entities is 10000
        """
        nb = 6000
        collection_w = self.init_collection_wrap()
        df = cf.gen_default_dataframe_data(nb)
        collection_w.insert(df)
        assert collection_w.num_entities == nb
        collection_w.load(_async=True)
        self.utility_wrap.wait_for_loading_complete(collection_w.name)
        res, _ = self.utility_wrap.loading_progress(collection_w.name)
        assert res[num_loaded_entities] == nb

T
ThreadDao 已提交
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951
    @pytest.mark.tag(CaseLabel.L0)
    def test_drop_collection(self):
        """
        target: test utility drop collection by name
        method: input collection name and drop collection
        expected: collection is dropped
        """
        c_name = cf.gen_unique_str(prefix)
        self.init_collection_wrap(c_name)
        assert self.utility_wrap.has_collection(c_name)[0]
        self.utility_wrap.drop_collection(c_name)
        assert not self.utility_wrap.has_collection(c_name)[0]

    def test_drop_collection_repeatedly(self):
        """
        target: test drop collection repeatedly
        method: 1.collection.drop 2.utility.drop_collection
        expected: raise exception
        """
        c_name = cf.gen_unique_str(prefix)
        collection_w = self.init_collection_wrap(c_name)
        assert self.utility_wrap.has_collection(c_name)[0]
        collection_w.drop()
        assert not self.utility_wrap.has_collection(c_name)[0]
        error = {ct.err_code: 1, ct.err_msg: {"describe collection failed: can't find collection:"}}
        self.utility_wrap.drop_collection(c_name, check_task=CheckTasks.err_res, check_items=error)

    def test_drop_collection_create_repeatedly(self):
        """
        target: test repeatedly create and drop same name collection
        method: repeatedly create and drop collection
        expected: no exception
        """
        from time import sleep
        loops = 3
        c_name = cf.gen_unique_str(prefix)
        for _ in range(loops):
            self.init_collection_wrap(c_name)
            assert self.utility_wrap.has_collection(c_name)[0]
            self.utility_wrap.drop_collection(c_name)
            assert not self.utility_wrap.has_collection(c_name)[0]
            sleep(1)

952 953 954 955 956 957 958
    @pytest.mark.tags(CaseLabel.L1)
    def test_calc_distance_default(self):
        """
        target: test calculated distance with default params
        method: calculated distance between two random vectors
        expected: distance calculated successfully
        """
959
        log.info("Creating connection")
960
        self._connect()
961
        log.info("Creating vectors for distance calculation")
962 963 964 965
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
966
        log.info("Calculating distance for generated vectors")
967 968 969 970 971 972
        self.utility_wrap.calc_distance(op_l, op_r,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r})

    @pytest.mark.tags(CaseLabel.L2)
973
    def test_calc_distance_default_sqrt(self, metric_field, metric):
974 975 976 977 978
        """
        target: test calculated distance with default param
        method: calculated distance with default sqrt
        expected: distance calculated successfully
        """
B
binbin 已提交
979
        log.info("Creating connection")
980
        self._connect()
B
binbin 已提交
981
        log.info("Creating vectors for distance calculation")
982 983 984 985
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
B
binbin 已提交
986
        log.info("Calculating distance for generated vectors within default sqrt")
987
        params = {metric_field: metric}
988 989 990 991 992 993 994 995 996 997 998 999 1000
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric})

    @pytest.mark.tags(CaseLabel.L2)
    def test_calc_distance_default_metric(self, sqrt):
        """
        target: test calculated distance with default param
        method: calculated distance with default metric
        expected: distance calculated successfully
        """
B
binbin 已提交
1001
        log.info("Creating connection")
1002
        self._connect()
B
binbin 已提交
1003
        log.info("Creating vectors for distance calculation")
1004 1005 1006 1007
        vectors_l = cf.gen_vectors(default_nb, default_dim)
        vectors_r = cf.gen_vectors(default_nb, default_dim)
        op_l = {"float_vectors": vectors_l}
        op_r = {"float_vectors": vectors_r}
B
binbin 已提交
1008
        log.info("Calculating distance for generated vectors within default metric")
1009 1010 1011 1012 1013 1014 1015 1016
        params = {"sqrt": sqrt}
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1017
    def test_calc_distance_binary_metric(self, metric_field, metric_binary):
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
        """
        target: test calculate distance with binary vectors
        method: calculate distance between binary vectors
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        raw_vectors_l, vectors_l = cf.gen_binary_vectors(nb, default_dim)
        raw_vectors_r, vectors_r = cf.gen_binary_vectors(nb, default_dim)
        op_l = {"bin_vectors": vectors_l}
        op_r = {"bin_vectors": vectors_r}
1029
        params = {metric_field: metric_binary}
1030 1031
        vectors_l = raw_vectors_l
        vectors_r = raw_vectors_r
1032 1033 1034 1035 1036 1037 1038
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric_binary})

    @pytest.mark.tags(CaseLabel.L1)
1039
    def test_calc_distance_from_collection_ids(self, metric_field, metric, sqrt):
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
        """
        target: test calculated distance from collection entities
        method: both left and right vectors are from collection
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb)
        middle = len(insert_ids) // 2
        vectors = vectors[0].loc[:, default_field_name]
        vectors_l = vectors[:middle]
        vectors_r = []
        for i in range(middle):
1053
            vectors_r.append(vectors[middle + i])
1054 1055 1056 1057
        op_l = {"ids": insert_ids[:middle], "collection": collection_w.name,
                "field": default_field_name}
        op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                "field": default_field_name}
1058
        params = {metric_field: metric, "sqrt": sqrt}
1059 1060 1061 1062 1063 1064 1065 1066
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1067
    def test_calc_distance_from_collections(self, metric_field, metric, sqrt):
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
        """
        target: test calculated distance between entities from collections
        method: calculated distance between entities from two collections
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        prefix_1 = "utility_distance"
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb)
        collection_w_1, vectors_1, _, insert_ids_1 = self.init_collection_general(prefix_1, True, nb)
        vectors_l = vectors[0].loc[:, default_field_name]
        vectors_r = vectors_1[0].loc[:, default_field_name]
        op_l = {"ids": insert_ids, "collection": collection_w.name,
                "field": default_field_name}
        op_r = {"ids": insert_ids_1, "collection": collection_w_1.name,
                "field": default_field_name}
1084
        params = {metric_field: metric, "sqrt": sqrt}
1085 1086 1087 1088 1089 1090 1091 1092
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1093
    def test_calc_distance_left_vector_and_collection_ids(self, metric_field, metric, sqrt):
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
        """
        target: test calculated distance from collection entities
        method: set left vectors as random vectors, right vectors from collection
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb)
        middle = len(insert_ids) // 2
        vectors = vectors[0].loc[:, default_field_name]
        vectors_l = cf.gen_vectors(nb, default_dim)
        vectors_r = []
        for i in range(middle):
            vectors_r.append(vectors[middle + i])
        op_l = {"float_vectors": vectors_l}
        op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                "field": default_field_name}
1111
        params = {metric_field: metric, "sqrt": sqrt}
1112 1113 1114 1115 1116 1117 1118 1119
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1120
    def test_calc_distance_right_vector_and_collection_ids(self, metric_field, metric, sqrt):
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
        """
        target: test calculated distance from collection entities
        method: set right vectors as random vectors, left vectors from collection
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb)
        middle = len(insert_ids) // 2
        vectors = vectors[0].loc[:, default_field_name]
        vectors_l = vectors[:middle]
        vectors_r = cf.gen_vectors(nb, default_dim)
        op_l = {"ids": insert_ids[:middle], "collection": collection_w.name,
                "field": default_field_name}
        op_r = {"float_vectors": vectors_r}
1136
        params = {metric_field: metric, "sqrt": sqrt}
1137 1138 1139 1140 1141 1142 1143 1144
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1145
    def test_calc_distance_from_partition_ids(self, metric_field, metric, sqrt):
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
        """
        target: test calculated distance from one partition entities
        method: both left and right vectors are from partition
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb, partition_num=1)
        partitions = collection_w.partitions
        middle = len(insert_ids) // 2
1156
        params = {metric_field: metric, "sqrt": sqrt}
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
        for i in range(len(partitions)):
            vectors_l = vectors[i].loc[:, default_field_name]
            vectors_r = vectors[i].loc[:, default_field_name]
            op_l = {"ids": insert_ids[:middle], "collection": collection_w.name,
                    "partition": partitions[i].name, "field": default_field_name}
            op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                    "partition": partitions[i].name, "field": default_field_name}
            self.utility_wrap.calc_distance(op_l, op_r, params,
                                            check_task=CheckTasks.check_distance,
                                            check_items={"vectors_l": vectors_l,
                                                         "vectors_r": vectors_r,
                                                         "metric": metric,
                                                         "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1172
    def test_calc_distance_from_partitions(self, metric_field, metric, sqrt):
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
        """
        target: test calculated distance between entities from partitions
        method: calculate distance between entities from two partitions
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb, partition_num=1)
        partitions = collection_w.partitions
        middle = len(insert_ids) // 2
1183
        params = {metric_field: metric, "sqrt": sqrt}
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
        vectors_l = vectors[0].loc[:, default_field_name]
        vectors_r = vectors[1].loc[:, default_field_name]
        op_l = {"ids": insert_ids[:middle], "collection": collection_w.name,
                "partition": partitions[0].name, "field": default_field_name}
        op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                "partition": partitions[1].name, "field": default_field_name}
        self.utility_wrap.calc_distance(op_l, op_r, params,
                                        check_task=CheckTasks.check_distance,
                                        check_items={"vectors_l": vectors_l,
                                                     "vectors_r": vectors_r,
                                                     "metric": metric,
                                                     "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1198
    def test_calc_distance_left_vectors_and_partition_ids(self, metric_field, metric, sqrt):
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
        """
        target: test calculated distance between vectors and partition entities
        method: set left vectors as random vectors, right vectors are entities
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb, partition_num=1)
        middle = len(insert_ids) // 2
        partitions = collection_w.partitions
        vectors_l = cf.gen_vectors(nb // 2, default_dim)
        op_l = {"float_vectors": vectors_l}
1211
        params = {metric_field: metric, "sqrt": sqrt}
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
        for i in range(len(partitions)):
            vectors_r = vectors[i].loc[:, default_field_name]
            op_r = {"ids": insert_ids[middle:], "collection": collection_w.name,
                    "partition": partitions[i].name, "field": default_field_name}
            self.utility_wrap.calc_distance(op_l, op_r, params,
                                            check_task=CheckTasks.check_distance,
                                            check_items={"vectors_l": vectors_l,
                                                         "vectors_r": vectors_r,
                                                         "metric": metric,
                                                         "sqrt": sqrt})

    @pytest.mark.tags(CaseLabel.L2)
1224
    def test_calc_distance_right_vectors_and_partition_ids(self, metric_field, metric, sqrt):
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
        """
        target: test calculated distance between vectors and partition entities
        method: set right vectors as random vectors, left vectors are entities
        expected: distance calculated successfully
        """
        self._connect()
        nb = 10
        collection_w, vectors, _, insert_ids = self.init_collection_general(prefix, True, nb, partition_num=1)
        middle = len(insert_ids) // 2
        partitions = collection_w.partitions
        vectors_r = cf.gen_vectors(nb // 2, default_dim)
        op_r = {"float_vectors": vectors_r}
1237
        params = {metric_field: metric, "sqrt": sqrt}
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
        for i in range(len(partitions)):
            vectors_l = vectors[i].loc[:, default_field_name]
            op_l = {"ids": insert_ids[middle:], "collection": collection_w.name,
                    "partition": partitions[i].name, "field": default_field_name}
            self.utility_wrap.calc_distance(op_l, op_r, params,
                                            check_task=CheckTasks.check_distance,
                                            check_items={"vectors_l": vectors_l,
                                                         "vectors_r": vectors_r,
                                                         "metric": metric,
                                                         "sqrt": sqrt})
D
del-zhenwu 已提交
1248

1249

1250
class TestUtilityAdvanced(TestcaseBase):
D
del-zhenwu 已提交
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    """ Test case of index interface """

    @pytest.mark.tags(CaseLabel.L2)
    def test_has_collection_multi_collections(self):
        """
        target: test has_collection with collection name
        method: input collection name created before
        expected: True
        """
        c_name = cf.gen_unique_str(prefix)
        c_name_2 = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
1262 1263
        self.init_collection_wrap(name=c_name)
        self.init_collection_wrap(name=c_name_2)
D
del-zhenwu 已提交
1264
        for name in [c_name, c_name_2]:
D
del-zhenwu 已提交
1265
            res, _ = self.utility_wrap.has_collection(name)
D
del-zhenwu 已提交
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
            assert res is True

    @pytest.mark.tags(CaseLabel.L2)
    def test_list_collections_multi_collection(self):
        """
        target: test list_collections
        method: create collection, list_collections
        expected: in the result
        """
        c_name = cf.gen_unique_str(prefix)
        c_name_2 = cf.gen_unique_str(prefix)
D
del-zhenwu 已提交
1277 1278 1279
        self.init_collection_wrap(name=c_name)
        self.init_collection_wrap(name=c_name_2)
        res, _ = self.utility_wrap.list_collections()
D
del-zhenwu 已提交
1280 1281
        for name in [c_name, c_name_2]:
            assert name in res
T
ThreadDao 已提交
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312

    def test_drop_multi_collection_concurrent(self):
        """
        target: test concurrent drop collection
        method: multi thread drop one collection
        expected: drop successfully
        """
        thread_num = 3
        threads = []
        c_names = []
        num = 5

        for i in range(thread_num*num):
            c_name = cf.gen_unique_str(prefix)
            self.init_collection_wrap(c_name)
            c_names.append(c_name)

        def create_and_drop_collection(names):
            for name in names:
                assert self.utility_wrap.has_collection(name)[0]
                self.utility_wrap.drop_collection(name)
                assert not self.utility_wrap.has_collection(name)[0]

        for i in range(thread_num):
            x = threading.Thread(target=create_and_drop_collection, args=(c_names[i*num:(i+1)*num],))
            threads.append(x)
            x.start()
        for t in threads:
            t.join()
        log.debug(self.utility_wrap.list_collections()[0])