Passed
Push — master ( fd4969...54df52 )
by
unknown
01:50
created

test_index.TestIndexIP.get_simple_index()   B

Complexity

Conditions 6

Size

Total Lines 14
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 13
nop 3
dl 0
loc 14
rs 8.6666
c 0
b 0
f 0
1
import logging
2
import time
3
import pdb
4
import threading
5
from multiprocessing import Pool, Process
6
import numpy
7
import pytest
8
import sklearn.preprocessing
9
from utils import *
10
11
nb = 6000
12
dim = 128
13
index_file_size = 10
14
BUILD_TIMEOUT = 300
15
nprobe = 1
16
top_k = 5
17
tag = "1970-01-01"
18
NLIST = 4046
19
INVALID_NLIST = 100000000
20
field_name = "float_vector"
21
binary_field_name = "binary_vector"
22
default_index_name = "partition"
23
collection_id = "index"
24
default_index_type = "FLAT"
25
entity = gen_entities(1)
26
entities = gen_entities(nb)
27
raw_vector, binary_entity = gen_binary_entities(1)
28
raw_vectors, binary_entities = gen_binary_entities(nb)
29
query, query_vecs = gen_query_vectors_inside_entities(field_name, entities, top_k, 1)
30
default_index = {"index_type": "IVF_FLAT", "nlist": 1024}
31
32
33
class TestIndexBase:
34 View Code Duplication
    @pytest.fixture(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
35
        scope="function",
36
        params=gen_simple_index()
37
    )
38
    def get_simple_index(self, request, connect):
39
        logging.getLogger().info(request.param)
40
        if str(connect._cmd("mode")) == "CPU":
41
            if request.param["index_type"] in index_cpu_not_support():
42
                pytest.skip("sq8h not support in CPU mode")
43
        return request.param
44
45
    @pytest.fixture(
46
        scope="function",
47
        params=[
48
            1,
49
            10,
50
            1500
51
        ],
52
    )
53
    def get_nq(self, request):
54
        yield request.param
55
56
    """
57
    ******************************************************************
58
      The following cases are used to test `create_index` function
59
    ******************************************************************
60
    """
61
62
    @pytest.mark.timeout(BUILD_TIMEOUT)
63
    def test_create_index(self, connect, collection, get_simple_index):
64
        '''
65
        target: test create index interface
66
        method: create collection and add entities in it, create index
67
        expected: return search success
68
        '''
69
        ids = connect.insert(collection, entities)
70
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
71
72
    @pytest.mark.timeout(BUILD_TIMEOUT)
73
    def test_create_index_no_vectors(self, connect, collection, get_simple_index):
74
        '''
75
        target: test create index interface
76
        method: create collection and add entities in it, create index
77
        expected: return search success
78
        '''
79
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
80
81
    @pytest.mark.timeout(BUILD_TIMEOUT)
82
    def test_create_index_partition(self, connect, collection, get_simple_index):
83
        '''
84
        target: test create index interface
85
        method: create collection, create partition, and add entities in it, create index
86
        expected: return search success
87
        '''
88
        connect.create_partition(collection, tag)
89
        ids = connect.insert(collection, entities, partition_tag=tag)
90
        connect.flush([collection])
91
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
92
93
    @pytest.mark.timeout(BUILD_TIMEOUT)
94
    def test_create_index_partition_flush(self, connect, collection, get_simple_index):
95
        '''
96
        target: test create index interface
97
        method: create collection, create partition, and add entities in it, create index
98
        expected: return search success
99
        '''
100
        connect.create_partition(collection, tag)
101
        ids = connect.insert(collection, entities, partition_tag=tag)
102
        connect.flush()
103
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
104
105
    @pytest.mark.level(2)
106
    def test_create_index_without_connect(self, dis_connect, collection):
107
        '''
108
        target: test create index without connection
109
        method: create collection and add entities in it, check if added successfully
110
        expected: raise exception
111
        '''
112
        with pytest.raises(Exception) as e:
113
            dis_connect.create_index(collection, field_name, default_index_name, get_simple_index)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable get_simple_index does not seem to be defined.
Loading history...
114
115 View Code Duplication
    @pytest.mark.timeout(BUILD_TIMEOUT)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
116
    def test_create_index_search_with_query_vectors(self, connect, collection, get_simple_index, get_nq):
