Passed
Push — master ( 64d748...d0b3c7 )
by
unknown
01:48
created

test_index.TestIndexBase.test_create_index_without_connect_ip()   A

Complexity

Conditions 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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