test_get_entity_by_id.py 16.5 KB
Newer Older
1 2 3 4 5 6
import time
import random
import pdb
import threading
import logging
from multiprocessing import Pool, Process
D
del-zhenwu 已提交
7
import concurrent.futures
8 9 10 11 12 13 14
import pytest
from milvus import IndexType, MetricType
from utils import *


dim = 128
index_file_size = 10
D
del-zhenwu 已提交
15
collection_id = "get_entity_by_id"
16 17 18 19 20 21 22 23 24 25
DELETE_TIMEOUT = 60
nprobe = 1
tag = "1970-01-01"
top_k = 1
nb = 6000
tag = "tag"

class TestGetBase:
    """
    ******************************************************************
D
del-zhenwu 已提交
26
      The following cases are used to test .get_entity_by_id` function
27 28
    ******************************************************************
    """
X
Xiaohai Xu 已提交
29
    def test_get_vector_A(self, connect, collection):
30
        '''
D
del-zhenwu 已提交
31
        target: test.get_entity_by_id
32 33 34 35
        method: add vector, and get
        expected: status ok, vector returned
        '''
        vector = gen_single_vector(dim)
D
del-zhenwu 已提交
36
        status, ids = connect.insert(collection, vector)
37
        assert status.OK()
X
Xiaohai Xu 已提交
38
        status = connect.flush([collection])
39
        assert status.OK()
D
del-zhenwu 已提交
40
        status, res = connect.get_entity_by_id(collection, ids) 
41
        assert status.OK()
42
        assert_equal_vector(res[0], vector[0])
43

X
Xiaohai Xu 已提交
44
    def test_get_vector_B(self, connect, collection):
45
        '''
D
del-zhenwu 已提交
46
        target: test.get_entity_by_id
47 48 49 50
        method: add vector, and get
        expected: status ok, vector returned
        '''
        vectors = gen_vectors(nb, dim)
D
del-zhenwu 已提交
51
        status, ids = connect.insert(collection, vectors)
52
        assert status.OK()
X
Xiaohai Xu 已提交
53
        status = connect.flush([collection])
54
        assert status.OK()
55
        length = 100
D
del-zhenwu 已提交
56
        status, res = connect.get_entity_by_id(collection, ids[:length])
57
        assert status.OK()
58 59 60
        for i in range(length):
            assert_equal_vector(res[i], vectors[i])

61
    def test_get_vector_C_limit(self, connect, collection, args):
62
        '''
D
del-zhenwu 已提交
63
        target: test.get_entity_by_id
64 65 66
        method: add vector, and get, limit > 1000
        expected: status ok, vector returned
        '''
67 68 69
        if args["handler"] == "HTTP":
            pytest.skip("skip in http mode")

70
        vectors = gen_vectors(nb, dim)
D
del-zhenwu 已提交
71
        status, ids = connect.insert(collection, vectors)
72 73 74
        assert status.OK()
        status = connect.flush([collection])
        assert status.OK()
D
del-zhenwu 已提交
75
        status, res = connect.get_entity_by_id(collection, ids)
76
        assert not status.OK()
77

X
Xiaohai Xu 已提交
78
    def test_get_vector_partition(self, connect, collection):
79
        '''
D
del-zhenwu 已提交
80
        target: test.get_entity_by_id
81 82 83 84
        method: add vector, and get
        expected: status ok, vector returned
        '''
        vectors = gen_vectors(nb, dim)
X
Xiaohai Xu 已提交
85
        status = connect.create_partition(collection, tag)
86
        assert status.OK()
D
del-zhenwu 已提交
87
        status, ids = connect.insert(collection, vectors, partition_tag=tag)
88
        assert status.OK()
X
Xiaohai Xu 已提交
89
        status = connect.flush([collection])
90
        assert status.OK()
91
        length = 100
D
del-zhenwu 已提交
92
        status, res = connect.get_entity_by_id(collection, ids[:length])
93
        assert status.OK()
94 95
        for i in range(length):
            assert_equal_vector(res[i], vectors[i])
96

X
Xiaohai Xu 已提交
97
    def test_get_vector_multi_same_ids(self, connect, collection):