117
        '''
118
        target: test create index interface, search with more query vectors
119
        method: create collection and add entities in it, create index
120
        expected: return search success
121
        '''
122
        ids = connect.insert(collection, entities)
123
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
124
        logging.getLogger().info(connect.get_collection_stats(collection))
125
        nq = get_nq
126
        index_type = get_simple_index["index_type"]
127
        search_param = get_search_param(index_type)
128
        query, vecs = gen_query_vectors_inside_entities(field_name, entities, top_k, nq, search_params=search_param)
129
        res = connect.search(collection, query)
130
        assert len(res) == nq
131
132 View Code Duplication
    @pytest.mark.timeout(BUILD_TIMEOUT)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
133
    @pytest.mark.level(2)
134
    def test_create_index_multithread(self, connect, collection, args):
135
        '''
136
        target: test create index interface with multiprocess
137
        method: create collection and add entities in it, create index
138
        expected: return search success
139
        '''
140
        ids = connect.insert(collection, entities)
141
142
        def build(connect):
143
            connect.create_index(collection, field_name, default_index_name, default_index)
144
145
        threads_num = 8
146
        threads = []
147
        for i in range(threads_num):
148
            m = get_milvus(host=args["ip"], port=args["port"], handler=args["handler"])
149
            t = threading.Thread(target=build, args=(m,))
150
            threads.append(t)
151
            t.start()
152
            time.sleep(0.2)
153
        for t in threads:
154
            t.join()
155
156
    def test_create_index_collection_not_existed(self, connect):
157
        '''
158
        target: test create index interface when collection name not existed
159
        method: create collection and add entities in it, create index
160
            , make sure the collection name not in index
161
        expected: return code not equals to 0, create index failed
162
        '''
163
        collection_name = gen_unique_str(collection_id)
164
        with pytest.raises(Exception) as e:
165
            connect.create_index(collection, field_name, default_index_name, default_index)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable collection does not seem to be defined.
Loading history...
166
167
    @pytest.mark.timeout(BUILD_TIMEOUT)
168
    def test_create_index_no_vectors_insert(self, connect, collection, get_simple_index):
169
        '''
170
        target: test create index interface when there is no vectors in collection, and does not affect the subsequent process
171
        method: create collection and add no vectors in it, and then create index, add entities in it
172
        expected: return code equals to 0
173
        '''
174
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
175
        ids = connect.insert(collection, entities)
176
        connect.flush([collection])
177
        count = connect.count_entities(collection)
178
        assert count == nb
179
180
    @pytest.mark.level(2)
181
    @pytest.mark.timeout(BUILD_TIMEOUT)
182
    def test_create_same_index_repeatedly(self, connect, collection, get_simple_index):
183
        '''
184
        target: check if index can be created repeatedly, with the same create_index params
185
        method: create index after index have been built
186
        expected: return code success, and search ok
187
        '''
188
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
189
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
190
191 View Code Duplication
    @pytest.mark.level(2)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
192
    @pytest.mark.timeout(BUILD_TIMEOUT)
193
    def test_create_different_index_repeatedly(self, connect, collection):
194
        '''
195
        target: check if index can be created repeatedly, with the different create_index params
196
        method: create another index with different index_params after index have been built
197
        expected: return code 0, and describe index result equals with the second index params
198
        '''
199
        ids = connect.insert(collection, entities)
200
        indexs = [default_index, {"index_type": "FLAT", "nlist": 1024}]
201
        for index in indexs:
202
            connect.create_index(collection, field_name, default_index_name, index)
203
            stats = connect.get_collection_stats(collection)
204
            assert stats["partitions"][0]["segments"][0]["index_name"] == index["index_type"]
205
            assert stats["row_count"] == nb
206
207
    @pytest.mark.timeout(BUILD_TIMEOUT)
208
    def test_create_index_ip(self, connect, ip_collection, get_simple_index):
209
        '''
210
        target: test create index interface
211
        method: create collection and add entities in it, create index
212
        expected: return search success
213
        '''
214
        ids = connect.insert(ip_collection, entities)
215
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
216
217
    @pytest.mark.timeout(BUILD_TIMEOUT)
218
    def test_create_index_no_vectors_ip(self, connect, ip_collection, get_simple_index):
