Passed
Push — master ( b86822...b6e78f )
by
unknown
02:07
created

test_delete.TestDeleteBase.test_search_delete_loop()   A

Complexity

Conditions 2

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nop 3
dl 0
loc 17
rs 9.8
c 0
b 0
f 0
1
import time
2
import random
3
import pdb
4
import copy
5
import threading
6
import logging
7
from multiprocessing import Pool, Process
8
import pytest
9
from utils import *
10
from constants import *
11
12
field_name = default_float_vec_field_name
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_float_vec_field_name does not seem to be defined.
Loading history...
13
default_single_query = {
14
    "bool": {
15
        "must": [
16
            {"vector": {field_name: {"topk": 10, "metric_type":"L2", "query": gen_vectors(1, default_dim), "params": {"nprobe": 10}}}}
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_vectors does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable default_dim does not seem to be defined.
Loading history...
17
        ]
18
    }
19
}
20
21
22
class TestDeleteBase:
23
    """
24
    ******************************************************************
25
      The following cases are used to test `delete_entity_by_id` function
26
    ******************************************************************
27
    """
28
29 View Code Duplication
    @pytest.fixture(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
30
        scope="function",
31
        params=gen_simple_index()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_simple_index does not seem to be defined.
Loading history...
32
    )
33
    def get_simple_index(self, request, connect):
34
        if str(connect._cmd("mode")) == "GPU":
35
            if not request.param["index_type"] not in ivf():
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ivf does not seem to be defined.
Loading history...
36
                pytest.skip("Only support index_type: idmap/ivf")
37
        if str(connect._cmd("mode")) == "CPU":
38
            if request.param["index_type"] in index_cpu_not_support():
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable index_cpu_not_support does not seem to be defined.
Loading history...
39
                pytest.skip("CPU not support index_type: ivf_sq8h")
40
        return request.param
41
42
    @pytest.fixture(
43
        scope="function",
44
        params=[
45
            1,
46
            2000
47
        ],
48
    )
49
    def insert_count(self, request):
50
        yield request.param
51
52
    def test_delete_entity_id_not_exised(self, connect, collection):
53
        '''
54
        target: test delete entity, params entity_id not existed
55
        method: add entity and delete
56
        expected: status DELETED
57
        '''
58
        ids = connect.bulk_insert(collection, default_entity)
59
        connect.flush([collection])
60
        status = connect.delete_entity_by_id(collection, [0])
61
        assert status
62
63
    def test_delete_empty_collection(self, connect, collection):
64
        '''
65
        target: test delete entity, params collection_name not existed
66
        method: add entity and delete
67
        expected: status DELETED
68
        '''
69
        status = connect.delete_entity_by_id(collection, [0])
70
        assert status
71
72
    def test_delete_entity_collection_not_existed(self, connect, collection):
73
        '''
74
        target: test delete entity, params collection_name not existed
75
        method: add entity and delete
76
        expected: error raised
77
        '''
78
        collection_new = gen_unique_str()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_unique_str does not seem to be defined.
Loading history...
79
        with pytest.raises(Exception) as e:
80
            status = connect.delete_entity_by_id(collection_new, [0])
81
82
    def test_delete_entity_collection_not_existed(self, connect, collection):
83
        '''
84
        target: test delete entity, params collection_name not existed
85
        method: add entity and delete
86
        expected: error raised
87
        '''
88
        ids = connect.bulk_insert(collection, default_entity)
89
        connect.flush([collection])
90
        collection_new = gen_unique_str()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_unique_str does not seem to be defined.
Loading history...
91
        with pytest.raises(Exception) as e:
92
            status = connect.delete_entity_by_id(collection_new, [0])
93
94
    def test_insert_delete(self, connect, collection, insert_count):
95
        '''
96
        target: test delete entity
97
        method: add entities and delete
98
        expected: no error raised
99
        '''
100
        entities = gen_entities(insert_count)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_entities does not seem to be defined.
Loading history...
101
        ids = connect.bulk_insert(collection, entities)
102
        connect.flush([collection])
