test_collection.TestCollectionLogic.execute()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nop 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
import pdb
2
import pytest
3
import logging
4
import itertools
5
from time import sleep
6
from multiprocessing import Process
7
from milvus import IndexType, MetricType
8
from utils import *
9
10
dim = 128
11
drop_collection_interval_time = 3
12
index_file_size = 10
13
vectors = gen_vectors(100, dim)
14
15
16
class TestCollection:
17
18
    """
19
    ******************************************************************
20
      The following cases are used to test `create_collection` function
21
    ******************************************************************
22
    """
23
24
    def test_create_collection(self, connect):
25
        '''
26
        target: test create normal collection 
27
        method: create collection with corrent params
28
        expected: create status return ok
29
        '''
30
        collection_name = gen_unique_str("test_collection")
31
        param = {'collection_name': collection_name,
32
                 'dimension': dim,
33
                 'index_file_size': index_file_size, 
34
                 'metric_type': MetricType.L2}
35
        status = connect.create_collection(param)
36
        assert status.OK()
37
38
    def test_create_collection_ip(self, connect):
39
        '''
40
        target: test create normal collection 
41
        method: create collection with corrent params
42
        expected: create status return ok
43
        '''
44
        collection_name = gen_unique_str("test_collection")
45
        param = {'collection_name': collection_name,
46
                 'dimension': dim,
47
                 'index_file_size': index_file_size, 
48
                 'metric_type': MetricType.IP}
49
        status = connect.create_collection(param)
50
        assert status.OK()
51
52
    def test_create_collection_jaccard(self, connect):
53
        '''
54
        target: test create normal collection 
55
        method: create collection with corrent params
56
        expected: create status return ok
57
        '''
58
        collection_name = gen_unique_str("test_collection")
59
        param = {'collection_name': collection_name,
60
                 'dimension': dim,
61
                 'index_file_size': index_file_size, 
62
                 'metric_type': MetricType.JACCARD}
63
        status = connect.create_collection(param)
64
        assert status.OK()
65
66
    def test_create_collection_hamming(self, connect):
67
        '''
68
        target: test create normal collection
69
        method: create collection with corrent params
70
        expected: create status return ok
71
        '''
72
        collection_name = gen_unique_str("test_collection")
73
        param = {'collection_name': collection_name,
74
                 'dimension': dim,
75
                 'index_file_size': index_file_size,
76
                 'metric_type': MetricType.HAMMING}
77
        status = connect.create_collection(param)
78
        assert status.OK()
79
80
    def test_create_collection_substructure(self, connect):
81
        '''
82
        target: test create normal collection
83
        method: create collection with corrent params
84
        expected: create status return ok
85
        '''
86
        collection_name = gen_unique_str("test_collection")
87
        param = {'collection_name': collection_name,
88
                 'dimension': dim,
89
                 'index_file_size': index_file_size,
90
                 'metric_type': MetricType.SUBSTRUCTURE}
91
        status = connect.create_collection(param)
92
        assert status.OK()
93
94
    def test_create_collection_superstructure(self, connect):
95
        '''
96
        target: test create normal collection
97
        method: create collection with corrent params
98
        expected: create status return ok
99
        '''
100
        collection_name = gen_unique_str("test_collection")
101
        param = {'collection_name': collection_name,
102
                 'dimension': dim,
103
                 'index_file_size': index_file_size,
104
                 'metric_type': MetricType.SUPERSTRUCTURE}
105
        status = connect.create_collection(param)
106
        assert status.OK()
107
108
    def test_create_collection_auto_flush_disabled(self, connect):
109
        '''
110
        target: test create normal collection, with large auto_flush_interval
111
        method: create collection with corrent params
112
        expected: create status return ok
113
        '''
114
        disable_flush(connect)
115
        collection_name = gen_unique_str("test_collection")
116
        try:
117
            param = {'collection_name': collection_name,
118
                     'dimension': dim,
119
                     'index_file_size': index_file_size,
120
                     'metric_type': MetricType.SUPERSTRUCTURE}
121
            status = connect.create_collection(param)
122
            assert status.OK()
123
            status = connect.drop_collection(collection_name,)
124
            assert status.OK()
125
            time.sleep(2)
126
            ## recreate collection
127
            status = connect.create_collection(param)
128
            assert status.OK()
129
        except Exception as e:
130
            pass
131
        finally:
132
            enable_flush(connect)
133
134
    @pytest.mark.level(2)
135
    def test_create_collection_without_connection(self, dis_connect):
136
        '''
137
        target: test create collection, without connection
138
        method: create collection with correct params, with a disconnected instance
139
        expected: create raise exception
140
        '''
141
        collection_name = gen_unique_str("test_collection")
142
        param = {'collection_name': collection_name,
143
                 'dimension': dim,
144
                 'index_file_size': index_file_size,
145
                 'metric_type': MetricType.L2}
146
        with pytest.raises(Exception) as e:
147
            status = dis_connect.create_collection(param)
148
149
    def test_create_collection_existed(self, connect):
150
        '''
151
        target: test create collection but the collection name have already existed
152
        method: create collection with the same collection_name
153
        expected: create status return not ok
154
        '''
155
        collection_name = gen_unique_str("test_collection")
156
        param = {'collection_name': collection_name,
157
                 'dimension': dim,
158
                 'index_file_size': index_file_size, 
159
                 'metric_type': MetricType.L2}