98
        '''
D
del-zhenwu 已提交
99
        target: test.get_entity_by_id
100 101 102 103 104 105
        method: add vectors, with the same id, get vector by the given id
        expected: status ok, get one vector 
        '''
        vectors = gen_vectors(nb, dim)
        ids = [i for i in range(nb)]
        ids[1] = 0; ids[-1] = 0
D
del-zhenwu 已提交
106
        status, ids = connect.insert(collection, vectors, ids=ids)
X
Xiaohai Xu 已提交
107
        status = connect.flush([collection])
108
        assert status.OK()
D
del-zhenwu 已提交
109
        status, res = connect.get_entity_by_id(collection, [0]) 
110
        assert status.OK()
111
        assert_equal_vector(res[0], vectors[0])
112 113 114 115 116 117 118 119 120 121 122 123 124 125

    @pytest.fixture(
        scope="function",
        params=[
            1,
            10,
            100,
            1000,
            -1
        ],
    )
    def get_id(self, request):
        yield request.param

X
Xiaohai Xu 已提交
126
    def test_get_vector_after_delete(self, connect, collection, get_id):
127
        '''
D
del-zhenwu 已提交
128
        target: test.get_entity_by_id
129 130 131 132
        method: add vectors, and delete, get vector by the given id
        expected: status ok, get one vector
        '''
        vectors = gen_vectors(nb, dim)
D
del-zhenwu 已提交
133
        status, ids = connect.insert(collection, vectors)
134
        assert status.OK()
X
Xiaohai Xu 已提交
135
        status = connect.flush([collection])
136 137
        assert status.OK()
        id = get_id
D
del-zhenwu 已提交
138
        status = connect.delete_entity_by_id(collection, [ids[id]])
139
        assert status.OK()
X
Xiaohai Xu 已提交
140
        status = connect.flush([collection])
141
        assert status.OK()
D
del-zhenwu 已提交
142
        status, res = connect.get_entity_by_id(collection, [ids[id]])
143
        assert status.OK()
144
        assert not len(res[0])
145

X
Xiaohai Xu 已提交
146
    def test_get_vector_after_delete_with_partition(self, connect, collection, get_id):
147
        '''
D
del-zhenwu 已提交
148
        target: test.get_entity_by_id
149 150 151 152
        method: add vectors into partition, and delete, get vector by the given id
        expected: status ok, get one vector
        '''
        vectors = gen_vectors(nb, dim)
X
Xiaohai Xu 已提交
153 154
        status = connect.create_partition(collection, tag)
        status, ids = connect.insert(collection, vectors, partition_tag=tag)
155
        assert status.OK()
X
Xiaohai Xu 已提交
156
        status = connect.flush([collection])
157 158
        assert status.OK()
        id = get_id
D
del-zhenwu 已提交
159
        status = connect.delete_entity_by_id(collection, [ids[id]])
160
        assert status.OK()
X
Xiaohai Xu 已提交
161
        status = connect.flush([collection])
162
        assert status.OK()
D
del-zhenwu 已提交
163
        status, res = connect.get_entity_by_id(collection, [ids[id]])
164
        assert status.OK()
165
        assert not len(res[0])
166

X
Xiaohai Xu 已提交
167
    def test_get_vector_id_not_exised(self, connect, collection):
168 169 170 171 172 173
        '''
        target: test get vector, params vector_id not existed
        method: add vector and get 
        expected: status ok, empty result
        '''
        vector = gen_single_vector(dim)
D
del-zhenwu 已提交
174
        status, ids = connect.insert(collection, vector)
175
        assert status.OK()
X
Xiaohai Xu 已提交
176
        status = connect.flush([collection])
177
        assert status.OK()
D
del-zhenwu 已提交
178
        status, res = connect.get_entity_by_id(collection, [1]) 
179
        assert status.OK()
180
        assert not len(res[0])
181

X
Xiaohai Xu 已提交
182
    def test_get_vector_collection_not_existed(self, connect, collection):
183
        '''
X
Xiaohai Xu 已提交
184
        target: test get vector, params collection_name not existed
185 186 187 188
        method: add vector and get
        expected: status not ok
        '''
        vector = gen_single_vector(dim)
D
del-zhenwu 已提交
189
        status, ids = connect.insert(collection, vector)
190
        assert status.OK()
X
Xiaohai Xu 已提交
191
        status = connect.flush([collection])