219
        '''
220
        target: test create index interface
221
        method: create collection and add entities in it, create index
222
        expected: return search success
223
        '''
224
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
225
226
    @pytest.mark.timeout(BUILD_TIMEOUT)
227
    def test_create_index_partition_ip(self, connect, ip_collection, get_simple_index):
228
        '''
229
        target: test create index interface
230
        method: create collection, create partition, and add entities in it, create index
231
        expected: return search success
232
        '''
233
        connect.create_partition(ip_collection, tag)
234
        ids = connect.insert(ip_collection, entities, partition_tag=tag)
235
        connect.flush([ip_collection])
236
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
237
238
    @pytest.mark.timeout(BUILD_TIMEOUT)
239
    def test_create_index_partition_flush_ip(self, connect, ip_collection, get_simple_index):
240
        '''
241
        target: test create index interface
242
        method: create collection, create partition, and add entities in it, create index
243
        expected: return search success
244
        '''
245
        connect.create_partition(ip_collection, tag)
246
        ids = connect.insert(ip_collection, entities, partition_tag=tag)
247
        connect.flush()
248
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
249
250
    @pytest.mark.level(2)
251
    def test_create_index_without_connect_ip(self, dis_connect, ip_collection):
252
        '''
253
        target: test create index without connection
254
        method: create collection and add entities in it, check if added successfully
255
        expected: raise exception
256
        '''
257
        with pytest.raises(Exception) as e:
258
            dis_connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable get_simple_index does not seem to be defined.
Loading history...
259
260 View Code Duplication
    @pytest.mark.timeout(BUILD_TIMEOUT)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
261
    def test_create_index_search_with_query_vectors_ip(self, connect, ip_collection, get_simple_index, get_nq):
262
        '''
263
        target: test create index interface, search with more query vectors
264
        method: create collection and add entities in it, create index
265
        expected: return search success
266
        '''
267
        ids = connect.insert(ip_collection, entities)
268
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
269
        logging.getLogger().info(connect.get_collection_stats(ip_collection))
270
        nq = get_nq
271
        index_type = get_simple_index["index_type"]
272
        search_param = get_search_param(index_type)
273
        query, vecs = gen_query_vectors_inside_entities(field_name, entities, top_k, nq, search_params=search_param)
274
        res = connect.search(ip_collection, query)
275
        assert len(res) == nq
276
277 View Code Duplication
    @pytest.mark.timeout(BUILD_TIMEOUT)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
278
    @pytest.mark.level(2)
279
    def test_create_index_multithread_ip(self, connect, ip_collection, args):
280
        '''
281
        target: test create index interface with multiprocess
282
        method: create collection and add entities in it, create index
283
        expected: return search success
284
        '''
285
        ids = connect.insert(ip_collection, entities)
286
287
        def build(connect):
288
            connect.create_index(ip_collection, field_name, default_index_name, default_index)
289
290
        threads_num = 8
291
        threads = []
292
        for i in range(threads_num):
293
            m = get_milvus(host=args["ip"], port=args["port"], handler=args["handler"])
294
            t = threading.Thread(target=build, args=(m,))
295
            threads.append(t)
296
            t.start()
297
            time.sleep(0.2)
298
        for t in threads:
299
            t.join()
300
301
    def test_create_index_collection_not_existed_ip(self, connect):
302
        '''
303
        target: test create index interface when collection name not existed
304
        method: create collection and add entities in it, create index
305
            , make sure the collection name not in index
306
        expected: return code not equals to 0, create index failed
307
        '''
308
        collection_name = gen_unique_str(collection_id)
309
        with pytest.raises(Exception) as e:
310
            connect.create_index(ip_collection, field_name, default_index_name, default_index)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ip_collection does not seem to be defined.
Loading history...
311
312
    @pytest.mark.timeout(BUILD_TIMEOUT)
313
    def test_create_index_no_vectors_insert_ip(self, connect, ip_collection, get_simple_index):
314
        '''
315
        target: test create index interface when there is no vectors in collection, and does not affect the subsequent process
316
        method: create collection and add no vectors in it, and then create index, add entities in it
317
        expected: return code equals to 0
318
        '''
319
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
320
        ids = connect.insert(ip_collection, entities)
321
        connect.flush([ip_collection])
322
        count = connect.count_entities(ip_collection)
323
        assert count == nb