160
        status = connect.create_collection(param)
161
        status = connect.create_collection(param)
162
        assert not status.OK()
163
164
    @pytest.mark.level(2)
165
    def test_create_collection_existed_ip(self, connect):
166
        '''
167
        target: test create collection but the collection name have already existed
168
        method: create collection with the same collection_name
169
        expected: create status return not ok
170
        '''
171
        collection_name = gen_unique_str("test_collection")
172
        param = {'collection_name': collection_name,
173
                 'dimension': dim,
174
                 'index_file_size': index_file_size, 
175
                 'metric_type': MetricType.IP}
176
        status = connect.create_collection(param)
177
        status = connect.create_collection(param)
178
        assert not status.OK()
179
180
    def test_create_collection_None(self, connect):
181
        '''
182
        target: test create collection but the collection name is None
183
        method: create collection, param collection_name is None
184
        expected: create raise error
185
        '''
186
        param = {'collection_name': None,
187
                 'dimension': dim,
188
                 'index_file_size': index_file_size, 
189
                 'metric_type': MetricType.L2}
190
        with pytest.raises(Exception) as e:
191
            status = connect.create_collection(param)
192
193
    def test_create_collection_no_dimension(self, connect):
194
        '''
195
        target: test create collection with no dimension params
196
        method: create collection with corrent params
197
        expected: create status return ok
198
        '''
199
        collection_name = gen_unique_str("test_collection")
200
        param = {'collection_name': collection_name,
201
                 'index_file_size': index_file_size,
202
                 'metric_type': MetricType.L2}
203
        with pytest.raises(Exception) as e:
204
            status = connect.create_collection(param)
205
206
    def test_create_collection_no_file_size(self, connect):
207
        '''
208
        target: test create collection with no index_file_size params
209
        method: create collection with corrent params
210
        expected: create status return ok, use default 1024
211
        '''
212
        collection_name = gen_unique_str("test_collection")
213
        param = {'collection_name': collection_name,
214
                 'dimension': dim,
215
                 'metric_type': MetricType.L2}
216
        status = connect.create_collection(param)
217
        logging.getLogger().info(status)
218
        status, result = connect.get_collection_info(collection_name)
219
        logging.getLogger().info(result)
220
        assert result.index_file_size == 1024
221
222
    def test_create_collection_no_metric_type(self, connect):
223
        '''
224
        target: test create collection with no metric_type params
225
        method: create collection with corrent params
226
        expected: create status return ok, use default L2
227
        '''
228
        collection_name = gen_unique_str("test_collection")
229
        param = {'collection_name': collection_name,
230
                 'dimension': dim,
231
                 'index_file_size': index_file_size}
232
        status = connect.create_collection(param)
233
        status, result = connect.get_collection_info(collection_name)
234
        logging.getLogger().info(result)
235
        assert result.metric_type == MetricType.L2
236
237
    """
238
    ******************************************************************
239
      The following cases are used to test `get_collection_info` function
240
    ******************************************************************
241
    """
242
243
    def test_collection_describe_result(self, connect):
244
        '''
245
        target: test describe collection created with correct params 
246
        method: create collection, assert the value returned by describe method
247
        expected: collection_name equals with the collection name created
248
        '''
249
        collection_name = gen_unique_str("test_collection")
250
        param = {'collection_name': collection_name,
251
                 'dimension': dim,
252
                 'index_file_size': index_file_size,
253
                 'metric_type': MetricType.L2}
254
        connect.create_collection(param)
255
        status, res = connect.get_collection_info(collection_name)
256
        assert res.collection_name == collection_name
257
        assert res.metric_type == MetricType.L2
258
259
    @pytest.mark.level(2)
260
    def test_collection_get_collection_info_name_ip(self, connect):
261
        '''
262
        target: test describe collection created with correct params 
263
        method: create collection, assert the value returned by describe method
264
        expected: collection_name equals with the collection name created
265
        '''
266
        collection_name = gen_unique_str("test_collection")
267
        param = {'collection_name': collection_name,
268
                 'dimension': dim,
269
                 'index_file_size': index_file_size,
270
                 'metric_type': MetricType.IP}
271
        connect.create_collection(param)
272
        status, res = connect.get_collection_info(collection_name)
273
        assert res.collection_name == collection_name
274
        assert res.metric_type == MetricType.IP
275
276
    @pytest.mark.level(2)
277
    def test_collection_get_collection_info_name_jaccard(self, connect):
278
        '''
279
        target: test describe collection created with correct params 
280
        method: create collection, assert the value returned by describe method
281
        expected: collection_name equals with the collection name created
282
        '''
283
        collection_name = gen_unique_str("test_collection")
284
        param = {'collection_name': collection_name,
285
                 'dimension': dim,
286
                 'index_file_size': index_file_size,
287
                 'metric_type': MetricType.JACCARD}
288
        connect.create_collection(param)
289
        status, res = connect.get_collection_info(collection_name)
290
        assert res.collection_name == collection_name
291
        assert res.metric_type == MetricType.JACCARD
292
293
    @pytest.mark.level(2)
294
    def test_collection_get_collection_info_name_hamming(self, connect):
295
        '''
296
        target: test describe collection created with correct params
297
        method: create collection, assert the value returned by describe method
298
        expected: collection_name equals with the collection name created
299
        '''
300
        collection_name = gen_unique_str("test_collection")