192
        assert status.OK()
X
Xiaohai Xu 已提交
193
        collection_new = gen_unique_str()
D
del-zhenwu 已提交
194
        status, res = connect.get_entity_by_id(collection_new, [1]) 
195 196
        assert not status.OK()

D
del-zhenwu 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
    def test_get_vector_by_id_multithreads(self, connect, collection):
        vectors = gen_vectors(nb, dim)
        status, ids = connect.insert(collection, vectors)
        status = connect.flush([collection])
        assert status.OK()
        get_id = ids[100:200]
        def get():
            status, res = connect.get_entity_by_id(collection, get_id)
            assert status.OK()
            assert len(res) == len(get_id)
            for i in range(len(res)):
                assert_equal_vector(res[i], vectors[100+i])
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_results = {executor.submit(
                get): i for i in range(10)}
            for future in concurrent.futures.as_completed(future_results):
                future.result()

    # TODO: autoflush
    def _test_get_vector_by_id_after_delete_no_flush(self, connect, collection):
        vectors = gen_vectors(nb, dim)
        status, ids = connect.insert(collection, vectors)
        status = connect.flush([collection])
        assert status.OK()
        get_id = ids[100:200]
        status = connect.delete_entity_by_id(collection, get_id)
        assert status.OK()
        status, res = connect.get_entity_by_id(collection, get_id)
        assert status.OK()
        assert len(res) == len(get_id)
        for i in range(len(res)):
            assert_equal_vector(res[i], vectors[100+i])

230 231 232 233

class TestGetIndexedVectors:
    """
    ******************************************************************
D
del-zhenwu 已提交
234
      The following cases are used to test .get_entity_by_id` function
235 236 237 238
    ******************************************************************
    """
    @pytest.fixture(
        scope="function",
239
        params=gen_simple_index()
240
    )
241
    def get_simple_index(self, request, connect):
242 243 244 245 246 247 248
        if str(connect._cmd("mode")[1]) == "GPU":
            if request.param["index_type"] not in [IndexType.IVF_SQ8, IndexType.IVFLAT, IndexType.FLAT, IndexType.IVF_PQ, IndexType.IVF_SQ8H]:
                pytest.skip("Only support index_type: idmap/ivf")
        elif str(connect._cmd("mode")[1]) == "CPU":
            if request.param["index_type"] in [IndexType.IVF_SQ8H]:
                pytest.skip("CPU not support index_type: ivf_sq8h")

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
        return request.param

    @pytest.fixture(
        scope="function",
        params=[
            1,
            10,
            100,
            1000,
            -1
        ],
    )
    def get_id(self, request):
        yield request.param

X
Xiaohai Xu 已提交
264
    def test_get_vectors_after_index_created(self, connect, collection, get_simple_index, get_id):
265 266 267 268 269
        '''
        target: test get vector after index created
        method: add vector, create index and get vector
        expected: status ok
        '''
270 271
        index_param = get_simple_index["index_param"]
        index_type = get_simple_index["index_type"]
272
        vectors = gen_vector(nb, dim)
D
del-zhenwu 已提交
273
        status, ids = connect.insert(collection, vectors)
274
        assert status.OK()
X
Xiaohai Xu 已提交
275
        status = connect.flush([collection])
276
        assert status.OK()
X
Xiaohai Xu 已提交
277
        status = connect.create_index(collection, index_type, index_param)
278 279
        assert status.OK()
        id = get_id
D
del-zhenwu 已提交
280
        status, res = connect.get_entity_by_id(collection, [ids[id]])
281
        assert status.OK()
282
        assert_equal_vector(res[0], vectors[id])
283

X
Xiaohai Xu 已提交
284
    def test_get_vector_after_delete(self, connect, collection, get_simple_index, get_id):
285
        '''
D
del-zhenwu 已提交
286
        target: test.get_entity_by_id
287 288 289
        method: add vectors, and delete, get vector by the given id
        expected: status ok, get one vector
        '''
290 291
        index_param = get_simple_index["index_param"]
        index_type = get_simple_index["index_type"]
292
        vectors = gen_vectors(nb, dim)
D
del-zhenwu 已提交
293
        status, ids = connect.insert(collection, vectors)
294
        assert status.OK()
X
Xiaohai Xu 已提交
295
        status = connect.flush([collection])