324
325
    @pytest.mark.level(2)
326
    @pytest.mark.timeout(BUILD_TIMEOUT)
327
    def test_create_same_index_repeatedly_ip(self, connect, ip_collection, get_simple_index):
328
        '''
329
        target: check if index can be created repeatedly, with the same create_index params
330
        method: create index after index have been built
331
        expected: return code success, and search ok
332
        '''
333
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
334
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
335
336 View Code Duplication
    @pytest.mark.level(2)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
337
    @pytest.mark.timeout(BUILD_TIMEOUT)
338
    def test_create_different_index_repeatedly_ip(self, connect, ip_collection):
339
        '''
340
        target: check if index can be created repeatedly, with the different create_index params
341
        method: create another index with different index_params after index have been built
342
        expected: return code 0, and describe index result equals with the second index params
343
        '''
344
        ids = connect.insert(ip_collection, entities)
345
        indexs = [default_index, {"index_type": "FLAT", "nlist": 1024}]
346
        for index in indexs:
347
            connect.create_index(ip_collection, field_name, default_index_name, index)
348
            stats = connect.get_collection_stats(ip_collection)
349
            assert stats["partitions"][0]["segments"][0]["index_name"] == index["index_type"]
350
            assert stats["row_count"] == nb
351
352
    """
353
    ******************************************************************
354
      The following cases are used to test `drop_index` function
355
    ******************************************************************
356
    """
357
358
    def test_drop_index(self, connect, collection, get_simple_index):
359
        '''
360
        target: test drop index interface
361
        method: create collection and add entities in it, create index, call drop index
362
        expected: return code 0, and default index param
363
        '''
364
        # ids = connect.insert(collection, entities)
365
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
366
        connect.drop_index(collection, field_name, default_index_name)
367
        stats = connect.get_collection_stats(collection)
368
        # assert stats["partitions"][0]["segments"][0]["index_name"] == default_index_type
369
        assert not stats["partitions"][0]["segments"]
370
371
    @pytest.mark.level(2)
372
    def test_drop_index_repeatly(self, connect, collection, get_simple_index):
373
        '''
374
        target: test drop index repeatly
375
        method: create index, call drop index, and drop again
376
        expected: return code 0
377
        '''
378
        connect.create_index(collection, field_name, default_index_name, get_simple_index)
379
        stats = connect.get_collection_stats(collection)
380
        connect.drop_index(collection, field_name, default_index_name)
381
        connect.drop_index(collection, field_name, default_index_name)
382
        stats = connect.get_collection_stats(collection)
383
        logging.getLogger().info(stats)
384
        # assert stats["partitions"][0]["segments"][0]["index_name"] == default_index_type
385
        assert not stats["partitions"][0]["segments"]
386
387
    @pytest.mark.level(2)
388
    def test_drop_index_without_connect(self, dis_connect, collection):
389
        '''
390
        target: test drop index without connection
391
        method: drop index, and check if drop successfully
392
        expected: raise exception
393
        '''
394
        with pytest.raises(Exception) as e:
395
            dis_connect.drop_index(collection, field_name, default_index_name)
396
397
    def test_drop_index_collection_not_existed(self, connect):
398
        '''
399
        target: test drop index interface when collection name not existed
400
        method: create collection and add entities in it, create index
401
            , make sure the collection name not in index, and then drop it
402
        expected: return code not equals to 0, drop index failed
403
        '''
404
        collection_name = gen_unique_str(collection_id)
405
        with pytest.raises(Exception) as e:
406
            connect.drop_index(collection_name, field_name, default_index_name)
407
408
    def test_drop_index_collection_not_create(self, connect, collection):
409
        '''
410
        target: test drop index interface when index not created
411
        method: create collection and add entities in it, create index
412
        expected: return code not equals to 0, drop index failed
413
        '''
414
        # ids = connect.insert(collection, entities)
415
        # no create index
416
        connect.drop_index(collection, field_name, default_index_name)
417
418
    @pytest.mark.level(2)
419
    def test_create_drop_index_repeatly(self, connect, collection, get_simple_index):
420
        '''
421
        target: test create / drop index repeatly, use the same index params
422
        method: create index, drop index, four times
423
        expected: return code 0
424
        '''
425
        for i in range(4):
426
            connect.create_index(collection, field_name, default_index_name, get_simple_index)