301
        param = {'collection_name': collection_name,
302
                 'dimension': dim,
303
                 'index_file_size': index_file_size,
304
                 'metric_type': MetricType.HAMMING}
305
        connect.create_collection(param)
306
        status, res = connect.get_collection_info(collection_name)
307
        assert res.collection_name == collection_name
308
        assert res.metric_type == MetricType.HAMMING
309
310
    def test_collection_get_collection_info_name_substructure(self, connect):
311
        '''
312
        target: test describe collection created with correct params
313
        method: create collection, assert the value returned by describe method
314
        expected: collection_name equals with the collection name created
315
        '''
316
        collection_name = gen_unique_str("test_collection")
317
        param = {'collection_name': collection_name,
318
                 'dimension': dim,
319
                 'index_file_size': index_file_size,
320
                 'metric_type': MetricType.SUBSTRUCTURE}
321
        connect.create_collection(param)
322
        status, res = connect.get_collection_info(collection_name)
323
        assert res.collection_name == collection_name
324
        assert res.metric_type == MetricType.SUBSTRUCTURE
325
326
    def test_collection_get_collection_info_name_superstructure(self, connect):
327
        '''
328
        target: test describe collection created with correct params
329
        method: create collection, assert the value returned by describe method
330
        expected: collection_name equals with the collection name created
331
        '''
332
        collection_name = gen_unique_str("test_collection")
333
        param = {'collection_name': collection_name,
334
                 'dimension': dim,
335
                 'index_file_size': index_file_size,
336
                 'metric_type': MetricType.SUPERSTRUCTURE}
337
        connect.create_collection(param)
338
        status, res = connect.get_collection_info(collection_name)
339
        assert res.collection_name == collection_name
340
        assert res.metric_type == MetricType.SUPERSTRUCTURE
341
342
    # TODO: enable
343 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...
344
    def _test_collection_get_collection_info_name_multiprocessing(self, connect, args):
345
        '''
346
        target: test describe collection created with multiprocess 
347
        method: create collection, assert the value returned by describe method
348
        expected: collection_name equals with the collection name created
349
        '''
350
        collection_name = gen_unique_str("test_collection")
351
        param = {'collection_name': collection_name,
352
                 'dimension': dim,
353
                 'index_file_size': index_file_size, 
354
                 'metric_type': MetricType.L2}
355
        connect.create_collection(param)
356
357
        def describecollection(milvus):
358
            status, res = milvus.get_collection_info(collection_name)
359
            assert res.collection_name == collection_name
360
361
        process_num = 4
362
        processes = []
363
        for i in range(process_num):
364
            milvus = get_milvus(args["ip"], args["port"], handler=args["handler"])
365
            p = Process(target=describecollection, args=(milvus,))
366
            processes.append(p)
367
            p.start()
368
        for p in processes:
369
            p.join()
370
    
371
    # @pytest.mark.level(2)
372
    # def test_collection_describe_without_connection(self, collection, dis_connect):
373
    #     '''
374
    #     target: test describe collection, without connection
375
    #     method: describe collection with correct params, with a disconnected instance
376
    #     expected: describe raise exception
377
    #     '''
378
    #     with pytest.raises(Exception) as e:
379
    #         status = dis_connect.get_collection_info(collection)
380
381
    def test_collection_describe_dimension(self, connect):
382
        '''
383
        target: test describe collection created with correct params 
384
        method: create collection, assert the dimention value returned by describe method
385
        expected: dimention equals with dimention when created
386
        '''
387
        collection_name = gen_unique_str("test_collection")
388
        param = {'collection_name': collection_name,
389
                 'dimension': dim+1,
390
                 'index_file_size': index_file_size,
391
                 'metric_type': MetricType.L2}
392
        connect.create_collection(param)
393
        status, res = connect.get_collection_info(collection_name)
394
        assert res.dimension == dim+1
395
396
    """
397
    ******************************************************************
398
      The following cases are used to test `drop_collection` function
399
    ******************************************************************
400
    """
401
402
    def test_drop_collection(self, connect, collection):
403
        '''
404
        target: test delete collection created with correct params 
405
        method: create collection and then delete, 
406
            assert the value returned by delete method
407
        expected: status ok, and no collection in collections
408
        '''
409
        status = connect.drop_collection(collection)
410
        assert not assert_has_collection(connect, collection)
411
412
    @pytest.mark.level(2)
413
    def test_drop_collection_ip(self, connect, ip_collection):
414
        '''
415
        target: test delete collection created with correct params 
416
        method: create collection and then delete, 
417
            assert the value returned by delete method
418
        expected: status ok, and no collection in collections
419
        '''
420
        status = connect.drop_collection(ip_collection)
421
        assert not assert_has_collection(connect, ip_collection)
422
423
    @pytest.mark.level(2)
424
    def test_drop_collection_jaccard(self, connect, jac_collection):
425
        '''
426
        target: test delete collection created with correct params 
427
        method: create collection and then delete, 
428
            assert the value returned by delete method
429
        expected: status ok, and no collection in collections
430
        '''
431
        status = connect.drop_collection(jac_collection)
432
        assert not assert_has_collection(connect, jac_collection)
433
434
    @pytest.mark.level(2)
435
    def test_drop_collection_hamming(self, connect, ham_collection):
436
        '''
437
        target: test delete collection created with correct params
438
        method: create collection and then delete,
439
            assert the value returned by delete method
440
        expected: status ok, and no collection in collections
441
        '''
