@@ -36,10 +36,115 @@ def setUp(self):
3636 self .app .client_manager .volume .cgsnapshots )
3737 self .cgsnapshots_mock .reset_mock ()
3838
39+ self .volumes_mock = (
40+ self .app .client_manager .volume .volumes )
41+ self .volumes_mock .reset_mock ()
42+
3943 self .types_mock = self .app .client_manager .volume .volume_types
4044 self .types_mock .reset_mock ()
4145
4246
47+ class TestConsistencyGroupAddVolume (TestConsistencyGroup ):
48+
49+ _consistency_group = (
50+ volume_fakes .FakeConsistencyGroup .create_one_consistency_group ())
51+
52+ def setUp (self ):
53+ super (TestConsistencyGroupAddVolume , self ).setUp ()
54+
55+ self .consistencygroups_mock .get .return_value = (
56+ self ._consistency_group )
57+ # Get the command object to test
58+ self .cmd = \
59+ consistency_group .AddVolumeToConsistencyGroup (self .app , None )
60+
61+ def test_add_one_volume_to_consistency_group (self ):
62+ volume = volume_fakes .FakeVolume .create_one_volume ()
63+ self .volumes_mock .get .return_value = volume
64+ arglist = [
65+ self ._consistency_group .id ,
66+ volume .id ,
67+ ]
68+ verifylist = [
69+ ('consistency_group' , self ._consistency_group .id ),
70+ ('volumes' , [volume .id ]),
71+ ]
72+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
73+
74+ result = self .cmd .take_action (parsed_args )
75+
76+ # Set expected values
77+ kwargs = {
78+ 'add_volumes' : volume .id ,
79+ }
80+ self .consistencygroups_mock .update .assert_called_once_with (
81+ self ._consistency_group .id ,
82+ ** kwargs
83+ )
84+ self .assertIsNone (result )
85+
86+ def test_add_multiple_volumes_to_consistency_group (self ):
87+ volumes = volume_fakes .FakeVolume .create_volumes (count = 2 )
88+ self .volumes_mock .get = volume_fakes .FakeVolume .get_volumes (volumes )
89+ arglist = [
90+ self ._consistency_group .id ,
91+ volumes [0 ].id ,
92+ volumes [1 ].id ,
93+ ]
94+ verifylist = [
95+ ('consistency_group' , self ._consistency_group .id ),
96+ ('volumes' , [volumes [0 ].id , volumes [1 ].id ]),
97+ ]
98+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
99+
100+ result = self .cmd .take_action (parsed_args )
101+
102+ # Set expected values
103+ kwargs = {
104+ 'add_volumes' : volumes [0 ].id + ',' + volumes [1 ].id ,
105+ }
106+ self .consistencygroups_mock .update .assert_called_once_with (
107+ self ._consistency_group .id ,
108+ ** kwargs
109+ )
110+ self .assertIsNone (result )
111+
112+ @mock .patch .object (consistency_group .LOG , 'error' )
113+ def test_add_multiple_volumes_to_consistency_group_with_exception (
114+ self , mock_error ):
115+ volume = volume_fakes .FakeVolume .create_one_volume ()
116+ arglist = [
117+ self ._consistency_group .id ,
118+ volume .id ,
119+ 'unexist_volume' ,
120+ ]
121+ verifylist = [
122+ ('consistency_group' , self ._consistency_group .id ),
123+ ('volumes' , [volume .id , 'unexist_volume' ]),
124+ ]
125+
126+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
127+
128+ find_mock_result = [volume ,
129+ exceptions .CommandError ,
130+ self ._consistency_group ]
131+ with mock .patch .object (utils , 'find_resource' ,
132+ side_effect = find_mock_result ) as find_mock :
133+ result = self .cmd .take_action (parsed_args )
134+ mock_error .assert_called_with ("1 of 2 volumes failed to add." )
135+ self .assertIsNone (result )
136+ find_mock .assert_any_call (self .consistencygroups_mock ,
137+ self ._consistency_group .id )
138+ find_mock .assert_any_call (self .volumes_mock ,
139+ volume .id )
140+ find_mock .assert_any_call (self .volumes_mock ,
141+ 'unexist_volume' )
142+ self .assertEqual (3 , find_mock .call_count )
143+ self .consistencygroups_mock .update .assert_called_once_with (
144+ self ._consistency_group .id , add_volumes = volume .id
145+ )
146+
147+
43148class TestConsistencyGroupCreate (TestConsistencyGroup ):
44149
45150 volume_type = volume_fakes .FakeType .create_one_type ()
@@ -394,6 +499,107 @@ def test_consistency_group_list_with_long(self):
394499 self .assertEqual (self .data_long , list (data ))
395500
396501
502+ class TestConsistencyGroupRemoveVolume (TestConsistencyGroup ):
503+
504+ _consistency_group = (
505+ volume_fakes .FakeConsistencyGroup .create_one_consistency_group ())
506+
507+ def setUp (self ):
508+ super (TestConsistencyGroupRemoveVolume , self ).setUp ()
509+
510+ self .consistencygroups_mock .get .return_value = (
511+ self ._consistency_group )
512+ # Get the command object to test
513+ self .cmd = \
514+ consistency_group .RemoveVolumeFromConsistencyGroup (self .app , None )
515+
516+ def test_remove_one_volume_from_consistency_group (self ):
517+ volume = volume_fakes .FakeVolume .create_one_volume ()
518+ self .volumes_mock .get .return_value = volume
519+ arglist = [
520+ self ._consistency_group .id ,
521+ volume .id ,
522+ ]
523+ verifylist = [
524+ ('consistency_group' , self ._consistency_group .id ),
525+ ('volumes' , [volume .id ]),
526+ ]
527+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
528+
529+ result = self .cmd .take_action (parsed_args )
530+
531+ # Set expected values
532+ kwargs = {
533+ 'remove_volumes' : volume .id ,
534+ }
535+ self .consistencygroups_mock .update .assert_called_once_with (
536+ self ._consistency_group .id ,
537+ ** kwargs
538+ )
539+ self .assertIsNone (result )
540+
541+ def test_remove_multi_volumes_from_consistency_group (self ):
542+ volumes = volume_fakes .FakeVolume .create_volumes (count = 2 )
543+ self .volumes_mock .get = volume_fakes .FakeVolume .get_volumes (volumes )
544+ arglist = [
545+ self ._consistency_group .id ,
546+ volumes [0 ].id ,
547+ volumes [1 ].id ,
548+ ]
549+ verifylist = [
550+ ('consistency_group' , self ._consistency_group .id ),
551+ ('volumes' , [volumes [0 ].id , volumes [1 ].id ]),
552+ ]
553+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
554+
555+ result = self .cmd .take_action (parsed_args )
556+
557+ # Set expected values
558+ kwargs = {
559+ 'remove_volumes' : volumes [0 ].id + ',' + volumes [1 ].id ,
560+ }
561+ self .consistencygroups_mock .update .assert_called_once_with (
562+ self ._consistency_group .id ,
563+ ** kwargs
564+ )
565+ self .assertIsNone (result )
566+
567+ @mock .patch .object (consistency_group .LOG , 'error' )
568+ def test_remove_multiple_volumes_from_consistency_group_with_exception (
569+ self , mock_error ):
570+ volume = volume_fakes .FakeVolume .create_one_volume ()
571+ arglist = [
572+ self ._consistency_group .id ,
573+ volume .id ,
574+ 'unexist_volume' ,
575+ ]
576+ verifylist = [
577+ ('consistency_group' , self ._consistency_group .id ),
578+ ('volumes' , [volume .id , 'unexist_volume' ]),
579+ ]
580+
581+ parsed_args = self .check_parser (self .cmd , arglist , verifylist )
582+
583+ find_mock_result = [volume ,
584+ exceptions .CommandError ,
585+ self ._consistency_group ]
586+ with mock .patch .object (utils , 'find_resource' ,
587+ side_effect = find_mock_result ) as find_mock :
588+ result = self .cmd .take_action (parsed_args )
589+ mock_error .assert_called_with ("1 of 2 volumes failed to remove." )
590+ self .assertIsNone (result )
591+ find_mock .assert_any_call (self .consistencygroups_mock ,
592+ self ._consistency_group .id )
593+ find_mock .assert_any_call (self .volumes_mock ,
594+ volume .id )
595+ find_mock .assert_any_call (self .volumes_mock ,
596+ 'unexist_volume' )
597+ self .assertEqual (3 , find_mock .call_count )
598+ self .consistencygroups_mock .update .assert_called_once_with (
599+ self ._consistency_group .id , remove_volumes = volume .id
600+ )
601+
602+
397603class TestConsistencyGroupSet (TestConsistencyGroup ):
398604
399605 consistency_group = (
0 commit comments