427
            connect.drop_index(collection, field_name, default_index_name)
428
429
    def test_drop_index_ip(self, connect, ip_collection, get_simple_index):
430
        '''
431
        target: test drop index interface
432
        method: create collection and add entities in it, create index, call drop index
433
        expected: return code 0, and default index param
434
        '''
435
        # ids = connect.insert(collection, entities)
436
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
437
        connect.drop_index(ip_collection, field_name, default_index_name)
438
        stats = connect.get_collection_stats(ip_collection)
439
        # assert stats["partitions"][0]["segments"][0]["index_name"] == default_index_type
440
        assert not stats["partitions"][0]["segments"]
441
442
    @pytest.mark.level(2)
443
    def test_drop_index_repeatly_ip(self, connect, ip_collection, get_simple_index):
444
        '''
445
        target: test drop index repeatly
446
        method: create index, call drop index, and drop again
447
        expected: return code 0
448
        '''
449
        connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
450
        stats = connect.get_collection_stats(ip_collection)
451
        connect.drop_index(ip_collection, field_name, default_index_name)
452
        connect.drop_index(ip_collection, field_name, default_index_name)
453
        stats = connect.get_collection_stats(ip_collection)
454
        logging.getLogger().info(stats)
455
        # assert stats["partitions"][0]["segments"][0]["index_name"] == default_index_type
456
        assert not stats["partitions"][0]["segments"]
457
458
    @pytest.mark.level(2)
459
    def test_drop_index_without_connect_ip(self, dis_connect, ip_collection):
460
        '''
461
        target: test drop index without connection
462
        method: drop index, and check if drop successfully
463
        expected: raise exception
464
        '''
465
        with pytest.raises(Exception) as e:
466
            dis_connect.drop_index(ip_collection, field_name, default_index_name)
467
468
    def test_drop_index_collection_not_create_ip(self, connect, ip_collection):
469
        '''
470
        target: test drop index interface when index not created
471
        method: create collection and add entities in it, create index
472
        expected: return code not equals to 0, drop index failed
473
        '''
474
        # ids = connect.insert(collection, entities)
475
        # no create index
476
        connect.drop_index(ip_collection, field_name, default_index_name)
477
478
    @pytest.mark.level(2)
479
    def test_create_drop_index_repeatly_ip(self, connect, ip_collection, get_simple_index):
480
        '''
481
        target: test create / drop index repeatly, use the same index params
482
        method: create index, drop index, four times
483
        expected: return code 0
484
        '''
485
        for i in range(4):
486
            connect.create_index(ip_collection, field_name, default_index_name, get_simple_index)
487
            connect.drop_index(ip_collection, field_name, default_index_name)
488
489
490
class TestIndexJAC:
491
    @pytest.fixture(
492
        scope="function",
493
        params=gen_simple_index()
494
    )
495
    def get_simple_index(self, request, connect):
496
        if str(connect._cmd("mode")) == "CPU":
497
            if request.param["index_type"] in index_cpu_not_support():
498
                pytest.skip("sq8h not support in CPU mode")
499
        return request.param
500
501
    @pytest.fixture(
502
        scope="function",
503
        params=gen_binary_index()
504
    )
505
    def get_jaccard_index(self, request, connect):
506
        return request.param
507
508
    @pytest.fixture(
509
        scope="function",
510
        params=[
511
            1,
512
            10,
513
            1500
514
        ],
515
    )
516
    def get_nq(self, request):
517
        yield request.param
518
519
    """
520
    ******************************************************************
521
      The following cases are used to test `create_index` function
522
    ******************************************************************
523
    """
524
525
    @pytest.mark.timeout(BUILD_TIMEOUT)
526
    def test_create_index(self, connect, jac_collection, get_jaccard_index):
527
        '''
528
        target: test create index interface
529
        method: create collection and add entities in it, create index
530
        expected: return search success
531
        '''
532
        ids = connect.insert(jac_collection, binary_entities)
533
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
534
535
    @pytest.mark.timeout(BUILD_TIMEOUT)
536
    def test_create_index_partition(self, connect, jac_collection, get_jaccard_index):
537
        '''
538
        target: test create index interface
539
        method: create collection, create partition, and add entities in it, create index
540
        expected: return search success
541
        '''
542
        connect.create_partition(jac_collection, tag)