442
        status = connect.drop_collection(ham_collection)
443
        assert not assert_has_collection(connect, ham_collection)
444
445
    # @pytest.mark.level(2)
446
    # def test_collection_delete_without_connection(self, collection, dis_connect):
447
    #     '''
448
    #     target: test describe collection, without connection
449
    #     method: describe collection with correct params, with a disconnected instance
450
    #     expected: describe raise exception
451
    #     '''
452
    #     with pytest.raises(Exception) as e:
453
    #         status = dis_connect.drop_collection(collection)
454
455
    def test_drop_collection_not_existed(self, connect):
456
        '''
457
        target: test delete collection not in index
458
        method: delete all collections, and delete collection again, 
459
            assert the value returned by delete method
460
        expected: status not ok
461
        '''
462
        collection_name = gen_unique_str("test_collection")
463
        status = connect.drop_collection(collection_name)
464
        assert not status.OK()
465
466
    def test_delete_create_collection_repeatedly(self, connect):
467
        '''
468
        target: test delete and create the same collection repeatedly
469
        method: try to create the same collection and delete repeatedly,
470
            assert the value returned by delete method
471
        expected: create ok and delete ok
472
        '''
473
        loops = 2 
474
        timeout = 5
475
        for i in range(loops):
476
            collection_name = "test_collection"
477
            param = {'collection_name': collection_name,
478
                 'dimension': dim,
479
                 'index_file_size': index_file_size,
480
                 'metric_type': MetricType.L2}
481
            connect.create_collection(param)
482
            status = None
483
            while i < timeout:
484
                status = connect.drop_collection(collection_name)
485
                time.sleep(1)
486
                i += 1
487
                if status.OK():
488
                    break
489
            if i > timeout:
490
                assert False
491
492
    # TODO: enable
493
    @pytest.mark.level(2)
494
    def _test_drop_collection_multiprocessing(self, args):
495
        '''
496
        target: test delete collection with multiprocess 
497
        method: create collection and then delete, 
498
            assert the value returned by delete method
499
        expected: status ok, and no collection in collections
500
        '''
501
        process_num = 6
502
        processes = []
503
        def deletecollection(milvus):
504
            status = milvus.drop_collection(collection)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable collection does not seem to be defined.
Loading history...
505
            # assert not status.code==0
506
            assert assert_has_collection(milvus, collection)
507
            assert status.OK()
508
509
        for i in range(process_num):
510
            milvus = get_milvus(args["ip"], args["port"], handler=args["handler"])
511
            p = Process(target=deletecollection, args=(milvus,))
512
            processes.append(p)
513
            p.start()
514
        for p in processes:
515
            p.join()
516
517
    # TODO: enable
518
    @pytest.mark.level(2)
519
    def _test_drop_collection_multiprocessing_multicollection(self, connect):
520
        '''
521
        target: test delete collection with multiprocess 
522
        method: create collection and then delete, 
523
            assert the value returned by delete method
524
        expected: status ok, and no collection in collections
525
        '''
526
        process_num = 5
527
        loop_num = 2
528
        processes = []
529
530
        collection = []
531
        j = 0
532
        while j < (process_num*loop_num):
533
            collection_name = gen_unique_str("test_drop_collection_with_multiprocessing")
534
            collection.append(collection_name)
535
            param = {'collection_name': collection_name,
536
                 'dimension': dim,
537
                 'index_file_size': index_file_size,
538
                 'metric_type': MetricType.L2}
539
            connect.create_collection(param)
540
            j = j + 1
541
542
        def delete(connect,ids):
543
            i = 0
544
            while i < loop_num:
545
                status = connect.drop_collection(collection[ids*process_num+i])
546
                time.sleep(2)
547
                assert status.OK()
548
                assert not assert_has_collection(connect, collection[ids*process_num+i])
549
                i = i + 1
550
551
        for i in range(process_num):
552
            ids = i
553
            p = Process(target=delete, args=(connect,ids))
554
            processes.append(p)
555
            p.start()
556
        for p in processes:
557
            p.join()
558
559
    """
560
    ******************************************************************
561
      The following cases are used to test `has_collection` function
562
    ******************************************************************
563
    """
564
565
    def test_has_collection(self, connect):
566
        '''
567
        target: test if the created collection existed
568
        method: create collection, assert the value returned by has_collection method
569
        expected: True
570
        '''
571
        collection_name = gen_unique_str("test_collection")
572
        param = {'collection_name': collection_name,
573
                 'dimension': dim,
574
                 'index_file_size': index_file_size,
575
                 'metric_type': MetricType.L2}
576
        connect.create_collection(param)
577
        assert assert_has_collection(connect, collection_name)
578
579
    def test_has_collection_ip(self, connect):
580
        '''
581
        target: test if the created collection existed
582
        method: create collection, assert the value returned by has_collection method
583
        expected: True
584
        '''
585
        collection_name = gen_unique_str("test_collection")
586
        param = {'collection_name': collection_name,
587
                 'dimension': dim,
588
                 'index_file_size': index_file_size,
589
                 'metric_type': MetricType.IP}
590
        connect.create_collection(param)
591
        assert assert_has_collection(connect, collection_name)
592
593
    def test_has_collection_jaccard(self, connect):
594
        '''
595
        target: test if the created collection existed
596
        method: create collection, assert the value returned by has_collection method
597
        expected: True
598
        '''