103
        delete_ids = [ids[0]]
104
        status = connect.delete_entity_by_id(collection, delete_ids)
105
        assert status
106
        connect.flush([collection])
107
        res_count = connect.count_entities(collection)
108
        assert res_count == insert_count - 1
109
110 View Code Duplication
    def test_insert_delete_A(self, connect, collection):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
111
        '''
112
        target: test delete entity
113
        method: add entities and delete one in collection, and one not in collection
114
        expected: no error raised
115
        '''
116
        ids = connect.bulk_insert(collection, default_entities)
117
        connect.flush([collection])
118
        delete_ids = [ids[0], 1]
119
        status = connect.delete_entity_by_id(collection, delete_ids)
120
        assert status
121
        connect.flush([collection])
122
        res_count = connect.count_entities(collection)
123
        assert res_count == default_nb - 1
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
124
125
    def test_insert_delete_B(self, connect, id_collection):
126
        '''
127
        target: test delete entity
128
        method: add entities with the same ids, and delete the id in collection
129
        expected: no error raised, all entities deleted
130
        '''
131
        ids = [1 for i in range(default_nb)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
132
        res_ids = connect.bulk_insert(id_collection, default_entities, ids)
133
        connect.flush([id_collection])
134
        delete_ids = [1]
135
        status = connect.delete_entity_by_id(id_collection, delete_ids)
136
        assert status
137
        connect.flush([id_collection])
138
        res_count = connect.count_entities(id_collection)
139
        assert res_count == 0
140
141
    def test_delete_exceed_limit(self, connect, collection):
142
        '''
143
        target: test delete entity
144
        method: add one entity and delete two ids
145
        expected: error raised
146
        '''
147
        ids = connect.bulk_insert(collection, default_entity)
148
        connect.flush([collection])
149
        delete_ids = [ids[0], 1]
150
        status = connect.delete_entity_by_id(collection, delete_ids)
151
        connect.flush([collection])
152
        res_count = connect.count_entities(collection)
153
        assert res_count == 0
154
155 View Code Duplication
    def test_flush_after_delete(self, connect, collection):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
156
        '''
157
        target: test delete entity
158
        method: add entities and delete, then flush
159
        expected: entity deleted and no error raised
160
        '''
161
        ids = connect.bulk_insert(collection, default_entities)
162
        connect.flush([collection])
163
        delete_ids = [ids[0], ids[-1]]
164
        status = connect.delete_entity_by_id(collection, delete_ids)
165
        assert status
166
        connect.flush([collection])
167
        res_count = connect.count_entities(collection)
168
        assert res_count == default_nb - len(delete_ids)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
169
170
    def test_flush_after_delete_binary(self, connect, binary_collection):
171
        '''
172
        target: test delete entity
173
        method: add entities and delete, then flush
174
        expected: entity deleted and no error raised
175
        '''
176
        ids = connect.bulk_insert(binary_collection, default_binary_entities)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_binary_entities does not seem to be defined.
Loading history...
177
        connect.flush([binary_collection])
178
        delete_ids = [ids[0], ids[-1]]
179
        status = connect.delete_entity_by_id(binary_collection, delete_ids)
180
        assert status
181
        connect.flush([binary_collection])
182
        res_count = connect.count_entities(binary_collection)
183
        assert res_count == default_nb - len(delete_ids)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
184
185
    def test_insert_delete_binary(self, connect, binary_collection):
186
        '''
187
        method: add entities and delete
188
        expected: status DELETED
189
        '''
190
        ids = connect.bulk_insert(binary_collection, default_binary_entities)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_binary_entities does not seem to be defined.
Loading history...
191
        connect.flush([binary_collection])
192
        delete_ids = [ids[0], ids[-1]]
193
        status = connect.delete_entity_by_id(binary_collection, delete_ids)
194
195
    def test_insert_same_ids_after_delete(self, connect, id_collection):
196
        '''
197
        method: add entities and delete
198
        expected: status DELETED
199
        note: Not flush after delete
200
        '''
201
        insert_ids = [i for i in range(default_nb)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
202
        ids = connect.bulk_insert(id_collection, default_entities, insert_ids)
203
        connect.flush([id_collection])
204
        delete_ids = [ids[0], ids[-1]]
205
        status = connect.delete_entity_by_id(id_collection, delete_ids)
206
        assert status
207
        new_ids = connect.bulk_insert(id_collection, default_entity, [ids[0]])
208
        assert new_ids == [ids[0]]
209
        connect.flush([id_collection])
210
        res_count = connect.count_entities(id_collection)
211
        assert res_count == default_nb - 1
212
213
    def test_insert_same_ids_after_delete_binary(self, connect, binary_id_collection):
214
        '''
215
        method: add entities, with the same id and delete the ids
216
        expected: status DELETED, all id deleted
217
        '''
218
        insert_ids = [i for i in range(default_nb)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
219
        ids = connect.bulk_insert(binary_id_collection, default_binary_entities, insert_ids)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_binary_entities does not seem to be defined.
Loading history...
220
        connect.flush([binary_id_collection])
221
        delete_ids = [ids[0], ids[-1]]
222
        status = connect.delete_entity_by_id(binary_id_collection, delete_ids)
223
        assert status
224
        new_ids = connect.bulk_insert(binary_id_collection, default_binary_entity, [ids[0]])
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_binary_entity does not seem to be defined.
Loading history...
225
        assert new_ids == [ids[0]]
226
        connect.flush([binary_id_collection])
227
        res_count = connect.count_entities(binary_id_collection)
228
        assert res_count == default_nb - 1
229
230
    def test_search_after_delete(self, connect, collection):
231
        '''
232
        target: test delete entity
233
        method: add entities and delete, then search
234
        expected: entity deleted and no error raised
235
        '''
236
        ids = connect.bulk_insert(collection, default_entities)
237
        connect.flush([collection])
238
        delete_ids = [ids[0], ids[-1]]
239
        status = connect.delete_entity_by_id(collection, delete_ids)
240
        assert status
241
        query = copy.deepcopy(default_single_query)
242
        query["bool"]["must"][0]["vector"][field_name]["query"] =\
243
            [default_entity[-1]["values"][0], default_entities[-1]["values"][0], default_entities[-1]["values"][-1]]
244
        res = connect.search(collection, query)
245
        logging.getLogger().debug(res)
246
        assert len(res) == len(query["bool"]["must"][0]["vector"][field_name]["query"])
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable field_name does not seem to be defined.
Loading history...
247
        assert res[0]._distances[0] > epsilon
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable epsilon does not seem to be defined.
Loading history...
248
        assert res[1]._distances[0] < epsilon
249
        assert res[2]._distances[0] < epsilon
250
251
    def test_create_index_after_delete(self, connect, collection, get_simple_index):
252
        '''
253
        method: add entitys and delete, then create index
254
        expected: vectors deleted, index created
255
        '''
256
        ids = connect.bulk_insert(collection, default_entities)
257
        connect.flush([collection])
258
        delete_ids = [ids[0], ids[-1]]
259
        status = connect.delete_entity_by_id(collection, delete_ids)
260
        connect.create_index(collection, field_name, get_simple_index)
261
        # assert index info
262
263
    def test_delete_multiable_times(self, connect, collection):
264
        '''
265
        method: add entities and delete id serveral times
266
        expected: entities deleted
267
        '''
268
        ids = connect.bulk_insert(collection, default_entities)
269
        connect.flush([collection])
270
        delete_ids = [ids[0], ids[-1]]
271
        status = connect.delete_entity_by_id(collection, delete_ids)
272
        assert status
273
        connect.flush([collection])
274
        for i in range(10):
275
            status = connect.delete_entity_by_id(collection, delete_ids)
276
            assert status
277
278
    def test_index_insert_batch_delete_get(self, connect, collection, get_simple_index):
279
        '''
280
        method: create index, insert entities, and delete
281
        expected: entities deleted
282
        '''
283
        connect.create_index(collection, field_name, get_simple_index)
284
        ids = connect.bulk_insert(collection, default_entities)
285
        connect.flush([collection])
286
        delete_ids = [ids[0], ids[-1]]
287
        status = connect.delete_entity_by_id(collection, delete_ids)
288
        assert status
289
        connect.flush([collection])
290
        res_count = connect.count_entities(collection)
291
        assert res_count == default_nb - len(delete_ids)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
292
        res_get = connect.get_entity_by_id(collection, delete_ids)
293
        assert res_get[0] is None
294
295
    @pytest.mark.level(2)
296
    def test_index_insert_single_delete_get(self, connect, id_collection, get_simple_index):
297
        '''
298
        method: create index, insert entities, and delete
299
        expected: entities deleted
300
        '''
301
        ids = [i for i in range(default_nb)]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
302
        connect.create_index(id_collection, field_name, get_simple_index)
303
        for i in range(default_nb):
304
            connect.bulk_insert(id_collection, default_entity, [ids[i]])
305
        connect.flush([id_collection])
306
        delete_ids = [ids[0], ids[-1]]
307
        status = connect.delete_entity_by_id(id_collection, delete_ids)
308
        assert status
309
        connect.flush([id_collection])
310
        res_count = connect.count_entities(id_collection)
311
        assert res_count == default_nb - len(delete_ids)
312
313
    """
314
    ******************************************************************
315
      The following cases are used to test `delete_entity_by_id` function, with tags
316
    ******************************************************************
317
    """
318
319
    def test_insert_tag_delete(self, connect, collection):
320
        '''
321
        method: add entitys with given tag, delete entities with the return ids
322
        expected: entities deleted
323
        '''
324
        connect.create_partition(collection, default_tag)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_tag does not seem to be defined.
Loading history...
325
        ids = connect.bulk_insert(collection, default_entities, partition_tag=default_tag)
326
        connect.flush([collection])
327
        delete_ids = [ids[0], ids[-1]]
328
        status = connect.delete_entity_by_id(collection, delete_ids)
329
        assert status
330
        connect.flush([collection])
331
        res_count = connect.count_entities(collection)
332
        assert res_count == default_nb - 2
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
333
334
    def test_insert_default_tag_delete(self, connect, collection):
335
        '''
336
        method: add entitys, delete entities with the return ids
337
        expected: entities deleted
338
        '''
339
        connect.create_partition(collection, default_tag)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_tag does not seem to be defined.
Loading history...
340
        ids = connect.bulk_insert(collection, default_entities)
341
        connect.flush([collection])
342
        delete_ids = [ids[0], ids[-1]]
343
        status = connect.delete_entity_by_id(collection, delete_ids)
344
        assert status
345
        connect.flush([collection])
346
        res_count = connect.count_entities(collection)
347
        assert res_count == default_nb - 2
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
348
349 View Code Duplication
    def test_insert_tags_delete(self, connect, collection):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
350
        '''
351
        method: add entitys with given two tags, delete entities with the return ids
352
        expected: entities deleted
353
        '''
354
        tag_new = "tag_new"
355
        connect.create_partition(collection, default_tag)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_tag does not seem to be defined.
Loading history...
356
        connect.create_partition(collection, tag_new)
357
        ids = connect.bulk_insert(collection, default_entities, partition_tag=default_tag)
358
        ids_new = connect.bulk_insert(collection, default_entities, partition_tag=tag_new)
359
        connect.flush([collection])
360
        delete_ids = [ids[0], ids_new[0]]
361
        status = connect.delete_entity_by_id(collection, delete_ids)
362
        assert status
363
        connect.flush([collection])
364
        res_count = connect.count_entities(collection)
365
        assert res_count == 2 * (default_nb - 1)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
366
367 View Code Duplication
    def test_insert_tags_index_delete(self, connect, collection, get_simple_index):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
368
        """
369
        method: add entitys with given tag, create index, delete entities with the return ids
370
        expected: entities deleted
371
        """
372
        tag_new = "tag_new"
373
        connect.create_partition(collection, default_tag)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_tag does not seem to be defined.
Loading history...
374
        connect.create_partition(collection, tag_new)
375
        ids = connect.bulk_insert(collection, default_entities, partition_tag=default_tag)
376
        ids_new = connect.bulk_insert(collection, default_entities, partition_tag=tag_new)
377
        connect.flush([collection])
378
        connect.create_index(collection, field_name, get_simple_index)
379
        delete_ids = [ids[0], ids_new[0]]
380
        status = connect.delete_entity_by_id(collection, delete_ids)
381
        assert status
382
        connect.flush([collection])
383
        res_count = connect.count_entities(collection)
384
        assert res_count == 2 * (default_nb - 1)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
385
386
    def test_insert_delete_loop(self, connect, collection):
387
        """
388
        target: test loop insert and delete entities
389
        method: loop insert entities into two segments, and delete entities cross segments.
390
        expected: count is correct
391
        """
392
        loop = 2
393
        for i in range(loop):
394
            ids = connect.bulk_insert(collection, default_entities)
395
            connect.flush([collection])
396
            status = connect.delete_entity_by_id(collection, ids[100:default_nb - 100])
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
397
            connect.flush([collection])
398
        res_count = connect.count_entities(collection)
399
        assert res_count == loop * 200
400
401
    def test_search_delete_loop(self, connect, collection):
402
        """
403
        target: test loop search and delete entities
404
        method: loop search and delete cross segments
405
        expected: ok
406
        """
407
        loop = 2
408
        ids = connect.bulk_insert(collection, default_entities)
409
        connect.flush([collection])
410
        ni = default_nb // loop
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
411
        for i in range(loop):
412
            res = connect.search(collection, default_single_query)
413
            status = connect.delete_entity_by_id(collection, ids[i * ni:(i + 1) * ni])
414
            assert status
415
            connect.flush([collection])
416
        res_count = connect.count_entities(collection)
417
        assert res_count == 0
418
419
    def test_count_delete_loop(self, connect, collection):
420
        """
421
        target: test loop search and delete entities
422
        method: loop search and delete cross segments
423
        expected: ok
424
        """
425
        loop = 2
426
        ids = connect.bulk_insert(collection, default_entities)
427
        connect.flush([collection])
428
        ni = default_nb // loop
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable default_nb does not seem to be defined.
Loading history...
429
        for i in range(loop):
430
            connect.count_entities(collection)
431
            status = connect.delete_entity_by_id(collection, ids[i * ni:(i + 1) * ni])
432
            assert status
433
            connect.flush([collection])
434
        res_count = connect.count_entities(collection)
435
        assert res_count == 0
436
437
438
class TestDeleteInvalid(object):
439
    """
440
    Test adding vectors with invalid vectors
441
    """
442
443
    @pytest.fixture(
444
        scope="function",
445
        params=gen_invalid_ints()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_invalid_ints does not seem to be defined.
Loading history...
446
    )
447
    def gen_entity_id(self, request):
448
        yield request.param
449
450
    @pytest.fixture(
451
        scope="function",
452
        params=gen_invalid_strs()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gen_invalid_strs does not seem to be defined.
Loading history...
453
    )
454
    def get_collection_name(self, request):
455
        yield request.param
456
457
    @pytest.mark.level(1)
458
    def test_delete_entity_id_invalid(self, connect, collection, gen_entity_id):
459
        invalid_id = gen_entity_id
460
        with pytest.raises(Exception) as e:
461
            status = connect.delete_entity_by_id(collection, [invalid_id])
462
463
    def test_delete_entity_ids_invalid(self, connect, collection, gen_entity_id):
464
        invalid_id = gen_entity_id
465
        with pytest.raises(Exception) as e:
466
            status = connect.delete_entity_by_id(collection, [1, invalid_id])
467
468
    @pytest.mark.level(2)
469
    def test_delete_entity_with_invalid_collection_name(self, connect, get_collection_name):
470
        collection_name = get_collection_name
471
        with pytest.raises(Exception) as e:
472
            status = connect.delete_entity_by_id(collection_name, [1])
473