543
        ids = connect.insert(jac_collection, binary_entities, partition_tag=tag)
544
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
545
546
    # TODO:
547
    @pytest.mark.timeout(BUILD_TIMEOUT)
548
    def _test_create_index_search_with_query_vectors(self, connect, jac_collection, get_jaccard_index, get_nq):
549
        '''
550
        target: test create index interface, search with more query vectors
551
        method: create collection and add entities in it, create index
552
        expected: return search success
553
        '''
554
        nq = get_nq
555
        pdb.set_trace()
556
        ids = connect.insert(jac_collection, binary_entities)
557
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
558
        query, vecs = gen_query_vectors_inside_entities(binary_field_name, binary_entities, top_k, nq)
559
        search_param = get_search_param(get_jaccard_index["index_type"])
560
        res = connect.search(jac_collection, query, search_params=search_param)
561
        logging.getLogger().info(res)
562
        assert len(res) == nq
563
564
    """
565
    ******************************************************************
566
      The following cases are used to test `get_index_info` function
567
    ******************************************************************
568
    """
569
570 View Code Duplication
    def test_get_index_info(self, connect, jac_collection, get_jaccard_index):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
571
        '''
572
        target: test describe index interface
573
        method: create collection and add entities in it, create index, call describe index
574
        expected: return code 0, and index instructure
575
        '''
576
        if get_jaccard_index["index_type"] == "BIN_FLAT":
577
            pytest.skip("GetCollectionStats skip BIN_FLAT")
578
        ids = connect.insert(jac_collection, binary_entities)
579
        connect.flush([jac_collection])
580
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
581
        stats = connect.get_collection_stats(jac_collection)
582
        logging.getLogger().info(stats)
583
        assert stats['partitions'][0]['segments'][0]['index_name'] == get_jaccard_index['index_type']
584
585 View Code Duplication
    def test_get_index_info_partition(self, connect, jac_collection, get_jaccard_index):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
586
        '''
587
        target: test describe index interface
588
        method: create collection, create partition and add entities in it, create index, call describe index
589
        expected: return code 0, and index instructure
590
        '''
591
        if get_jaccard_index["index_type"] == "BIN_FLAT":
592
            pytest.skip("GetCollectionStats skip BIN_FLAT")
593
        connect.create_partition(jac_collection, tag)
594
        ids = connect.insert(jac_collection, binary_entities, partition_tag=tag)
595
        connect.flush([jac_collection])
596
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
597
        stats = connect.get_collection_stats(jac_collection)
598
        logging.getLogger().info(stats)
599
        assert stats['partitions'][1]['segments'][0]['index_name'] == get_jaccard_index['index_type']
600
601
    """
602
    ******************************************************************
603
      The following cases are used to test `drop_index` function
604
    ******************************************************************
605
    """
606
607
    def test_drop_index(self, connect, jac_collection, get_jaccard_index):
608
        '''
609
        target: test drop index interface
610
        method: create collection and add entities in it, create index, call drop index
611
        expected: return code 0, and default index param
612
        '''
613
        # ids = connect.insert(ip_collection, vectors)
614
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
615
        stats = connect.get_collection_stats(jac_collection)
616
        logging.getLogger().info(stats)
617
        connect.drop_index(jac_collection, binary_field_name, default_index_name)
618
        stats = connect.get_collection_stats(jac_collection)
619
        # assert stats["partitions"][0]["segments"][0]["index_name"] == default_index_type
620
        assert not stats["partitions"][0]["segments"]
621
622
    def test_drop_index_partition(self, connect, jac_collection, get_jaccard_index):
623
        '''
624
        target: test drop index interface
625
        method: create collection, create partition and add entities in it, create index on collection, call drop collection index
626
        expected: return code 0, and default index param
627
        '''
628
        connect.create_partition(jac_collection, tag)
629
        ids = connect.insert(jac_collection, binary_entities, partition_tag=tag)
630
        connect.flush([jac_collection])
631
        connect.create_index(jac_collection, binary_field_name, default_index_name, get_jaccard_index)
632
        stats = connect.get_collection_stats(jac_collection)
633
        logging.getLogger().info(stats)
634
        connect.drop_index(jac_collection, binary_field_name, default_index_name)
635
        stats = connect.get_collection_stats(jac_collection)