599
        collection_name = gen_unique_str("test_collection")
600
        param = {'collection_name': collection_name,
601
                 'dimension': dim,
602
                 'index_file_size': index_file_size,
603
                 'metric_type': MetricType.JACCARD}
604
        connect.create_collection(param)
605
        assert assert_has_collection(connect, collection_name)
606
607
    def test_has_collection_hamming(self, connect):
608
        '''
609
        target: test if the created collection existed
610
        method: create collection, assert the value returned by has_collection method
611
        expected: True
612
        '''
613
        collection_name = gen_unique_str("test_collection")
614
        param = {'collection_name': collection_name,
615
                 'dimension': dim,
616
                 'index_file_size': index_file_size,
617
                 'metric_type': MetricType.HAMMING}
618
        connect.create_collection(param)
619
        assert assert_has_collection(connect, collection_name)
620
621
    # @pytest.mark.level(2)
622
    # def test_has_collection_without_connection(self, collection, dis_connect):
623
    #     '''
624
    #     target: test has collection, without connection
625
    #     method: calling has collection with correct params, with a disconnected instance
626
    #     expected: has collection raise exception
627
    #     '''
628
    #     with pytest.raises(Exception) as e:
629
    #         assert_has_collection(dis_connect, collection)
630
631
    def test_has_collection_not_existed(self, connect):
632
        '''
633
        target: test if collection not created
634
        method: random a collection name, which not existed in db, 
635
            assert the value returned by has_collection method
636
        expected: False
637
        '''
638
        collection_name = gen_unique_str("test_collection")
639
        assert not assert_has_collection(connect, collection_name)
640
641
    """
642
    ******************************************************************
643
      The following cases are used to test `list_collections` function
644
    ******************************************************************
645
    """
646
647
    def test_list_collections(self, connect):
648
        '''
649
        target: test show collections is correct or not, if collection created
650
        method: create collection, assert the value returned by list_collections method is equal to 0
651
        expected: collection_name in show collections   
652
        '''
653
        collection_name = gen_unique_str("test_collection")
654
        param = {'collection_name': collection_name,
655
                 'dimension': dim,
656
                 'index_file_size': index_file_size,
657
                 'metric_type': MetricType.L2}
658
        connect.create_collection(param)    
659
        status, result = connect.list_collections()
660
        assert status.OK()
661
        assert collection_name in result
662
663
    def test_list_collections_ip(self, connect):
664
        '''
665
        target: test show collections is correct or not, if collection created
666
        method: create collection, assert the value returned by list_collections method is equal to 0
667
        expected: collection_name in show collections   
668
        '''
669
        collection_name = gen_unique_str("test_collection")
670
        param = {'collection_name': collection_name,
671
                 'dimension': dim,
672
                 'index_file_size': index_file_size,
673
                 'metric_type': MetricType.IP}
674
        connect.create_collection(param)    
675
        status, result = connect.list_collections()
676
        assert status.OK()
677
        assert collection_name in result
678
679
    def test_list_collections_jaccard(self, connect):
680
        '''
681
        target: test show collections is correct or not, if collection created
682
        method: create collection, assert the value returned by list_collections method is equal to 0
683
        expected: collection_name in show collections   
684
        '''
685
        collection_name = gen_unique_str("test_collection")
686
        param = {'collection_name': collection_name,
687
                 'dimension': dim,
688
                 'index_file_size': index_file_size,
689
                 'metric_type': MetricType.JACCARD}
690
        connect.create_collection(param)    
691
        status, result = connect.list_collections()
692
        assert status.OK()
693
        assert collection_name in result
694
695
    def test_list_collections_hamming(self, connect):
696
        '''
697
        target: test show collections is correct or not, if collection created
698
        method: create collection, assert the value returned by list_collections method is equal to 0
699
        expected: collection_name in show collections
700
        '''
701
        collection_name = gen_unique_str("test_collection")
702
        param = {'collection_name': collection_name,
703
                 'dimension': dim,
704
                 'index_file_size': index_file_size,
705
                 'metric_type': MetricType.HAMMING}
706
        connect.create_collection(param)
707
        status, result = connect.list_collections()
708
        assert status.OK()
709
        assert collection_name in result
710
711
    def test_list_collections_substructure(self, connect):
712
        '''
713
        target: test show collections is correct or not, if collection created
714
        method: create collection, assert the value returned by list_collections method is equal to 0
715
        expected: collection_name in show collections
716
        '''
717
        collection_name = gen_unique_str("test_collection")
718
        param = {'collection_name': collection_name,
719
                 'dimension': dim,
720
                 'index_file_size': index_file_size,
721
                 'metric_type': MetricType.SUBSTRUCTURE}
722
        connect.create_collection(param)
723
        status, result = connect.list_collections()
724
        assert status.OK()
725
        assert collection_name in result
726
727
    def test_list_collections_superstructure(self, connect):
728
        '''
729
        target: test show collections is correct or not, if collection created
730
        method: create collection, assert the value returned by list_collections method is equal to 0
731
        expected: collection_name in show collections
732
        '''
733
        collection_name = gen_unique_str("test_collection")
734
        param = {'collection_name': collection_name,
735
                 'dimension': dim,
736
                 'index_file_size': index_file_size,
737
                 'metric_type': MetricType.SUPERSTRUCTURE}
738
        connect.create_collection(param)
739
        status, result = connect.list_collections()
740
        assert status.OK()