296
        assert status.OK()
X
Xiaohai Xu 已提交
297
        status = connect.create_index(collection, index_type, index_param)
298 299
        assert status.OK()
        id = get_id
D
del-zhenwu 已提交
300
        status = connect.delete_entity_by_id(collection, [ids[id]])
301
        assert status.OK()
X
Xiaohai Xu 已提交
302
        status = connect.flush([collection])
303
        assert status.OK()
D
del-zhenwu 已提交
304
        status, res = connect.get_entity_by_id(collection, [ids[id]])
305
        assert status.OK()
306
        assert not len(res[0])
307

X
Xiaohai Xu 已提交
308
    def test_get_vector_partition(self, connect, collection, get_simple_index, get_id):
309
        '''
D
del-zhenwu 已提交
310
        target: test.get_entity_by_id
311 312 313
        method: add vector, and get
        expected: status ok, vector returned
        '''
314 315
        index_param = get_simple_index["index_param"]
        index_type = get_simple_index["index_type"]
316
        vectors = gen_vectors(nb, dim)
X
Xiaohai Xu 已提交
317
        status = connect.create_partition(collection, tag)
318
        ids = [i for i in range(nb)] 
D
del-zhenwu 已提交
319
        status, ids = connect.insert(collection, vectors, ids, partition_tag=tag)
320
        assert status.OK()
X
Xiaohai Xu 已提交
321
        status = connect.flush([collection])
322
        assert status.OK()
X
Xiaohai Xu 已提交
323
        status = connect.create_index(collection, index_type, index_param)
324 325
        assert status.OK()
        id = get_id
D
del-zhenwu 已提交
326
        status, res = connect.get_entity_by_id(collection, [ids[id]])
327
        assert status.OK()
328
        assert_equal_vector(res[0], vectors[id])
329 330 331 332 333


class TestGetBinary:
    """
    ******************************************************************
D
del-zhenwu 已提交
334
      The following cases are used to test .get_entity_by_id` function
335 336
    ******************************************************************
    """
X
Xiaohai Xu 已提交
337
    def test_get_vector_A(self, connect, jac_collection):
338
        '''
D
del-zhenwu 已提交
339
        target: test.get_entity_by_id
340 341 342 343
        method: add vector, and get
        expected: status ok, vector returned
        '''
        tmp, vector = gen_binary_vectors(1, dim)
D
del-zhenwu 已提交
344
        status, ids = connect.insert(jac_collection, vector)
345
        assert status.OK()
X
Xiaohai Xu 已提交
346
        status = connect.flush([jac_collection])
347
        assert status.OK()
D
del-zhenwu 已提交
348
        status, res = connect.get_entity_by_id(jac_collection, [ids[0]]) 
349
        assert status.OK()
350
        assert_equal_vector(res[0], vector[0])
351

X
Xiaohai Xu 已提交
352
    def test_get_vector_B(self, connect, jac_collection):
353
        '''
D
del-zhenwu 已提交
354
        target: test.get_entity_by_id
355 356 357 358
        method: add vector, and get
        expected: status ok, vector returned
        '''
        tmp, vectors = gen_binary_vectors(nb, dim)
D
del-zhenwu 已提交
359
        status, ids = connect.insert(jac_collection, vectors)
360
        assert status.OK()
X
Xiaohai Xu 已提交
361
        status = connect.flush([jac_collection])
362
        assert status.OK()
D
del-zhenwu 已提交
363
        status, res = connect.get_entity_by_id(jac_collection, [ids[0]])
364
        assert status.OK()
365
        assert_equal_vector(res[0], vectors[0])
366

X
Xiaohai Xu 已提交
367
    def test_get_vector_multi_same_ids(self, connect, jac_collection):
368
        '''
D
del-zhenwu 已提交
369
        target: test.get_entity_by_id
370 371 372 373 374 375
        method: add vectors, with the same id, get vector by the given id
        expected: status ok, get one vector 
        '''
        tmp, vectors = gen_binary_vectors(nb, dim)
        ids = [i for i in range(nb)]
        ids[0] = 0; ids[-1] = 0
D
del-zhenwu 已提交
376
        status, ids = connect.insert(jac_collection, vectors, ids=ids)
X
Xiaohai Xu 已提交
377
        status = connect.flush([jac_collection])