636
        logging.getLogger().info(stats)
637
        assert stats["partitions"][1]["segments"][0]["index_name"] == default_index_type
638
639
640
class TestIndexBinary:
641
    pass
642
643
644
class TestIndexMultiCollections(object):
645
646
    @pytest.mark.level(2)
647
    @pytest.mark.timeout(BUILD_TIMEOUT)
648
    def _test_create_index_multithread_multicollection(self, connect, args):
649
        '''
650
        target: test create index interface with multiprocess
651
        method: create collection and add entities in it, create index
652
        expected: return search success
653
        '''
654
        threads_num = 8
655
        loop_num = 8
656
        threads = []
657
        collection = []
658
        j = 0
659
        while j < (threads_num * loop_num):
660
            collection_name = gen_unique_str("test_create_index_multiprocessing")
661
            collection.append(collection_name)
662
            param = {'collection_name': collection_name,
663
                     'dimension': dim,
664
                     'index_type': IndexType.FLAT,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable IndexType does not seem to be defined.
Loading history...
665
                     'store_raw_vector': False}
666
            connect.create_collection(param)
667
            j = j + 1
668
669
        def create_index():
670
            i = 0
671
            while i < loop_num:
672
                # assert connect.has_collection(collection[ids*process_num+i])
673
                ids = connect.insert(collection[ids * threads_num + i], vectors)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable vectors does not seem to be defined.
Loading history...
introduced by
The variable ids does not seem to be defined in case the while loop on line 671 is not entered. Are you sure this can never be the case?
Loading history...
674
                connect.create_index(collection[ids * threads_num + i], IndexType.IVFLAT, {"nlist": NLIST})
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable IndexType does not seem to be defined.
Loading history...
675
                assert status.OK()
0 ignored issues
show
introduced by
The variable status does not seem to be defined in case the while loop on line 671 is not entered. Are you sure this can never be the case?
Loading history...
676
                query_vec = [vectors[0]]
677
                top_k = 1
678
                search_param = {"nprobe": nprobe}
679
                status, result = connect.search(collection[ids * threads_num + i], top_k, query_vec,
680
                                                params=search_param)
681
                assert len(result) == 1
682
                assert len(result[0]) == top_k
683
                assert result[0][0].distance == 0.0
684
                i = i + 1
685
686
        for i in range(threads_num):
687
            m = get_milvus(host=args["ip"], port=args["port"], handler=args["handler"])
688
            ids = i
689
            t = threading.Thread(target=create_index, args=(m, ids))
690
            threads.append(t)
691
            t.start()
692
            time.sleep(0.2)
693
        for t in threads:
694
            t.join()
695
696
    def _test_describe_and_drop_index_multi_collections(self, connect, get_simple_index):
697
        '''
698
        target: test create, describe and drop index interface with multiple collections of IP
699
        method: create collections and add entities in it, create index, call describe index
700
        expected: return code 0, and index instructure
701
        '''
702
        nq = 100
703
        vectors = gen_vectors(nq, dim)
704
        collection_list = []
705
        for i in range(10):
706
            collection_name = gen_unique_str()
707
            collection_list.append(collection_name)
708
            param = {'collection_name': collection_name,
709
                     'dimension': dim,
710
                     'index_file_size': index_file_size,
711
                     'metric_type': MetricType.IP}
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable MetricType does not seem to be defined.
Loading history...
712
            connect.create_collection(param)
713
            index_param = get_simple_index["index_param"]
714
            index_type = get_simple_index["index_type"]
715
            logging.getLogger().info(get_simple_index)
716
            ids = connect.insert(collection_name=collection_name, records=vectors)
717
            connect.create_index(collection_name, index_type, index_param)
718
            assert status.OK()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable status does not seem to be defined.
Loading history...
719
        for i in range(10):
720
            stats = connect.get_collection_stats(collection_list[i])
721
            logging.getLogger().info(result)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable result does not seem to be defined.
Loading history...
722
            assert result._params == index_param
0 ignored issues
show
introduced by
The variable index_param does not seem to be defined in case the for loop on line 705 is not entered. Are you sure this can never be the case?
Loading history...
723
            assert result._collection_name == collection_list[i]
724
            assert result._index_type == index_type
0 ignored issues
show
introduced by
The variable index_type does not seem to be defined in case the for loop on line 705 is not entered. Are you sure this can never be the case?
Loading history...
725
        for i in range(10):