741
        assert collection_name in result
742
743
    # @pytest.mark.level(2)
744
    # def test_list_collections_without_connection(self, dis_connect):
745
    #     '''
746
    #     target: test list_collections, without connection
747
    #     method: calling list_collections with correct params, with a disconnected instance
748
    #     expected: list_collections raise exception
749
    #     '''
750
    #     with pytest.raises(Exception) as e:
751
    #         status = dis_connect.list_collections()
752
753
    @pytest.mark.level(2)
754
    def test_list_collections_no_collection(self, connect):
755
        '''
756
        target: test show collections is correct or not, if no collection in db
757
        method: delete all collections,
758
            assert the value returned by list_collections method is equal to []
759
        expected: the status is ok, and the result is equal to []      
760
        '''
761
        status, result = connect.list_collections()
762
        if result:
763
            for collection_name in result:
764
                connect.drop_collection(collection_name)
765
        time.sleep(drop_collection_interval_time)
766
        status, result = connect.list_collections()
767
        assert status.OK()
768
        assert len(result) == 0
769
770
    # TODO: enable
771 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...
772
    def _test_list_collections_multiprocessing(self, connect, args):
773
        '''
774
        target: test show collections is correct or not with processes
775
        method: create collection, assert the value returned by list_collections method is equal to 0
776
        expected: collection_name in show collections
777
        '''
778
        collection_name = gen_unique_str("test_collection")
779
        param = {'collection_name': collection_name,
780
                 'dimension': dim,
781
                 'index_file_size': index_file_size,
782
                 'metric_type': MetricType.L2}
783
        connect.create_collection(param)
784
        def showcollections(milvus):
785
            status, result = milvus.list_collections()
786
            assert status.OK()
787
            assert collection_name in result
788
789
        process_num = 8
790
        processes = []
791
792
        for i in range(process_num):
793
            milvus = get_milvus(args["ip"], args["port"], handler=args["handler"])
794
            p = Process(target=showcollections, args=(milvus,))
795
            processes.append(p)
796
            p.start()
797
        for p in processes:
798
            p.join()
799
800
    """
801
    ******************************************************************
802
      The following cases are used to test `load_collection` function
803
    ******************************************************************
804
    """
805
806
    """
807
    generate valid create_index params
808
    """
809 View Code Duplication
    @pytest.fixture(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
810
        scope="function",
811
        params=gen_simple_index()
812
    )
813
    def get_simple_index(self, request, connect):
814
        if str(connect._cmd("mode")[1]) == "CPU":
815
            if request.param["index_type"] == IndexType.IVF_SQ8H:
816
                pytest.skip("sq8h not support in cpu mode")
817
        if request.param["index_type"] == IndexType.IVF_PQ:
818
            pytest.skip("Skip PQ Temporary")
819
        return request.param
820
821
    @pytest.mark.level(1)
822
    def test_load_collection(self, connect, collection, get_simple_index):
823
        index_param = get_simple_index["index_param"]
824
        index_type = get_simple_index["index_type"]
825
        status, ids = connect.insert(collection, vectors)
826
        status = connect.create_index(collection, index_type, index_param)
827
        status = connect.load_collection(collection)
828
        assert status.OK()
829
830
    @pytest.mark.level(1)
831
    def test_load_collection_ip(self, connect, ip_collection, get_simple_index):
832
        index_param = get_simple_index["index_param"]
833
        index_type = get_simple_index["index_type"]
834
        status, ids = connect.insert(ip_collection, vectors)
835
        status = connect.create_index(ip_collection, index_type, index_param)
836
        status = connect.load_collection(ip_collection)
837
        assert status.OK()
838
839
    @pytest.mark.level(1)
840
    def test_load_collection_jaccard(self, connect, jac_collection, get_simple_index):
841
        index_param = get_simple_index["index_param"]
842
        index_type = get_simple_index["index_type"]
843
        status, ids = connect.insert(jac_collection, vectors)
844
        status = connect.create_index(jac_collection, index_type, index_param)
845
        status = connect.load_collection(jac_collection)
846
        assert status.OK()
847
848
    @pytest.mark.level(1)
849
    def test_load_collection_hamming(self, connect, ham_collection, get_simple_index):
850
        index_param = get_simple_index["index_param"]
851
        index_type = get_simple_index["index_type"]
852
        status, ids = connect.insert(ham_collection, vectors)
853
        status = connect.create_index(ham_collection, index_type, index_param)
854
        status = connect.load_collection(ham_collection)
855
        assert status.OK()
856
857
    @pytest.mark.level(2)
858
    def test_load_collection_not_existed(self, connect, collection, get_simple_index):
859
        index_param = get_simple_index["index_param"]
860
        index_type = get_simple_index["index_type"]
861
        collection_name = gen_unique_str()
862
        status, ids = connect.insert(collection, vectors)
863
        status = connect.create_index(collection, index_type, index_param)
864
        status = connect.load_collection(collection_name)
865
        assert not status.OK()
866
867
    @pytest.mark.level(1)
868
    def test_load_collection_partition(self, connect, collection):
869
        partition_name = gen_unique_str()
870
        status, ids = connect.insert(collection, vectors)
871
        assert status.OK()
872
        status = connect.create_partition(collection, partition_name)
873
        status = connect.load_collection(collection, partition_tags=[partition_name])
874
        assert status.OK()
875
876
    @pytest.mark.level(1)
