python-openstackclient 8.0.0__py3-none-any.whl → 8.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. openstackclient/api/compute_v2.py +2 -2
  2. openstackclient/api/volume_v2.py +60 -0
  3. openstackclient/api/volume_v3.py +60 -0
  4. openstackclient/compute/client.py +5 -0
  5. openstackclient/compute/v2/console.py +7 -0
  6. openstackclient/compute/v2/console_connection.py +48 -0
  7. openstackclient/compute/v2/flavor.py +14 -1
  8. openstackclient/compute/v2/keypair.py +10 -3
  9. openstackclient/compute/v2/server.py +76 -13
  10. openstackclient/compute/v2/server_event.py +1 -1
  11. openstackclient/identity/common.py +85 -11
  12. openstackclient/identity/v3/application_credential.py +88 -87
  13. openstackclient/identity/v3/domain.py +67 -49
  14. openstackclient/identity/v3/group.py +113 -68
  15. openstackclient/identity/v3/project.py +42 -20
  16. openstackclient/identity/v3/role.py +7 -2
  17. openstackclient/identity/v3/user.py +38 -5
  18. openstackclient/image/client.py +5 -0
  19. openstackclient/image/v1/image.py +16 -1
  20. openstackclient/image/v2/cache.py +10 -6
  21. openstackclient/image/v2/image.py +59 -12
  22. openstackclient/image/v2/metadef_objects.py +8 -2
  23. openstackclient/image/v2/metadef_properties.py +9 -2
  24. openstackclient/network/client.py +0 -6
  25. openstackclient/network/v2/floating_ip.py +58 -29
  26. openstackclient/network/v2/network_qos_rule.py +3 -11
  27. openstackclient/network/v2/port.py +16 -0
  28. openstackclient/network/v2/router.py +1 -1
  29. openstackclient/network/v2/security_group.py +49 -7
  30. openstackclient/network/v2/security_group_rule.py +18 -1
  31. openstackclient/shell.py +1 -1
  32. openstackclient/tests/functional/base.py +5 -1
  33. openstackclient/tests/functional/compute/v2/test_keypair.py +41 -5
  34. openstackclient/tests/functional/identity/v3/test_access_rule.py +1 -1
  35. openstackclient/tests/functional/identity/v3/test_application_credential.py +7 -7
  36. openstackclient/tests/functional/image/v2/test_image.py +36 -14
  37. openstackclient/tests/functional/volume/v2/test_volume.py +1 -1
  38. openstackclient/tests/functional/volume/v3/test_volume.py +2 -2
  39. openstackclient/tests/unit/api/test_volume_v2.py +124 -0
  40. openstackclient/tests/unit/api/test_volume_v3.py +124 -0
  41. openstackclient/tests/unit/compute/v2/fakes.py +81 -305
  42. openstackclient/tests/unit/compute/v2/test_console.py +18 -1
  43. openstackclient/tests/unit/compute/v2/test_console_connection.py +72 -0
  44. openstackclient/tests/unit/compute/v2/test_flavor.py +160 -175
  45. openstackclient/tests/unit/compute/v2/test_keypair.py +12 -5
  46. openstackclient/tests/unit/compute/v2/test_server.py +211 -97
  47. openstackclient/tests/unit/compute/v2/test_server_backup.py +32 -71
  48. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  49. openstackclient/tests/unit/compute/v2/test_server_image.py +33 -72
  50. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  51. openstackclient/tests/unit/identity/v3/test_application_credential.py +93 -65
  52. openstackclient/tests/unit/identity/v3/test_domain.py +117 -107
  53. openstackclient/tests/unit/identity/v3/test_group.py +353 -202
  54. openstackclient/tests/unit/identity/v3/test_project.py +46 -53
  55. openstackclient/tests/unit/identity/v3/test_role.py +2 -8
  56. openstackclient/tests/unit/identity/v3/test_user.py +86 -6
  57. openstackclient/tests/unit/image/v1/test_image.py +55 -9
  58. openstackclient/tests/unit/image/v2/test_image.py +128 -58
  59. openstackclient/tests/unit/image/v2/test_metadef_objects.py +22 -0
  60. openstackclient/tests/unit/image/v2/test_metadef_properties.py +24 -10
  61. openstackclient/tests/unit/network/v2/fakes.py +406 -485
  62. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +13 -19
  63. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +2 -2
  64. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +3 -5
  65. openstackclient/tests/unit/network/v2/test_network.py +4 -4
  66. openstackclient/tests/unit/network/v2/test_network_agent.py +15 -29
  67. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +16 -19
  68. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +79 -152
  69. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +4 -6
  70. openstackclient/tests/unit/network/v2/test_network_rbac.py +2 -2
  71. openstackclient/tests/unit/network/v2/test_port.py +57 -17
  72. openstackclient/tests/unit/network/v2/test_router.py +73 -57
  73. openstackclient/tests/unit/network/v2/test_security_group_network.py +31 -27
  74. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +1 -3
  75. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +82 -39
  76. openstackclient/tests/unit/volume/v2/fakes.py +1 -2
  77. openstackclient/tests/unit/volume/v2/test_service.py +57 -91
  78. openstackclient/tests/unit/volume/v2/test_volume.py +466 -410
  79. openstackclient/tests/unit/volume/v2/test_volume_backup.py +141 -148
  80. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +293 -283
  81. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +61 -71
  82. openstackclient/tests/unit/volume/v3/test_service.py +221 -141
  83. openstackclient/tests/unit/volume/v3/test_volume.py +569 -534
  84. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  85. openstackclient/tests/unit/volume/v3/test_volume_backup.py +198 -203
  86. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +682 -47
  87. openstackclient/volume/v2/service.py +41 -38
  88. openstackclient/volume/v2/volume.py +140 -88
  89. openstackclient/volume/v2/volume_backup.py +9 -3
  90. openstackclient/volume/v2/volume_snapshot.py +121 -84
  91. openstackclient/volume/v3/block_storage_log_level.py +22 -28
  92. openstackclient/volume/v3/service.py +105 -14
  93. openstackclient/volume/v3/volume.py +287 -99
  94. openstackclient/volume/v3/volume_backup.py +24 -19
  95. openstackclient/volume/v3/volume_group.py +1 -1
  96. openstackclient/volume/v3/volume_snapshot.py +485 -10
  97. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/AUTHORS +13 -0
  98. python_openstackclient-8.2.0.dist-info/METADATA +264 -0
  99. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/RECORD +104 -98
  100. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/entry_points.txt +7 -6
  101. python_openstackclient-8.2.0.dist-info/pbr.json +1 -0
  102. python_openstackclient-8.0.0.dist-info/METADATA +0 -166
  103. python_openstackclient-8.0.0.dist-info/pbr.json +0 -1
  104. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/LICENSE +0 -0
  105. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/WHEEL +0 -0
  106. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.2.0.dist-info}/top_level.txt +0 -0
@@ -12,11 +12,17 @@
12
12
  # under the License.
13
13
 
14
14
  from unittest import mock
15
+ import uuid
15
16
 
17
+ from openstack.block_storage.v2 import snapshot as _snapshot
18
+ from openstack.block_storage.v2 import volume as _volume
19
+ from openstack import exceptions as sdk_exceptions
20
+ from openstack.test import fakes as sdk_fakes
16
21
  from osc_lib.cli import format_columns
17
22
  from osc_lib import exceptions
18
23
  from osc_lib import utils
19
24
 
25
+ from openstackclient.api import volume_v2
20
26
  from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
21
27
  from openstackclient.tests.unit.image.v2 import fakes as image_fakes
22
28
  from openstackclient.tests.unit import utils as test_utils
@@ -46,136 +52,157 @@ class TestVolume(volume_fakes.TestVolume):
46
52
  self.consistencygroups_mock = self.volume_client.consistencygroups
47
53
  self.consistencygroups_mock.reset_mock()
48
54
 