726
            connect.drop_index(collection_list[i])
727
            assert status.OK()
728
            stats = connect.get_collection_stats(collection_list[i])
729
            logging.getLogger().info(result)
730
            assert result._collection_name == collection_list[i]
731
            assert result._index_type == IndexType.FLAT
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable IndexType does not seem to be defined.
Loading history...
732
733
734
class TestIndexInvalid(object):
735
    """
736
    Test create / describe / drop index interfaces with invalid collection names
737
    """
738
739
    @pytest.fixture(
740
        scope="function",
741
        params=gen_invalid_strs()
742
    )
743
    def get_collection_name(self, request):
744
        yield request.param
745
746
    @pytest.mark.level(1)
747
    def test_create_index_with_invalid_collectionname(self, connect, get_collection_name):
748
        collection_name = get_collection_name
749
        with pytest.raises(Exception) as e:
750
            connect.create_index(collection_name, field_name, default_index_name, default_index)
751
752
    @pytest.mark.level(1)
753
    def test_drop_index_with_invalid_collectionname(self, connect, get_collection_name):
754
        collection_name = get_collection_name
755
        with pytest.raises(Exception) as e:
756
            connect.drop_index(collection_name)
757
758
    @pytest.fixture(
759
        scope="function",
760
        params=gen_invalid_index()
761
    )
762
    def get_index(self, request):
763
        yield request.param
764
765
    @pytest.mark.level(1)
766
    def test_create_index_with_invalid_index_params(self, connect, collection, get_index):
767
        logging.getLogger().info(get_index)
768
        with pytest.raises(Exception) as e:
769
            connect.create_index(collection, field_name, default_index_name, get_simple_index)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable get_simple_index does not seem to be defined.
Loading history...
770
771
772
class TestIndexAsync:
773
    @pytest.fixture(scope="function", autouse=True)
774
    def skip_http_check(self, args):
775
        if args["handler"] == "HTTP":
776
            pytest.skip("skip in http mode")
777
778
    """
779
    ******************************************************************
780
      The following cases are used to test `create_index` function
781
    ******************************************************************
782
    """
783
784
    @pytest.fixture(
785
        scope="function",
786
        params=gen_simple_index()
787
    )
788
    def get_simple_index(self, request, connect):
789
        if str(connect._cmd("mode")) == "CPU":
790
            if request.param["index_type"] in index_cpu_not_support():
791
                pytest.skip("sq8h not support in CPU mode")
792
        return request.param
793
794
    def check_result(self, res):
795
        logging.getLogger().info("In callback check search result")
796
        logging.getLogger().info(res)
797
798
    """
799
    ******************************************************************
800
      The following cases are used to test `create_index` function
801
    ******************************************************************
802
    """
803
804
    @pytest.mark.timeout(BUILD_TIMEOUT)
805
    def test_create_index(self, connect, collection, get_simple_index):
806
        '''
807
        target: test create index interface
808
        method: create collection and add entities in it, create index
809
        expected: return search success
810
        '''
811
        ids = connect.insert(collection, entities)
812
        logging.getLogger().info("start index")
813
        future = connect.create_index(collection, field_name, default_index_name, get_simple_index, _async=True)
814
        logging.getLogger().info("before result")
815
        res = future.result()
816
        # TODO:
817
        logging.getLogger().info(res)
818
819
    def test_create_index_with_invalid_collectionname(self, connect):
820
        collection_name = " "
821
        future = connect.create_index(collection_name, field_name, default_index_name, default_index, _async=True)
822
        with pytest.raises(Exception) as e:
823
            res = future.result()
824
825
    @pytest.mark.timeout(BUILD_TIMEOUT)
826
    def test_create_index_callback(self, connect, collection, get_simple_index):
827
        '''
828
        target: test create index interface
829
        method: create collection and add entities in it, create index
830
        expected: return search success
831
        '''
832
        ids = connect.insert(collection, entities)
833
        logging.getLogger().info("start index")
834
        future = connect.create_index(collection, field_name, default_index_name, get_simple_index, _async=True,
835
                                      _callback=self.check_result)
836
        logging.getLogger().info("before result")
837
        res = future.result()
838
        # TODO:
839
        logging.getLogger().info(res)
840