877
    def test_load_collection_partitions(self, connect, collection):
878
        partition_names = []
879
        for i in range(2):
880
            name = gen_unique_str()
881
            partition_names.append(name)
882
            status = connect.create_partition(collection, name)
883
            assert status.OK()
884
        status, ids = connect.insert(collection, vectors)
885
        status = connect.load_collection(collection, partition_tags=partition_names)
886
        assert status.OK()
887
888
    @pytest.mark.level(1)
889
    def test_load_collection_partition_not_existed(self, connect, collection):
890
        partition_name = gen_unique_str()
891
        status, ids = connect.insert(collection, vectors)
892
        assert status.OK()
893
        status = connect.load_collection(collection, partition_tags=[partition_name])
894
        assert not status.OK()
895
896
    @pytest.mark.level(1)
897
    def test_load_collection_partition_invalid_string(self, connect, collection):
898
        partition_name = "invalid string"
899
        status, ids = connect.insert(collection, vectors)
900
        assert status.OK()
901
        status = connect.load_collection(collection, partition_tags=[partition_name])
902
        assert not status.OK()
903
904
    @pytest.mark.level(1)
905
    def test_load_collection_partition_None(self, connect, collection):
906
        status = connect.load_collection(collection, partition_tags=None)
907
        assert status.OK()
908
909
    @pytest.mark.level(2)
910
    def test_load_collection_not_existed_ip(self, connect, ip_collection, get_simple_index):
911
        index_param = get_simple_index["index_param"]
912
        index_type = get_simple_index["index_type"]
913
        collection_name = gen_unique_str()
914
        status, ids = connect.insert(ip_collection, vectors)
915
        status = connect.create_index(ip_collection, index_type, index_param)
916
        status = connect.load_collection(collection_name)
917
        assert not status.OK()
918
919
    @pytest.mark.level(1)
920
    def test_load_collection_no_vectors(self, connect, collection):
921
        status = connect.load_collection(collection)
922
        assert status.OK()
923
924
    @pytest.mark.level(2)
925
    def test_load_collection_no_vectors_ip(self, connect, ip_collection):
926
        status = connect.load_collection(ip_collection)
927
        assert status.OK()
928
929
    # TODO: psutils get memory usage
930
    @pytest.mark.level(1)
931
    def test_load_collection_memory_usage(self, connect, collection):
932
        pass
933
934
935
class TestCollectionInvalid(object):
936
    """
937
    Test creating collection with invalid collection names
938
    """
939
    @pytest.fixture(
940
        scope="function",
941
        params=gen_invalid_collection_names()
942
    )
943
    def get_collection_name(self, request):
944
        yield request.param
945
946
    @pytest.mark.level(2)
947
    def test_create_collection_with_invalid_collectionname(self, connect, get_collection_name):
948
        collection_name = get_collection_name
949
        param = {'collection_name': collection_name,
950
                 'dimension': dim,
951
                 'index_file_size': index_file_size,
952
                 'metric_type': MetricType.L2}
953
        status = connect.create_collection(param)
954
        assert not status.OK()
955
956
    def test_create_collection_with_empty_collectionname(self, connect):
957
        collection_name = ''
958
        param = {'collection_name': collection_name,
959
                 'dimension': dim,
960
                 'index_file_size': index_file_size,
961
                 'metric_type': MetricType.L2}
962
        with pytest.raises(Exception) as e:
963
            status = connect.create_collection(param)
964
965
    def test_load_collection_with_invalid_collectionname(self, connect):
966
        collection_name = ''
967
        with pytest.raises(Exception) as e:
968
            status = connect.load_collection(collection_name)
969
970
971
class TestCreateCollectionDimInvalid(object):
972
    """
973
    Test creating collection with invalid dimension
974
    """
975
    @pytest.fixture(
976
        scope="function",
977
        params=gen_invalid_dims()
978
    )
979
    def get_dim(self, request):
980
        yield request.param
981
982
    @pytest.mark.level(2)
983
    @pytest.mark.timeout(5)
984
    def test_create_collection_with_invalid_dimension(self, connect, get_dim):
985
        dimension = get_dim
986
        collection = gen_unique_str("test_create_collection_with_invalid_dimension")
987
        param = {'collection_name': collection,
988
                 'dimension': dimension,
989
                 'index_file_size': index_file_size,
990
                 'metric_type': MetricType.L2}
991
        if isinstance(dimension, int):
992
            status = connect.create_collection(param)
993
            assert not status.OK()
994
        else:
995
            with pytest.raises(Exception) as e:
996
                status = connect.create_collection(param)
997
            
998
999
# TODO: max / min index file size
1000
class TestCreateCollectionIndexSizeInvalid(object):
1001
    """
1002
    Test creating collections with invalid index_file_size
1003
    """
1004
    @pytest.fixture(
1005
        scope="function",
1006
        params=gen_invalid_file_sizes()
1007
    )
1008
    def get_file_size(self, request):
1009
        yield request.param
1010
1011
    @pytest.mark.level(2)
1012
    def test_create_collection_with_invalid_file_size(self, connect, collection, get_file_size):
1013
        file_size = get_file_size
1014
        param = {'collection_name': collection,
1015
                 'dimension': dim,
1016
                 'index_file_size': file_size,
1017
                 'metric_type': MetricType.L2}
1018
        if isinstance(file_size, int):
1019
            status = connect.create_collection(param)
1020
            assert not status.OK()