49
- def setup_volumes_mock(self, count):
50
- volumes = volume_fakes.create_volumes(count=count)
51
-
52
- self.volumes_mock.get = volume_fakes.get_volumes(volumes, 0)
53
- return volumes
54
-
55
-
56
- class TestVolumeCreate(TestVolume):
57
- project = identity_fakes.FakeProject.create_one_project()
58
- user = identity_fakes.FakeUser.create_one_user()
59
55
 
56
+ class TestVolumeCreate(volume_fakes.TestVolume):
60
57
  columns = (
61
58
  'attachments',
62
59
  'availability_zone',
63
60
  'bootable',
61
+ 'consistencygroup_id',
62
+ 'created_at',
64
63
  'description',
64
+ 'encrypted',
65
65
  'id',
66
+ 'multiattach',
66
67
  'name',
68
+ 'os-vol-host-attr:host',
69
+ 'os-vol-mig-status-attr:migstat',
70
+ 'os-vol-mig-status-attr:name_id',
71
+ 'os-vol-tenant-attr:tenant_id',
72
+ 'os-volume-replication:driver_data',
73
+ 'os-volume-replication:extended_status',
67
74
  'properties',
75
+ 'replication_status',
68
76
  'size',
69
77
  'snapshot_id',
78
+ 'source_volid',
70
79
  'status',
71
80
  'type',
81
+ 'updated_at',
82
+ 'user_id',
83
+ 'volume_image_metadata',
72
84
  )
73
85
 
74
86
  def setUp(self):
75
87
  super().setUp()
76
88
 
77
- self.new_volume = volume_fakes.create_one_volume()
78
- self.volumes_mock.create.return_value = self.new_volume
89
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
90
+ self.volume_sdk_client.create_volume.return_value = self.volume
79
91
 
80
92
  self.datalist = (
81
- self.new_volume.attachments,
82
- self.new_volume.availability_zone,
83
- self.new_volume.bootable,
84
- self.new_volume.description,
85
- self.new_volume.id,
86
- self.new_volume.name,
87
- format_columns.DictColumn(self.new_volume.metadata),
88
- self.new_volume.size,
89
- self.new_volume.snapshot_id,
90
- self.new_volume.status,
91
- self.new_volume.volume_type,
93
+ self.volume.attachments,
94
+ self.volume.availability_zone,
95
+ self.volume.is_bootable,
96
+ self.volume.consistency_group_id,
97
+ self.volume.created_at,
98
+ self.volume.description,
99
+ self.volume.is_encrypted,
100
+ self.volume.id,
101
+ self.volume.is_multiattach,
102
+ self.volume.name,
103
+ self.volume.host,
104
+ self.volume.migration_status,
105
+ self.volume.migration_id,
106
+ self.volume.project_id,
107
+ self.volume.replication_driver_data,
108
+ self.volume.extended_replication_status,
109
+ format_columns.DictColumn(self.volume.metadata),
110
+ self.volume.replication_status,
111
+ self.volume.size,
112
+ self.volume.snapshot_id,
113
+ self.volume.source_volume_id,
114
+ self.volume.status,
115
+ self.volume.volume_type,
116
+ self.volume.updated_at,
117
+ self.volume.user_id,
118
+ self.volume.volume_image_metadata,
92
119
  )
93
-
94
120
  # Get the command object to test
95
121
  self.cmd = volume.CreateVolume(self.app, None)
96
122
 
97
123
  def test_volume_create_min_options(self):
98
124
  arglist = [
99
125
  '--size',
100
- str(self.new_volume.size),
126
+ str(self.volume.size),
101
127
  ]
102
128
  verifylist = [
103
- ('size', self.new_volume.size),
129
+ ('size', self.volume.size),
104
130
  ]
105
131
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
106
132
 
107
- # In base command class ShowOne in cliff, abstract method take_action()
108
- # returns a two-part tuple with a tuple of column names and a tuple of
109
- # data to be shown.
110
133
  columns, data = self.cmd.take_action(parsed_args)
111
134
 