378
        assert status.OK()
D
del-zhenwu 已提交
379
        status, res = connect.get_entity_by_id(jac_collection, [0]) 
380
        assert status.OK()
381
        assert_equal_vector(res[0], vectors[0])
382

X
Xiaohai Xu 已提交
383
    def test_get_vector_id_not_exised(self, connect, jac_collection):
384 385 386 387 388 389
        '''
        target: test get vector, params vector_id not existed
        method: add vector and get 
        expected: status ok, empty result
        '''
        tmp, vector = gen_binary_vectors(1, dim)
D
del-zhenwu 已提交
390
        status, ids = connect.insert(jac_collection, vector)
391
        assert status.OK()
X
Xiaohai Xu 已提交
392
        status = connect.flush([jac_collection])
393
        assert status.OK()
D
del-zhenwu 已提交
394
        status, res = connect.get_entity_by_id(jac_collection, [1]) 
395
        assert status.OK()
396
        assert not len(res[0])
397

X
Xiaohai Xu 已提交
398
    def test_get_vector_collection_not_existed(self, connect, jac_collection):
399
        '''
X
Xiaohai Xu 已提交
400
        target: test get vector, params collection_name not existed
401 402 403 404
        method: add vector and get
        expected: status not ok
        '''
        tmp, vector = gen_binary_vectors(1, dim)
D
del-zhenwu 已提交
405
        status, ids = connect.insert(jac_collection, vector)
406
        assert status.OK()
X
Xiaohai Xu 已提交
407
        status = connect.flush([jac_collection])
408
        assert status.OK()
X
Xiaohai Xu 已提交
409
        collection_new = gen_unique_str()
D
del-zhenwu 已提交
410
        status, res = connect.get_entity_by_id(collection_new, [1]) 
411 412
        assert not status.OK()

X
Xiaohai Xu 已提交
413
    def test_get_vector_partition(self, connect, jac_collection):
414
        '''
D
del-zhenwu 已提交
415
        target: test.get_entity_by_id
416 417 418 419
        method: add vector, and get
        expected: status ok, vector returned
        '''
        tmp, vectors = gen_binary_vectors(nb, dim)
X
Xiaohai Xu 已提交
420
        status = connect.create_partition(jac_collection, tag)
D
del-zhenwu 已提交
421
        status, ids = connect.insert(jac_collection, vectors, partition_tag=tag)
422
        assert status.OK()
X
Xiaohai Xu 已提交
423
        status = connect.flush([jac_collection])
424
        assert status.OK()
D
del-zhenwu 已提交
425
        status, res = connect.get_entity_by_id(jac_collection, [ids[0]])
426
        assert status.OK()
427
        assert_equal_vector(res[0], vectors[0])
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443


class TestGetVectorIdIngalid(object):
    single_vector = gen_single_vector(dim)

    """
    Test adding vectors with invalid vectors
    """
    @pytest.fixture(
        scope="function",
        params=gen_invalid_vector_ids()
    )
    def gen_invalid_id(self, request):
        yield request.param

    @pytest.mark.level(2)
X
Xiaohai Xu 已提交
444
    def test_get_vector_id_invalid(self, connect, collection, gen_invalid_id):
445 446
        invalid_id = gen_invalid_id
        with pytest.raises(Exception) as e:
D
del-zhenwu 已提交
447
            status = connect.get_entity_by_id(collection, [invalid_id])
448 449


S
sahuang 已提交
450
class TestCollectionNameInvalid(object):
451
    """
X
Xiaohai Xu 已提交
452
    Test adding vectors with invalid collection names
453 454 455
    """
    @pytest.fixture(
        scope="function",
X
Xiaohai Xu 已提交
456
        params=gen_invalid_collection_names()
457
    )
X
Xiaohai Xu 已提交
458
    def get_collection_name(self, request):
459 460 461
        yield request.param

    @pytest.mark.level(2)
X
Xiaohai Xu 已提交
462 463
    def test_get_vectors_with_invalid_collection_name(self, connect, get_collection_name):
        collection_name = get_collection_name
464
        vectors = gen_vectors(1, dim)
D
del-zhenwu 已提交
465
        status, result = connect.get_entity_by_id(collection_name, [1])
466
        assert not status.OK()