1021
        else:
1022
            with pytest.raises(Exception) as e:
1023
                status = connect.create_collection(param)
1024
1025
1026
class TestCreateMetricTypeInvalid(object):
1027
    """
1028
    Test creating collections with invalid metric_type
1029
    """
1030
    @pytest.fixture(
1031
        scope="function",
1032
        params=gen_invalid_metric_types()
1033
    )
1034
    def get_metric_type(self, request):
1035
        yield request.param
1036
1037
    @pytest.mark.level(2)
1038
    def test_create_collection_with_invalid_file_size(self, connect, collection, get_metric_type):
1039
        metric_type = get_metric_type
1040
        param = {'collection_name': collection,
1041
                 'dimension': dim,
1042
                 'index_file_size': 10,
1043
                 'metric_type': metric_type}
1044
        with pytest.raises(Exception) as e:
1045
            status = connect.create_collection(param)
1046
1047
1048
def create_collection(connect, **params):
1049
    param = {'collection_name': params["collection_name"],
1050
             'dimension': params["dimension"],
1051
             'index_file_size': index_file_size,
1052
             'metric_type': MetricType.L2}
1053
    status = connect.create_collection(param)
1054
    return status
1055
1056
def search_collection(connect, **params):
1057
    status, result = connect.search(
1058
        params["collection_name"], 
1059
        params["top_k"], 
1060
        params["query_vectors"],
1061
        params={"nprobe": params["nprobe"]})
1062
    return status
1063
1064
def load_collection(connect, **params):
1065
    status = connect.load_collection(params["collection_name"])
1066
    return status
1067
1068
def has(connect, **params):
1069
    status, result = connect.has_collection(params["collection_name"])
1070
    return status
1071
1072
def show(connect, **params):
1073
    status, result = connect.list_collections()
1074
    return status
1075
1076
def delete(connect, **params):
1077
    status = connect.drop_collection(params["collection_name"])
1078
    return status
1079
1080
def describe(connect, **params):
1081
    status, result = connect.get_collection_info(params["collection_name"])
1082
    return status
1083
1084
def rowcount(connect, **params):
1085
    status, result = connect.count_entities(params["collection_name"])
1086
    return status
1087
1088
def create_index(connect, **params):
1089
    status = connect.create_index(params["collection_name"], params["index_type"], params["index_param"])
1090
    return status
1091
1092
func_map = { 
1093
    # 0:has, 
1094
    1:show,
1095
    10:create_collection, 
1096
    11:describe,
1097
    12:rowcount,
1098
    13:search_collection,
1099
    14:load_collection,
1100
    15:create_index,
1101
    30:delete
1102
}
1103
1104
def gen_sequence():
1105
    raw_seq = func_map.keys()
1106
    result = itertools.permutations(raw_seq)
1107
    for x in result:
1108
        yield x
1109
1110
class TestCollectionLogic(object):
1111
    @pytest.mark.parametrize("logic_seq", gen_sequence())
1112
    @pytest.mark.level(2)
1113
    def test_logic(self, connect, logic_seq, args):
1114
        if args["handler"] == "HTTP":
1115
            pytest.skip("Skip in http mode")
1116
        if self.is_right(logic_seq):
1117
            self.execute(logic_seq, connect)
1118
        else:
1119
            self.execute_with_error(logic_seq, connect)
1120
        self.tear_down(connect)
1121
1122
    def is_right(self, seq):
1123
        if sorted(seq) == seq:
1124
            return True
1125
1126
        not_created = True
1127
        has_deleted = False
1128
        for i in range(len(seq)):
1129
            if seq[i] > 10 and not_created:
1130
                return False
1131
            elif seq [i] > 10 and has_deleted:
1132
                return False
1133
            elif seq[i] == 10:
1134
                not_created = False
1135
            elif seq[i] == 30:
1136
                has_deleted = True
1137
1138
        return True
1139
1140
    def execute(self, logic_seq, connect):
1141
        basic_params = self.gen_params()
1142
        for i in range(len(logic_seq)):
1143
            # logging.getLogger().info(logic_seq[i])
1144
            f = func_map[logic_seq[i]]
1145
            status = f(connect, **basic_params)
1146
            assert status.OK()
1147
1148
    def execute_with_error(self, logic_seq, connect):
1149
        basic_params = self.gen_params()
1150
1151
        error_flag = False
1152
        for i in range(len(logic_seq)):
1153
            f = func_map[logic_seq[i]]
1154
            status = f(connect, **basic_params)
1155
            if not status.OK():
1156
                # logging.getLogger().info(logic_seq[i])
1157
                error_flag = True
1158
                break
1159
        assert error_flag == True
1160
1161
    def tear_down(self, connect):
1162
        names = connect.list_collections()[1]
1163
        for name in names:
1164
            connect.drop_collection(name)
1165
1166
    def gen_params(self):
1167
        collection_name = gen_unique_str("test_collection")
1168
        top_k = 1
1169
        vectors = gen_vectors(2, dim)
1170
        param = {'collection_name': collection_name,
1171
                 'dimension': dim,
1172
                 'metric_type': MetricType.L2,
1173
                 'nprobe': 1,
1174
                 'top_k': top_k,
1175
                 'index_type': IndexType.IVF_SQ8,
1176
                 'index_param': {
1177
                        'nlist': 16384
1178
                 },
1179
                 'query_vectors': vectors}
1180
        return param
1181