112
- self.volumes_mock.create.assert_called_with(
113
- size=self.new_volume.size,
135
+ self.volume_sdk_client.create_volume.assert_called_with(
136
+ size=self.volume.size,
114
137
  snapshot_id=None,
115
138
  name=None,
116
139
  description=None,
117
140
  volume_type=None,
118
141
  availability_zone=None,
119
142
  metadata=None,
120
- imageRef=None,
121
- source_volid=None,
122
- consistencygroup_id=None,
143
+ image_id=None,
144
+ source_volume_id=None,
145
+ consistency_group_id=None,
123
146
  scheduler_hints=None,
124
147
  )
125
148
 
126
149
  self.assertEqual(self.columns, columns)
127
- self.assertCountEqual(self.datalist, data)
150
+ self.assertEqual(self.datalist, data)
128
151
 
129
152
  def test_volume_create_options(self):
130
- consistency_group = volume_fakes.create_one_consistency_group()
131
- self.consistencygroups_mock.get.return_value = consistency_group
153
+ consistency_group_id = 'cg123'
132
154
  arglist = [
133
155
  '--size',
134
- str(self.new_volume.size),
156
+ str(self.volume.size),
135
157
  '--description',
136
- self.new_volume.description,
158
+ self.volume.description,
137
159
  '--type',
138
- self.new_volume.volume_type,
160
+ self.volume.volume_type,
139
161
  '--availability-zone',
140
- self.new_volume.availability_zone,
162
+ self.volume.availability_zone,
141
163
  '--consistency-group',
142
- consistency_group.id,
164
+ consistency_group_id,
143
165
  '--hint',
144
166
  'k=v',
145
- self.new_volume.name,
167
+ self.volume.name,
146
168
  ]
147
169
  verifylist = [
148
- ('size', self.new_volume.size),
149
- ('description', self.new_volume.description),
150
- ('type', self.new_volume.volume_type),
151
- ('availability_zone', self.new_volume.availability_zone),
152
- ('consistency_group', consistency_group.id),
170
+ ('size', self.volume.size),
171
+ ('description', self.volume.description),
172
+ ('type', self.volume.volume_type),
173
+ ('availability_zone', self.volume.availability_zone),
174
+ ('consistency_group', consistency_group_id),
153
175
  ('hint', {'k': 'v'}),
154
- ('name', self.new_volume.name),
176
+ ('name', self.volume.name),
155
177
  ]
156
178
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
157
179
 
158
- # In base command class ShowOne in cliff, abstract method take_action()
159
- # returns a two-part tuple with a tuple of column names and a tuple of
160
- # data to be shown.
161
- columns, data = self.cmd.take_action(parsed_args)
162
-
163
- self.volumes_mock.create.assert_called_with(
164
- size=self.new_volume.size,
180
+ with mock.patch.object(
181
+ volume_v2,
182
+ 'find_consistency_group',
183
+ return_value={'id': consistency_group_id},
184
+ ) as mock_find_cg:
185
+ columns, data = self.cmd.take_action(parsed_args)
186
+
187
+ self.volume_sdk_client.create_volume.assert_called_with(
188
+ size=self.volume.size,
165
189
  snapshot_id=None,
166
- name=self.new_volume.name,
167
- description=self.new_volume.description,
168
- volume_type=self.new_volume.volume_type,
169
- availability_zone=self.new_volume.availability_zone,
190
+ name=self.volume.name,
191
+ description=self.volume.description,
192
+ volume_type=self.volume.volume_type,
193
+ availability_zone=self.volume.availability_zone,
170
194
  metadata=None,
171
- imageRef=None,
172
- source_volid=None,
173
- consistencygroup_id=consistency_group.id,
195
+ image_id=None,
196
+ source_volume_id=None,
197
+ consistency_group_id=consistency_group_id,
174
198
  scheduler_hints={'k': 'v'},
175
199
  )
200
+ mock_find_cg.assert_called_once_with(
201
+ self.volume_sdk_client, consistency_group_id
202
+ )
176
203
 
177
204
  self.assertEqual(self.columns, columns)
178
- self.assertCountEqual(self.datalist, data)
205
+ self.assertEqual(self.datalist, data)
179
206
 
180
207
  def test_volume_create_properties(self):
181
208
  arglist = [
@@ -184,39 +211,36 @@ class TestVolumeCreate(TestVolume):
184
211
  '--property',
185
212
  'Beta=b',
186
213
  '--size',
187
- str(self.new_volume.size),
188
- self.new_volume.name,
214
+ str(self.volume.size),
215
+ self.volume.name,
189
216
  ]
190
217
  verifylist = [
191
- ('property', {'Alpha': 'a', 'Beta': 'b'}),
192
- ('size', self.new_volume.size),
193
- ('name', self.new_volume.name),
218
+ ('properties', {'Alpha': 'a', 'Beta': 'b'}),
219
+ ('size', self.volume.size),
220
+ ('name', self.volume.name),
194
221
  ]
195
222
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
196
223
 
197
- # In base command class ShowOne in cliff, abstract method take_action()
198
- # returns a two-part tuple with a tuple of column names and a tuple of
199
- # data to be shown.
200
224
  columns, data = self.cmd.take_action(parsed_args)
201
225
 
202
- self.volumes_mock.create.assert_called_with(
203
- size=self.new_volume.size,
226
+ self.volume_sdk_client.create_volume.assert_called_with(
227
+ size=self.volume.size,
204
228
  snapshot_id=None,
205
- name=self.new_volume.name,
229
+ name=self.volume.name,
206
230
  description=None,
207
231
  volume_type=None,
208
232
  availability_zone=None,
209
233
  metadata={'Alpha': 'a', 'Beta': 'b'},
210
- imageRef=None,
211
- source_volid=None,
212
- consistencygroup_id=None,
234
+ image_id=None,
235
+ source_volume_id=None,
236
+ consistency_group_id=None,
213
237
  scheduler_hints=None,
214
238
  )
215
239
 
216
240
  self.assertEqual(self.columns, columns)
217
- self.assertCountEqual(self.datalist, data)
241
+ self.assertEqual(self.datalist, data)
218
242
 
219
- def test_volume_create_image_id(self):
243
+ def test_volume_create_image(self):
220
244
  image = image_fakes.create_one_image()
221
245
  self.image_client.find_image.return_value = image
222
246
 
@@ -224,152 +248,111 @@ class TestVolumeCreate(TestVolume):
224
248
  '--image',
225
249
  image.id,
226
250
  '--size',
227
- str(self.new_volume.size),
228
- self.new_volume.name,
251
+ str(self.volume.size),
252
+ self.volume.name,
229
253
  ]
230
254
  verifylist = [
231
255
  ('image', image.id),
232
- ('size', self.new_volume.size),
233
- ('name', self.new_volume.name),
256
+ ('size', self.volume.size),
257
+ ('name', self.volume.name),
234
258
  ]
235
259
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
236
260
 
237
- # In base command class ShowOne in cliff, abstract method take_action()
238
- # returns a two-part tuple with a tuple of column names and a tuple of
239
- # data to be shown.
240
261
  columns, data = self.cmd.take_action(parsed_args)
241
262
 
242
- self.volumes_mock.create.assert_called_with(
243
- size=self.new_volume.size,
263
+ self.volume_sdk_client.create_volume.assert_called_with(
264
+ size=self.volume.size,
244
265
  snapshot_id=None,
245
- name=self.new_volume.name,
266
+ name=self.volume.name,
246
267
  description=None,
247
268
  volume_type=None,
248
269
  availability_zone=None,
249
270
  metadata=None,
250
- imageRef=image.id,
251
- source_volid=None,
252
- consistencygroup_id=None,
271
+ image_id=image.id,
272
+ source_volume_id=None,
273
+ consistency_group_id=None,
253
274
  scheduler_hints=None,
254
275
  )
255
-
256
- self.assertEqual(self.columns, columns)
257
- self.assertCountEqual(self.datalist, data)
258
-
259
- def test_volume_create_image_name(self):
260
- image = image_fakes.create_one_image()
261
- self.image_client.find_image.return_value = image
262
-
263
- arglist = [
264
- '--image',
265
- image.name,
266
- '--size',
267
- str(self.new_volume.size),
268
- self.new_volume.name,
269
- ]
270
- verifylist = [
271
- ('image', image.name),
272
- ('size', self.new_volume.size),
273
- ('name', self.new_volume.name),
274
- ]
275
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
276
-
277
- # In base command class ShowOne in cliff, abstract method take_action()
278
- # returns a two-part tuple with a tuple of column names and a tuple of
279
- # data to be shown.
280
- columns, data = self.cmd.take_action(parsed_args)
281
-
282
- self.volumes_mock.create.assert_called_with(
283
- size=self.new_volume.size,
284
- snapshot_id=None,
285
- name=self.new_volume.name,
286
- description=None,
287
- volume_type=None,
288
- availability_zone=None,
289
- metadata=None,
290
- imageRef=image.id,
291
- source_volid=None,
292
- consistencygroup_id=None,
293
- scheduler_hints=None,
276
+ self.image_client.find_image.assert_called_once_with(
277
+ image.id, ignore_missing=False
294
278
  )
295
279
 
296
280
  self.assertEqual(self.columns, columns)
297
- self.assertCountEqual(self.datalist, data)
281
+ self.assertEqual(self.datalist, data)
298
282
 
299
283
  def test_volume_create_with_snapshot(self):
300
- snapshot = volume_fakes.create_one_snapshot()
301
- self.new_volume.snapshot_id = snapshot.id
284
+ snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
285
+ self.volume_sdk_client.find_snapshot.return_value = snapshot
286
+
302
287
  arglist = [
303
288
  '--snapshot',
304
- self.new_volume.snapshot_id,
305
- self.new_volume.name,
289
+ snapshot.id,
290
+ self.volume.name,
306
291
  ]
307
292
  verifylist = [
308
- ('snapshot', self.new_volume.snapshot_id),
309
- ('name', self.new_volume.name),
293
+ ('snapshot', snapshot.id),
294
+ ('name', self.volume.name),
310
295
  ]
311
296
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
312
297
 
313
- self.snapshots_mock.get.return_value = snapshot
314
-
315
- # In base command class ShowOne in cliff, abstract method take_action()
316
- # returns a two-part tuple with a tuple of column names and a tuple of
317
- # data to be shown.
318
298
  columns, data = self.cmd.take_action(parsed_args)
319
299
 
320
- self.volumes_mock.create.assert_called_once_with(
300
+ self.volume_sdk_client.create_volume.assert_called_with(
321
301
  size=snapshot.size,
322
302
  snapshot_id=snapshot.id,
323
- name=self.new_volume.name,
303
+ name=self.volume.name,
324
304
  description=None,
325
305
  volume_type=None,
326
306
  availability_zone=None,
327
307
  metadata=None,
328
- imageRef=None,
329
- source_volid=None,
330
- consistencygroup_id=None,
308
+ image_id=None,
309
+ source_volume_id=None,
310
+ consistency_group_id=None,
331
311
  scheduler_hints=None,
332
312
  )
313
+ self.volume_sdk_client.find_snapshot.assert_called_once_with(
314
+ snapshot.id, ignore_missing=False
315
+ )
333
316
 
334
317
  self.assertEqual(self.columns, columns)
335
- self.assertCountEqual(self.datalist, data)
318
+ self.assertEqual(self.datalist, data)
336
319
 
337
320
  def test_volume_create_with_source_volume(self):
338
- source_vol = "source_vol"
321
+ source_volume = sdk_fakes.generate_fake_resource(_volume.Volume)
322
+ self.volume_sdk_client.find_volume.return_value = source_volume
323
+
339
324
  arglist = [
340
325
  '--source',
341
- self.new_volume.id,
342
- source_vol,
326
+ source_volume.id,
327
+ self.volume.name,
343
328
  ]
344
329
  verifylist = [
345
- ('source', self.new_volume.id),
346
- ('name', source_vol),
330
+ ('source', source_volume.id),
331
+ ('name', self.volume.name),
347
332
  ]
348
333
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
349
334
 
350
- self.volumes_mock.get.return_value = self.new_volume
351
-
352
- # In base command class ShowOne in cliff, abstract method take_action()
353
- # returns a two-part tuple with a tuple of column names and a tuple of
354
- # data to be shown.
355
335
  columns, data = self.cmd.take_action(parsed_args)
356
336
 
357
- self.volumes_mock.create.assert_called_once_with(
358
- size=self.new_volume.size,
337
+ self.volume_sdk_client.create_volume.assert_called_with(
338
+ size=source_volume.size,
359
339
  snapshot_id=None,
360
- name=source_vol,
340
+ name=self.volume.name,
361
341
  description=None,
362
342
  volume_type=None,
363
343
  availability_zone=None,
364
344
  metadata=None,
365
- imageRef=None,
366
- source_volid=self.new_volume.id,
367
- consistencygroup_id=None,
345
+ image_id=None,
346
+ source_volume_id=source_volume.id,
347
+ consistency_group_id=None,
368
348
  scheduler_hints=None,
369
349
  )
350
+ self.volume_sdk_client.find_volume.assert_called_once_with(
351
+ source_volume.id, ignore_missing=False
352
+ )
370
353
 
371
354
  self.assertEqual(self.columns, columns)
372
- self.assertCountEqual(self.datalist, data)
355
+ self.assertEqual(self.datalist, data)
373
356
 
374
357
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
375
358
  def test_volume_create_with_bootable_and_readonly(self, mock_wait):
@@ -377,196 +360,187 @@ class TestVolumeCreate(TestVolume):
377
360
  '--bootable',
378
361
  '--read-only',
379
362
  '--size',
380
- str(self.new_volume.size),
381
- self.new_volume.name,
363
+ str(self.volume.size),
364
+ self.volume.name,
382
365
  ]
383
366
  verifylist = [
384
367
  ('bootable', True),
385
- ('non_bootable', False),
386
368
  ('read_only', True),
387
- ('read_write', False),
388
- ('size', self.new_volume.size),
389
- ('name', self.new_volume.name),
369
+ ('size', self.volume.size),
370
+ ('name', self.volume.name),
390
371
  ]
391
372
 
392
373
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
393
374
 
394
375
  columns, data = self.cmd.take_action(parsed_args)
395
376
 
396
- self.volumes_mock.create.assert_called_with(
397
- size=self.new_volume.size,
377
+ self.volume_sdk_client.create_volume.assert_called_with(
378
+ size=self.volume.size,
398
379
  snapshot_id=None,
399
- name=self.new_volume.name,
380
+ name=self.volume.name,
400
381
  description=None,
401
382
  volume_type=None,
402
383
  availability_zone=None,
403
384
  metadata=None,
404
- imageRef=None,
405
- source_volid=None,
406
- consistencygroup_id=None,
385
+ image_id=None,
386
+ source_volume_id=None,
387
+ consistency_group_id=None,
407
388
  scheduler_hints=None,
408
389
  )
409
-
410
- self.assertEqual(self.columns, columns)
411
- self.assertCountEqual(self.datalist, data)
412
- self.volumes_mock.set_bootable.assert_called_with(
413
- self.new_volume.id, True
390
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
391
+ self.volume, True
414
392
  )
415
- self.volumes_mock.update_readonly_flag.assert_called_with(
416
- self.new_volume.id, True
393
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
394
+ self.volume, True
417
395
  )
418
396
 
397
+ self.assertEqual(self.columns, columns)
398
+ self.assertEqual(self.datalist, data)
399
+
419
400
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
420
401
  def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
421
402
  arglist = [
422
403
  '--non-bootable',
423
404
  '--read-write',
424
405
  '--size',
425
- str(self.new_volume.size),
426
- self.new_volume.name,
406
+ str(self.volume.size),
407
+ self.volume.name,
427
408
  ]
428
409
  verifylist = [
429
410
  ('bootable', False),
430
- ('non_bootable', True),
431
411
  ('read_only', False),
432
- ('read_write', True),
433
- ('size', self.new_volume.size),
434
- ('name', self.new_volume.name),
412
+ ('size', self.volume.size),
413
+ ('name', self.volume.name),
435
414
  ]
436
415
 
437
416
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
438
417
 
439
418
  columns, data = self.cmd.take_action(parsed_args)
440
419
 
441
- self.volumes_mock.create.assert_called_with(
442
- size=self.new_volume.size,
420
+ self.volume_sdk_client.create_volume.assert_called_with(
421
+ size=self.volume.size,
443
422
  snapshot_id=None,
444
- name=self.new_volume.name,
423
+ name=self.volume.name,
445
424
  description=None,
446
425
  volume_type=None,
447
426
  availability_zone=None,
448
427
  metadata=None,
449
- imageRef=None,
450
- source_volid=None,
451
- consistencygroup_id=None,
428
+ image_id=None,
429
+ source_volume_id=None,
430
+ consistency_group_id=None,
452
431
  scheduler_hints=None,
453
432
  )
454
-
455
- self.assertEqual(self.columns, columns)
456
- self.assertCountEqual(self.datalist, data)
457
- self.volumes_mock.set_bootable.assert_called_with(
458
- self.new_volume.id, False
433
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
434
+ self.volume, False
459
435
  )
460
- self.volumes_mock.update_readonly_flag.assert_called_with(
461
- self.new_volume.id, False
436
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
437
+ self.volume, False
462
438
  )
463
439
 
440
+ self.assertEqual(self.columns, columns)
441
+ self.assertEqual(self.datalist, data)
442
+
464
443
  @mock.patch.object(volume.LOG, 'error')
465
444
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
466
445
  def test_volume_create_with_bootable_and_readonly_fail(
467
446
  self, mock_wait, mock_error
468
447
  ):
469
- self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
470
-
471
- self.volumes_mock.update_readonly_flag.side_effect = (
472
- exceptions.CommandError()
448
+ self.volume_sdk_client.set_volume_bootable_status.side_effect = (
449
+ sdk_exceptions.NotFoundException('foo')
450
+ )
451
+ self.volume_sdk_client.set_volume_readonly.side_effect = (
452
+ sdk_exceptions.NotFoundException('foo')
473
453
  )
474
454
 
475
455
  arglist = [
476
456
  '--bootable',
477
457
  '--read-only',
478
458
  '--size',
479
- str(self.new_volume.size),
480
- self.new_volume.name,
459
+ str(self.volume.size),
460
+ self.volume.name,
481
461
  ]
482
462
  verifylist = [
483
463
  ('bootable', True),
484
- ('non_bootable', False),
485
464
  ('read_only', True),
486
- ('read_write', False),
487
- ('size', self.new_volume.size),
488
- ('name', self.new_volume.name),
465
+ ('size', self.volume.size),
466
+ ('name', self.volume.name),
489
467
  ]
490
468
 
491
469
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
492
470
 
493
471
  columns, data = self.cmd.take_action(parsed_args)
494
472
 
495
- self.volumes_mock.create.assert_called_with(
496
- size=self.new_volume.size,
473
+ self.volume_sdk_client.create_volume.assert_called_with(
474
+ size=self.volume.size,
497
475
  snapshot_id=None,
498
- name=self.new_volume.name,
476
+ name=self.volume.name,
499
477
  description=None,
500
478
  volume_type=None,
501
479
  availability_zone=None,
502
480
  metadata=None,
503
- imageRef=None,
504
- source_volid=None,
505
- consistencygroup_id=None,
481
+ image_id=None,
482
+ source_volume_id=None,
483
+ consistency_group_id=None,
506
484
  scheduler_hints=None,
507
485
  )
486
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
487
+ self.volume, True
488
+ )
489
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
490
+ self.volume, True
491
+ )
508
492
 
509
493
  self.assertEqual(2, mock_error.call_count)
510
494
  self.assertEqual(self.columns, columns)
511
- self.assertCountEqual(self.datalist, data)
512
- self.volumes_mock.set_bootable.assert_called_with(
513
- self.new_volume.id, True
514
- )
515
- self.volumes_mock.update_readonly_flag.assert_called_with(
516
- self.new_volume.id, True
517
- )
495
+ self.assertEqual(self.datalist, data)
518
496
 
519
497
  @mock.patch.object(volume.LOG, 'error')
520
498
  @mock.patch.object(utils, 'wait_for_status', return_value=False)
521
499
  def test_volume_create_non_available_with_readonly(
522
- self,
523
- mock_wait,
524
- mock_error,
500
+ self, mock_wait, mock_error
525
501
  ):
526
502
  arglist = [
527
503
  '--non-bootable',
528
504
  '--read-only',
529
505
  '--size',
530
- str(self.new_volume.size),
531
- self.new_volume.name,
506
+ str(self.volume.size),
507
+ self.volume.name,
532
508
  ]
533
509
  verifylist = [
534
510
  ('bootable', False),
535
- ('non_bootable', True),
536
511
  ('read_only', True),
537
- ('read_write', False),
538
- ('size', self.new_volume.size),
539
- ('name', self.new_volume.name),
512
+ ('size', self.volume.size),
513
+ ('name', self.volume.name),
540
514
  ]
541
515
 
542
516
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
543
517
 
544
518
  columns, data = self.cmd.take_action(parsed_args)
545
519
 
546
- self.volumes_mock.create.assert_called_with(
547
- size=self.new_volume.size,
520
+ self.volume_sdk_client.create_volume.assert_called_with(
521
+ size=self.volume.size,
548
522
  snapshot_id=None,
549
- name=self.new_volume.name,
523
+ name=self.volume.name,
550
524
  description=None,
551
525
  volume_type=None,
552
526
  availability_zone=None,
553
527
  metadata=None,
554
- imageRef=None,
555
- source_volid=None,
556
- consistencygroup_id=None,
528
+ image_id=None,
529
+ source_volume_id=None,
530
+ consistency_group_id=None,
557
531
  scheduler_hints=None,
558
532
  )
559
533
 
560
534
  self.assertEqual(2, mock_error.call_count)
561
535
  self.assertEqual(self.columns, columns)
562
- self.assertCountEqual(self.datalist, data)
536
+ self.assertEqual(self.datalist, data)
563
537
 
564
538
  def test_volume_create_without_size(self):
565
539
  arglist = [
566
- self.new_volume.name,
540
+ self.volume.name,
567
541
  ]
568
542
  verifylist = [
569
- ('name', self.new_volume.name),
543
+ ('name', self.volume.name),
570
544
  ]
571
545
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
572
546
 
@@ -583,15 +557,15 @@ class TestVolumeCreate(TestVolume):
583
557
  '--snapshot',
584
558
  'source_snapshot',
585
559
  '--size',
586
- str(self.new_volume.size),
587
- self.new_volume.name,
560
+ str(self.volume.size),
561
+ self.volume.name,
588
562
  ]
589
563
  verifylist = [
590
564
  ('image', 'source_image'),
591
565
  ('source', 'source_volume'),
592
566
  ('snapshot', 'source_snapshot'),
593
- ('size', self.new_volume.size),
594
- ('name', self.new_volume.name),
567
+ ('size', self.volume.size),
568
+ ('name', self.volume.name),
595
569
  ]
596
570
 
597
571
  self.assertRaises(
@@ -610,7 +584,7 @@ class TestVolumeCreate(TestVolume):
610
584
  """
611
585
  arglist = [
612
586
  '--size',
613
- str(self.new_volume.size),
587
+ str(self.volume.size),
614
588
  '--hint',
615
589
  'k=v',
616
590
  '--hint',
@@ -625,10 +599,10 @@ class TestVolumeCreate(TestVolume):
625
599
  'local_to_instance=v6',
626
600
  '--hint',
627
601
  'different_host=v7',
628
- self.new_volume.name,
602
+ self.volume.name,
629
603
  ]
630
604
  verifylist = [
631
- ('size', self.new_volume.size),
605
+ ('size', self.volume.size),
632
606
  (
633
607
  'hint',
634
608
  {
@@ -638,26 +612,23 @@ class TestVolumeCreate(TestVolume):
638
612
  'different_host': ['v5', 'v7'],
639
613
  },
640
614
  ),
641
- ('name', self.new_volume.name),
615
+ ('name', self.volume.name),
642
616
  ]
643
617
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
644
618
 
645
- # In base command class ShowOne in cliff, abstract method take_action()
646
- # returns a two-part tuple with a tuple of column names and a tuple of
647
- # data to be shown.
648
619
  columns, data = self.cmd.take_action(parsed_args)
649
620
 
650
- self.volumes_mock.create.assert_called_with(
651
- size=self.new_volume.size,
621
+ self.volume_sdk_client.create_volume.assert_called_with(
622
+ size=self.volume.size,
652
623
  snapshot_id=None,
653
- name=self.new_volume.name,
624
+ name=self.volume.name,
654
625
  description=None,
655
626
  volume_type=None,
656
627
  availability_zone=None,
657
628
  metadata=None,
658
- imageRef=None,
659
- source_volid=None,
660
- consistencygroup_id=None,
629
+ image_id=None,
630
+ source_volume_id=None,
631
+ consistency_group_id=None,
661
632
  scheduler_hints={
662
633
  'k': 'v2',
663
634
  'same_host': ['v3', 'v4'],
@@ -667,40 +638,40 @@ class TestVolumeCreate(TestVolume):
667
638
  )
668
639
 
669
640
  self.assertEqual(self.columns, columns)
670
- self.assertCountEqual(self.datalist, data)
641
+ self.assertEqual(self.datalist, data)
671
642
 
672
643
 
673
- class TestVolumeDelete(TestVolume):
644
+ class TestVolumeDelete(volume_fakes.TestVolume):
674
645
  def setUp(self):
675
646
  super().setUp()
676
647
 
677
- self.volumes_mock.delete.return_value = None
648
+ self.volumes = list(sdk_fakes.generate_fake_resources(_volume.Volume))
649
+ self.volume_sdk_client.find_volume.side_effect = self.volumes
650
+ self.volume_sdk_client.delete_volume.return_value = None
678
651
 
679
- # Get the command object to mock
680
652
  self.cmd = volume.DeleteVolume(self.app, None)
681
653
 
682
654
  def test_volume_delete_one_volume(self):
683
- volumes = self.setup_volumes_mock(count=1)
684
-
685
- arglist = [volumes[0].id]
655
+ arglist = [self.volumes[0].id]
686
656
  verifylist = [
687
657
  ("force", False),
688
658
  ("purge", False),
689
- ("volumes", [volumes[0].id]),
659
+ ("volumes", [self.volumes[0].id]),
690
660
  ]
691
661
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
692
662
 
693
663
  result = self.cmd.take_action(parsed_args)
664
+ self.assertIsNone(result)
694
665
 
695
- self.volumes_mock.delete.assert_called_once_with(
696
- volumes[0].id, cascade=False
666
+ self.volume_sdk_client.find_volume.assert_called_once_with(
667
+ self.volumes[0].id, ignore_missing=False
668
+ )
669
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
670
+ self.volumes[0].id, cascade=False, force=False
697
671
  )
698
- self.assertIsNone(result)
699
672
 
700
673
  def test_volume_delete_multi_volumes(self):
701
- volumes = self.setup_volumes_mock(count=3)
702
-
703
- arglist = [v.id for v in volumes]
674
+ arglist = [v.id for v in self.volumes]
704
675
  verifylist = [
705
676
  ('force', False),
706
677
  ('purge', False),
@@ -709,83 +680,95 @@ class TestVolumeDelete(TestVolume):
709
680
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
710
681
 
711
682
  result = self.cmd.take_action(parsed_args)
712
-
713
- calls = [mock.call(v.id, cascade=False) for v in volumes]
714
- self.volumes_mock.delete.assert_has_calls(calls)
715
683
  self.assertIsNone(result)
716
684
 
685
+ self.volume_sdk_client.find_volume.assert_has_calls(
686
+ [mock.call(v.id, ignore_missing=False) for v in self.volumes]
687
+ )
688
+ self.volume_sdk_client.delete_volume.assert_has_calls(
689
+ [mock.call(v.id, cascade=False, force=False) for v in self.volumes]
690
+ )
691
+
717
692
  def test_volume_delete_multi_volumes_with_exception(self):
718
- volumes = self.setup_volumes_mock(count=2)
693
+ self.volume_sdk_client.find_volume.side_effect = [
694
+ self.volumes[0],
695
+ sdk_exceptions.NotFoundException(),
696
+ ]
719
697
 
720
698
  arglist = [
721
- volumes[0].id,
699
+ self.volumes[0].id,
722
700
  'unexist_volume',
723
701
  ]
724
702
  verifylist = [
725
703
  ('force', False),
726
704
  ('purge', False),
727
- ('volumes', arglist),
705
+ ('volumes', [self.volumes[0].id, 'unexist_volume']),
728
706
  ]
729
707
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
730
708
 
731
- find_mock_result = [volumes[0], exceptions.CommandError]
732
- with mock.patch.object(
733
- utils, 'find_resource', side_effect=find_mock_result
734
- ) as find_mock:
735
- try:
736
- self.cmd.take_action(parsed_args)
737
- self.fail('CommandError should be raised.')
738
- except exceptions.CommandError as e:
739
- self.assertEqual('1 of 2 volumes failed to delete.', str(e))
740
-
741
- find_mock.assert_any_call(self.volumes_mock, volumes[0].id)
742
- find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
743
-
744
- self.assertEqual(2, find_mock.call_count)
745
- self.volumes_mock.delete.assert_called_once_with(
746
- volumes[0].id, cascade=False
747
- )
709
+ exc = self.assertRaises(
710
+ exceptions.CommandError,
711
+ self.cmd.take_action,
712
+ parsed_args,
713
+ )
714
+ self.assertEqual('1 of 2 volumes failed to delete.', str(exc))
748
715
 
749
- def test_volume_delete_with_purge(self):
750
- volumes = self.setup_volumes_mock(count=1)
716
+ self.volume_sdk_client.find_volume.assert_has_calls(
717
+ [
718
+ mock.call(self.volumes[0].id, ignore_missing=False),
719
+ mock.call('unexist_volume', ignore_missing=False),
720
+ ]
721
+ )
722
+ self.volume_sdk_client.delete_volume.assert_has_calls(
723
+ [
724
+ mock.call(self.volumes[0].id, cascade=False, force=False),
725
+ ]
726
+ )
751
727
 
728
+ def test_volume_delete_with_purge(self):
752
729
  arglist = [
753
730
  '--purge',
754
- volumes[0].id,
731
+ self.volumes[0].id,
755
732
  ]
756
733
  verifylist = [
757
734
  ('force', False),
758
735
  ('purge', True),
759
- ('volumes', [volumes[0].id]),
736
+ ('volumes', [self.volumes[0].id]),
760
737
  ]
761
738
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
762
739
 
763
740
  result = self.cmd.take_action(parsed_args)
741
+ self.assertIsNone(result)
764
742
 
765
- self.volumes_mock.delete.assert_called_once_with(
766
- volumes[0].id, cascade=True
743
+ self.volume_sdk_client.find_volume.assert_called_once_with(
744
+ self.volumes[0].id, ignore_missing=False
745
+ )
746
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
747
+ self.volumes[0].id, cascade=True, force=False
767
748
  )
768
- self.assertIsNone(result)
769
749
 
770
750
  def test_volume_delete_with_force(self):
771
- volumes = self.setup_volumes_mock(count=1)
772
-
773
751
  arglist = [
774
752
  '--force',
775
- volumes[0].id,
753
+ self.volumes[0].id,
776
754
  ]
777
755
  verifylist = [
778
756
  ('force', True),
779
757
  ('purge', False),
780
- ('volumes', [volumes[0].id]),
758
+ ('volumes', [self.volumes[0].id]),
781
759
  ]
782
760
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
783
761
 
784
762
  result = self.cmd.take_action(parsed_args)
785
-
786
- self.volumes_mock.force_delete.assert_called_once_with(volumes[0].id)
787
763
  self.assertIsNone(result)
788
764
 
765
+ self.volume_sdk_client.find_volume.assert_called_once_with(
766
+ self.volumes[0].id, ignore_missing=False
767
+ )
768
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
769
+ self.volumes[0].id, cascade=False, force=True
770
+ )
771
+
789
772
 
790
773
  class TestVolumeList(TestVolume):
791
774
  project = identity_fakes.FakeProject.create_one_project()
@@ -1311,69 +1294,80 @@ class TestVolumeList(TestVolume):
1311
1294
  self.assertIn(self.mock_volume.name, each_volume)
1312
1295
 
1313
1296
 
1314
- class TestVolumeMigrate(TestVolume):
1315
- _volume = volume_fakes.create_one_volume()
1316
-
1297
+ class TestVolumeMigrate(volume_fakes.TestVolume):
1317
1298
  def setUp(self):
1318
1299
  super().setUp()
1319
1300
 
1320
- self.volumes_mock.get.return_value = self._volume
1321
- self.volumes_mock.migrate_volume.return_value = None
1322
- # Get the command object to test
1301
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
1302
+ self.volume_sdk_client.find_volume.return_value = self.volume
1303
+ self.volume_sdk_client.migrate_volume.return_value = None
1304
+
1323
1305
  self.cmd = volume.MigrateVolume(self.app, None)
1324
1306
 
1325
1307
  def test_volume_migrate(self):
1326
1308
  arglist = [
1327
1309
  "--host",
1328
1310
  "host@backend-name#pool",
1329
- self._volume.id,
1311
+ self.volume.id,
1330
1312
  ]
1331
1313
  verifylist = [
1332
1314
  ("force_host_copy", False),
1333
1315
  ("lock_volume", False),
1334
1316
  ("host", "host@backend-name#pool"),
1335
- ("volume", self._volume.id),
1317
+ ("volume", self.volume.id),
1336
1318
  ]
1337
1319
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1338
1320
 
1339
1321
  result = self.cmd.take_action(parsed_args)
1340
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1341
- self.volumes_mock.migrate_volume.assert_called_once_with(
1342
- self._volume.id, "host@backend-name#pool", False, False
1343
- )
1344
1322
  self.assertIsNone(result)
1345
1323
 
1324
+ self.volume_sdk_client.find_volume.assert_called_with(
1325
+ self.volume.id, ignore_missing=False
1326
+ )
1327
+ self.volume_sdk_client.migrate_volume.assert_called_once_with(
1328
+ self.volume.id,
1329
+ host="host@backend-name#pool",
1330
+ force_host_copy=False,
1331
+ lock_volume=False,
1332
+ )
1333
+
1346
1334
  def test_volume_migrate_with_option(self):
1347
1335
  arglist = [
1348
1336
  "--force-host-copy",
1349
1337
  "--lock-volume",
1350
1338
  "--host",
1351
1339
  "host@backend-name#pool",
1352
- self._volume.id,
1340
+ self.volume.id,
1353
1341
  ]
1354
1342
  verifylist = [
1355
1343
  ("force_host_copy", True),
1356
1344
  ("lock_volume", True),
1357
1345
  ("host", "host@backend-name#pool"),
1358
- ("volume", self._volume.id),
1346
+ ("volume", self.volume.id),
1359
1347
  ]
1360
1348
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1361
1349
 
1362
1350
  result = self.cmd.take_action(parsed_args)
1363
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1364
- self.volumes_mock.migrate_volume.assert_called_once_with(
1365
- self._volume.id, "host@backend-name#pool", True, True
1366
- )
1367
1351
  self.assertIsNone(result)
1368
1352
 
1353
+ self.volume_sdk_client.find_volume.assert_called_with(
1354
+ self.volume.id, ignore_missing=False
1355
+ )
1356
+ self.volume_sdk_client.migrate_volume.assert_called_once_with(
1357
+ self.volume.id,
1358
+ host="host@backend-name#pool",
1359
+ force_host_copy=True,
1360
+ lock_volume=True,
1361
+ )
1362
+
1369
1363
  def test_volume_migrate_without_host(self):
1370
1364
  arglist = [
1371
- self._volume.id,
1365
+ self.volume.id,
1372
1366
  ]
1373
1367
  verifylist = [
1374
1368
  ("force_host_copy", False),
1375
1369
  ("lock_volume", False),
1376
- ("volume", self._volume.id),
1370
+ ("volume", self.volume.id),
1377
1371
  ]
1378
1372
 
1379
1373
  self.assertRaises(
@@ -1384,6 +1378,9 @@ class TestVolumeMigrate(TestVolume):
1384
1378
  verifylist,
1385
1379
  )
1386
1380
 
1381
+ self.volume_sdk_client.find_volume.assert_not_called()
1382
+ self.volume_sdk_client.migrate_volume.assert_not_called()
1383
+
1387
1384
 
1388
1385
  class TestVolumeSet(TestVolume):
1389
1386
  volume_type = volume_fakes.create_one_volume_type()
@@ -1407,16 +1404,16 @@ class TestVolumeSet(TestVolume):
1407
1404
  self.new_volume.id,
1408
1405
  ]
1409
1406
  verifylist = [
1410
- ('property', {'a': 'b', 'c': 'd'}),
1407
+ ('properties', {'a': 'b', 'c': 'd'}),
1411
1408
  ('volume', self.new_volume.id),
1412
- ('bootable', False),
1413
- ('non_bootable', False),
1409
+ ('bootable', None),
1410
+ ('read_only', None),
1414
1411
  ]
1415
1412
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1416
1413
 
1417
1414
  self.cmd.take_action(parsed_args)
1418
1415
  self.volumes_mock.set_metadata.assert_called_with(
1419
- self.new_volume.id, parsed_args.property
1416
+ self.new_volume.id, parsed_args.properties
1420
1417
  )
1421
1418
 
1422
1419
  def test_volume_set_image_property(self):
@@ -1428,10 +1425,10 @@ class TestVolumeSet(TestVolume):
1428
1425
  self.new_volume.id,
1429
1426
  ]
1430
1427
  verifylist = [
1431
- ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
1428
+ ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
1432
1429
  ('volume', self.new_volume.id),
1433
- ('bootable', False),
1434
- ('non_bootable', False),
1430
+ ('bootable', None),
1431
+ ('read_only', None),
1435
1432
  ]
1436
1433
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1437
1434
 
@@ -1439,14 +1436,13 @@ class TestVolumeSet(TestVolume):
1439
1436
  # returns nothing
1440
1437
  self.cmd.take_action(parsed_args)
1441
1438
  self.volumes_mock.set_image_metadata.assert_called_with(
1442
- self.new_volume.id, parsed_args.image_property
1439
+ self.new_volume.id, parsed_args.image_properties
1443
1440
  )
1444
1441
 
1445
1442
  def test_volume_set_state(self):
1446
1443
  arglist = ['--state', 'error', self.new_volume.id]
1447
1444
  verifylist = [
1448
- ('read_only', False),
1449
- ('read_write', False),
1445
+ ('read_only', None),
1450
1446
  ('state', 'error'),
1451
1447
  ('volume', self.new_volume.id),
1452
1448
  ]
@@ -1511,36 +1507,40 @@ class TestVolumeSet(TestVolume):
1511
1507
 
1512
1508
  def test_volume_set_bootable(self):
1513
1509
  arglist = [
1514
- ['--bootable', self.new_volume.id],
1515
- ['--non-bootable', self.new_volume.id],
1510
+ '--bootable',
1511
+ self.new_volume.id,
1516
1512
  ]
1517
1513
  verifylist = [
1518
- [
1519
- ('bootable', True),
1520
- ('non_bootable', False),
1521
- ('volume', self.new_volume.id),
1522
- ],
1523
- [
1524
- ('bootable', False),
1525
- ('non_bootable', True),
1526
- ('volume', self.new_volume.id),
1527
- ],
1514
+ ('bootable', True),
1515
+ ('volume', self.new_volume.id),
1528
1516
  ]
1529
- for index in range(len(arglist)):
1530
- parsed_args = self.check_parser(
1531
- self.cmd, arglist[index], verifylist[index]
1532
- )
1517
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1533
1518
 
1534
- self.cmd.take_action(parsed_args)
1535
- self.volumes_mock.set_bootable.assert_called_with(
1536
- self.new_volume.id, verifylist[index][0][1]
1537
- )
1519
+ self.cmd.take_action(parsed_args)
1520
+ self.volumes_mock.set_bootable.assert_called_with(
1521
+ self.new_volume.id, verifylist[0][1]
1522
+ )
1523
+
1524
+ def test_volume_set_non_bootable(self):
1525
+ arglist = [
1526
+ '--non-bootable',
1527
+ self.new_volume.id,
1528
+ ]
1529
+ verifylist = [
1530
+ ('bootable', False),
1531
+ ('volume', self.new_volume.id),
1532
+ ]
1533
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1538
1534
 
1539
- def test_volume_set_readonly(self):
1535
+ self.cmd.take_action(parsed_args)
1536
+ self.volumes_mock.set_bootable.assert_called_with(
1537
+ self.new_volume.id, verifylist[0][1]
1538
+ )
1539
+
1540
+ def test_volume_set_read_only(self):
1540
1541
  arglist = ['--read-only', self.new_volume.id]
1541
1542
  verifylist = [
1542
1543
  ('read_only', True),
1543
- ('read_write', False),
1544
1544
  ('volume', self.new_volume.id),
1545
1545
  ]
1546
1546
 
@@ -1556,7 +1556,6 @@ class TestVolumeSet(TestVolume):
1556
1556
  arglist = ['--read-write', self.new_volume.id]
1557
1557
  verifylist = [
1558
1558
  ('read_only', False),
1559
- ('read_write', True),
1560
1559
  ('volume', self.new_volume.id),
1561
1560
  ]
1562
1561
 
@@ -1624,42 +1623,83 @@ class TestVolumeSet(TestVolume):
1624
1623
  self.assertIsNone(result)
1625
1624
 
1626
1625
 
1627
- class TestVolumeShow(TestVolume):
1626
+ class TestVolumeShow(volume_fakes.TestVolume):
1628
1627
  def setUp(self):
1629
1628
  super().setUp()
1630
1629
 
1631
- self._volume = volume_fakes.create_one_volume()
1632
- self.volumes_mock.get.return_value = self._volume
1633
- # Get the command object to test
1630
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
1631
+ self.volume_sdk_client.find_volume.return_value = self.volume
1632
+
1633
+ self.columns = (
1634
+ 'attachments',
1635
+ 'availability_zone',
1636
+ 'bootable',
1637
+ 'consistencygroup_id',
1638
+ 'created_at',
1639
+ 'description',
1640
+ 'encrypted',
1641
+ 'id',
1642
+ 'multiattach',
1643
+ 'name',
1644
+ 'os-vol-host-attr:host',
1645
+ 'os-vol-mig-status-attr:migstat',
1646
+ 'os-vol-mig-status-attr:name_id',
1647
+ 'os-vol-tenant-attr:tenant_id',
1648
+ 'os-volume-replication:driver_data',
1649
+ 'os-volume-replication:extended_status',
1650
+ 'properties',
1651
+ 'replication_status',
1652
+ 'size',
1653
+ 'snapshot_id',
1654
+ 'source_volid',
1655
+ 'status',
1656
+ 'type',
1657
+ 'updated_at',
1658
+ 'user_id',
1659
+ 'volume_image_metadata',
1660
+ )
1661
+ self.data = (
1662
+ self.volume.attachments,
1663
+ self.volume.availability_zone,
1664
+ self.volume.is_bootable,
1665
+ self.volume.consistency_group_id,
1666
+ self.volume.created_at,
1667
+ self.volume.description,
1668
+ self.volume.is_encrypted,
1669
+ self.volume.id,
1670
+ self.volume.is_multiattach,
1671
+ self.volume.name,
1672
+ self.volume.host,
1673
+ self.volume.migration_status,
1674
+ self.volume.migration_id,
1675
+ self.volume.project_id,
1676
+ self.volume.replication_driver_data,
1677
+ self.volume.extended_replication_status,
1678
+ format_columns.DictColumn(self.volume.metadata),
1679
+ self.volume.replication_status,
1680
+ self.volume.size,
1681
+ self.volume.snapshot_id,
1682
+ self.volume.source_volume_id,
1683
+ self.volume.status,
1684
+ self.volume.volume_type,
1685
+ self.volume.updated_at,
1686
+ self.volume.user_id,
1687
+ self.volume.volume_image_metadata,
1688
+ )
1689
+
1634
1690
  self.cmd = volume.ShowVolume(self.app, None)
1635
1691
 
1636
1692
  def test_volume_show(self):
1637
- arglist = [self._volume.id]
1638
- verifylist = [("volume", self._volume.id)]
1693
+ arglist = [self.volume.id]
1694
+ verifylist = [("volume", self.volume.id)]
1639
1695
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1640
1696
 
1641
1697
  columns, data = self.cmd.take_action(parsed_args)
1642
- self.volumes_mock.get.assert_called_with(self._volume.id)
1643
1698
 
1644
- self.assertEqual(
1645
- tuple(sorted(self._volume.keys())),
1646
- columns,
1647
- )
1648
- self.assertTupleEqual(
1649
- (
1650
- self._volume.attachments,
1651
- self._volume.availability_zone,
1652
- self._volume.bootable,
1653
- self._volume.description,
1654
- self._volume.id,
1655
- self._volume.name,
1656
- format_columns.DictColumn(self._volume.metadata),
1657
- self._volume.size,
1658
- self._volume.snapshot_id,
1659
- self._volume.status,
1660
- self._volume.volume_type,
1661
- ),
1662
- data,
1699
+ self.assertEqual(self.columns, columns)
1700
+ self.assertEqual(self.data, data)
1701
+ self.volume_sdk_client.find_volume.assert_called_with(
1702
+ self.volume.id, ignore_missing=False
1663
1703
  )
1664
1704
 
1665
1705
 
@@ -1686,7 +1726,7 @@ class TestVolumeUnset(TestVolume):
1686
1726
  self.new_volume.id,
1687
1727
  ]
1688
1728
  verifylist = [
1689
- ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
1729
+ ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
1690
1730
  ('volume', self.new_volume.id),
1691
1731
  ]
1692
1732
  parsed_args = self.check_parser(self.cmd_set, arglist, verifylist)
@@ -1702,7 +1742,7 @@ class TestVolumeUnset(TestVolume):
1702
1742
  self.new_volume.id,
1703
1743
  ]
1704
1744
  verifylist_unset = [
1705
- ('image_property', ['Alpha']),
1745
+ ('image_properties', ['Alpha']),
1706
1746
  ('volume', self.new_volume.id),
1707
1747
  ]
1708
1748
  parsed_args_unset = self.check_parser(
@@ -1714,7 +1754,7 @@ class TestVolumeUnset(TestVolume):
1714
1754
  self.cmd_unset.take_action(parsed_args_unset)
1715
1755
 
1716
1756
  self.volumes_mock.delete_image_metadata.assert_called_with(
1717
- self.new_volume.id, parsed_args_unset.image_property
1757
+ self.new_volume.id, parsed_args_unset.image_properties
1718
1758
  )
1719
1759
 
1720
1760
  def test_volume_unset_image_property_fail(self):
@@ -1729,8 +1769,8 @@ class TestVolumeUnset(TestVolume):
1729
1769
  self.new_volume.id,
1730
1770
  ]
1731
1771
  verifylist = [
1732
- ('image_property', ['Alpha']),
1733
- ('property', ['Beta']),
1772
+ ('image_properties', ['Alpha']),
1773
+ ('properties', ['Beta']),
1734
1774
  ('volume', self.new_volume.id),
1735
1775
  ]
1736
1776
  parsed_args = self.check_parser(self.cmd_unset, arglist, verifylist)
@@ -1743,38 +1783,54 @@ class TestVolumeUnset(TestVolume):
1743
1783
  'One or more of the unset operations failed', str(e)
1744
1784
  )
1745
1785
  self.volumes_mock.delete_image_metadata.assert_called_with(
1746
- self.new_volume.id, parsed_args.image_property
1786
+ self.new_volume.id, parsed_args.image_properties
1747
1787
  )
1748
1788
  self.volumes_mock.delete_metadata.assert_called_with(
1749
- self.new_volume.id, parsed_args.property
1789
+ self.new_volume.id, parsed_args.properties
1750
1790
  )
1751
1791
 
1752
1792
 
1753
- class TestColumns(TestVolume):
1793
+ class TestColumns(volume_fakes.TestVolume):
1754
1794
  def test_attachments_column_without_server_cache(self):
1755
- _volume = volume_fakes.create_one_volume()
1756
- server_id = _volume.attachments[0]['server_id']
1757
- device = _volume.attachments[0]['device']
1795
+ vol = sdk_fakes.generate_fake_resource(
1796
+ _volume.Volume,
1797
+ attachments=[
1798
+ {
1799
+ 'device': '/dev/' + uuid.uuid4().hex,
1800
+ 'server_id': uuid.uuid4().hex,
1801
+ },
1802
+ ],
1803
+ )
1804
+ server_id = vol.attachments[0]['server_id']
1805
+ device = vol.attachments[0]['device']
1758
1806
 
1759
- col = volume.AttachmentsColumn(_volume.attachments, {})
1807
+ col = volume.AttachmentsColumn(vol.attachments, {})
1760
1808
  self.assertEqual(
1761
1809
  f'Attached to {server_id} on {device} ',
1762
1810
  col.human_readable(),
1763
1811
  )
1764
- self.assertEqual(_volume.attachments, col.machine_readable())
1812
+ self.assertEqual(vol.attachments, col.machine_readable())
1765
1813
 
1766
1814
  def test_attachments_column_with_server_cache(self):
1767
- _volume = volume_fakes.create_one_volume()
1815
+ vol = sdk_fakes.generate_fake_resource(
1816
+ _volume.Volume,
1817
+ attachments=[
1818
+ {
1819
+ 'device': '/dev/' + uuid.uuid4().hex,
1820
+ 'server_id': uuid.uuid4().hex,
1821
+ },
1822
+ ],
1823
+ )
1768
1824
 
1769
- server_id = _volume.attachments[0]['server_id']
1770
- device = _volume.attachments[0]['device']
1825
+ server_id = vol.attachments[0]['server_id']
1826
+ device = vol.attachments[0]['device']
1771
1827
  fake_server = mock.Mock()
1772
1828
  fake_server.name = 'fake-server-name'
1773
1829
  server_cache = {server_id: fake_server}
1774
1830
 
1775
- col = volume.AttachmentsColumn(_volume.attachments, server_cache)
1831
+ col = volume.AttachmentsColumn(vol.attachments, server_cache)
1776
1832
  self.assertEqual(
1777
1833
  'Attached to {} on {} '.format('fake-server-name', device),
1778
1834
  col.human_readable(),
1779
1835
  )
1780
- self.assertEqual(_volume.attachments, col.machine_readable())
1836
+ self.assertEqual(vol.attachments, col.machine_readable())