python-openstackclient 8.1.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 (56) 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/v2/flavor.py +14 -1
  5. openstackclient/compute/v2/server.py +1 -3
  6. openstackclient/identity/common.py +8 -13
  7. openstackclient/identity/v3/application_credential.py +86 -85
  8. openstackclient/identity/v3/domain.py +5 -6
  9. openstackclient/identity/v3/project.py +25 -20
  10. openstackclient/identity/v3/role.py +7 -2
  11. openstackclient/image/v1/image.py +16 -1
  12. openstackclient/image/v2/cache.py +10 -6
  13. openstackclient/image/v2/image.py +48 -1
  14. openstackclient/image/v2/metadef_objects.py +8 -2
  15. openstackclient/image/v2/metadef_properties.py +9 -2
  16. openstackclient/network/v2/port.py +16 -0
  17. openstackclient/network/v2/security_group.py +44 -3
  18. openstackclient/network/v2/security_group_rule.py +17 -0
  19. openstackclient/tests/functional/identity/v3/test_access_rule.py +1 -1
  20. openstackclient/tests/functional/identity/v3/test_application_credential.py +7 -7
  21. openstackclient/tests/functional/image/v2/test_image.py +36 -14
  22. openstackclient/tests/functional/volume/v2/test_volume.py +1 -1
  23. openstackclient/tests/functional/volume/v3/test_volume.py +2 -2
  24. openstackclient/tests/unit/api/test_volume_v2.py +124 -0
  25. openstackclient/tests/unit/api/test_volume_v3.py +124 -0
  26. openstackclient/tests/unit/compute/v2/test_flavor.py +159 -174
  27. openstackclient/tests/unit/compute/v2/test_server.py +42 -51
  28. openstackclient/tests/unit/identity/v3/test_application_credential.py +47 -41
  29. openstackclient/tests/unit/identity/v3/test_domain.py +2 -2
  30. openstackclient/tests/unit/identity/v3/test_project.py +30 -53
  31. openstackclient/tests/unit/identity/v3/test_role.py +2 -8
  32. openstackclient/tests/unit/image/v1/test_image.py +47 -0
  33. openstackclient/tests/unit/image/v2/test_image.py +79 -9
  34. openstackclient/tests/unit/image/v2/test_metadef_objects.py +22 -0
  35. openstackclient/tests/unit/image/v2/test_metadef_properties.py +24 -10
  36. openstackclient/tests/unit/network/v2/fakes.py +1 -0
  37. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +2 -2
  38. openstackclient/tests/unit/network/v2/test_port.py +40 -0
  39. openstackclient/tests/unit/network/v2/test_security_group_network.py +6 -0
  40. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +49 -0
  41. openstackclient/tests/unit/volume/v2/test_volume.py +358 -305
  42. openstackclient/tests/unit/volume/v3/test_volume.py +439 -415
  43. openstackclient/volume/v2/service.py +1 -1
  44. openstackclient/volume/v2/volume.py +78 -52
  45. openstackclient/volume/v3/service.py +1 -1
  46. openstackclient/volume/v3/volume.py +102 -75
  47. openstackclient/volume/v3/volume_group.py +1 -1
  48. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/AUTHORS +5 -0
  49. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/METADATA +7 -7
  50. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/RECORD +55 -51
  51. python_openstackclient-8.2.0.dist-info/pbr.json +1 -0
  52. python_openstackclient-8.1.0.dist-info/pbr.json +0 -1
  53. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/LICENSE +0 -0
  54. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/WHEEL +0 -0
  55. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/entry_points.txt +0 -0
  56. {python_openstackclient-8.1.0.dist-info → python_openstackclient-8.2.0.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,9 @@
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
16
18
  from openstack.block_storage.v2 import volume as _volume
17
19
  from openstack import exceptions as sdk_exceptions
18
20
  from openstack.test import fakes as sdk_fakes
@@ -20,6 +22,7 @@ from osc_lib.cli import format_columns
20
22
  from osc_lib import exceptions
21
23
  from osc_lib import utils
22
24
 
25
+ from openstackclient.api import volume_v2
23
26
  from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
24
27
  from openstackclient.tests.unit.image.v2 import fakes as image_fakes
25
28
  from openstackclient.tests.unit import utils as test_utils
@@ -50,129 +53,156 @@ class TestVolume(volume_fakes.TestVolume):
50
53
  self.consistencygroups_mock.reset_mock()
51
54
 
52
55
 
53
- class TestVolumeCreate(TestVolume):
54
- project = identity_fakes.FakeProject.create_one_project()
55
- user = identity_fakes.FakeUser.create_one_user()
56
-
56
+ class TestVolumeCreate(volume_fakes.TestVolume):
57
57
  columns = (
58
58
  'attachments',
59
59
  'availability_zone',
60
60
  'bootable',
61
+ 'consistencygroup_id',
62
+ 'created_at',
61
63
  'description',
64
+ 'encrypted',
62
65
  'id',
66
+ 'multiattach',
63
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',
64
74
  'properties',
75
+ 'replication_status',
65
76
  'size',
66
77
  'snapshot_id',
78
+ 'source_volid',
67
79
  'status',
68
80
  'type',
81
+ 'updated_at',
82
+ 'user_id',
83
+ 'volume_image_metadata',
69
84
  )
70
85
 
71
86
  def setUp(self):
72
87
  super().setUp()
73
88
 
74
- self.new_volume = volume_fakes.create_one_volume()
75
- 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
76
91
 
77
92
  self.datalist = (
78
- self.new_volume.attachments,
79
- self.new_volume.availability_zone,
80
- self.new_volume.bootable,
81
- self.new_volume.description,
82
- self.new_volume.id,
83
- self.new_volume.name,
84
- format_columns.DictColumn(self.new_volume.metadata),
85
- self.new_volume.size,
86
- self.new_volume.snapshot_id,
87
- self.new_volume.status,
88
- 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,
89
119
  )
90
-
91
120
  # Get the command object to test
92
121
  self.cmd = volume.CreateVolume(self.app, None)
93
122
 
94
123
  def test_volume_create_min_options(self):
95
124
  arglist = [
96
125
  '--size',
97
- str(self.new_volume.size),
126
+ str(self.volume.size),
98
127
  ]
99
128
  verifylist = [
100
- ('size', self.new_volume.size),
129
+ ('size', self.volume.size),
101
130
  ]
102
131
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
103
132
 
104
- # In base command class ShowOne in cliff, abstract method take_action()
105
- # returns a two-part tuple with a tuple of column names and a tuple of
106
- # data to be shown.
107
133
  columns, data = self.cmd.take_action(parsed_args)
108
134
 
109
- self.volumes_mock.create.assert_called_with(
110
- size=self.new_volume.size,
135
+ self.volume_sdk_client.create_volume.assert_called_with(
136
+ size=self.volume.size,
111
137
  snapshot_id=None,
112
138
  name=None,
113
139
  description=None,
114
140
  volume_type=None,
115
141
  availability_zone=None,
116
142
  metadata=None,
117
- imageRef=None,
118
- source_volid=None,
119
- consistencygroup_id=None,
143
+ image_id=None,
144
+ source_volume_id=None,
145
+ consistency_group_id=None,
120
146
  scheduler_hints=None,
121
147
  )
122
148
 
123
149
  self.assertEqual(self.columns, columns)
124
- self.assertCountEqual(self.datalist, data)
150
+ self.assertEqual(self.datalist, data)
125
151
 
126
152
  def test_volume_create_options(self):
127
- consistency_group = volume_fakes.create_one_consistency_group()
128
- self.consistencygroups_mock.get.return_value = consistency_group
153
+ consistency_group_id = 'cg123'
129
154
  arglist = [
130
155
  '--size',
131
- str(self.new_volume.size),
156
+ str(self.volume.size),
132
157
  '--description',
133
- self.new_volume.description,
158
+ self.volume.description,
134
159
  '--type',
135
- self.new_volume.volume_type,
160
+ self.volume.volume_type,
136
161
  '--availability-zone',
137
- self.new_volume.availability_zone,
162
+ self.volume.availability_zone,
138
163
  '--consistency-group',
139
- consistency_group.id,
164
+ consistency_group_id,
140
165
  '--hint',
141
166
  'k=v',
142
- self.new_volume.name,
167
+ self.volume.name,
143
168
  ]
144
169
  verifylist = [
145
- ('size', self.new_volume.size),
146
- ('description', self.new_volume.description),
147
- ('type', self.new_volume.volume_type),
148
- ('availability_zone', self.new_volume.availability_zone),
149
- ('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),
150
175
  ('hint', {'k': 'v'}),
151
- ('name', self.new_volume.name),
176
+ ('name', self.volume.name),
152
177
  ]
153
178
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
154
179
 
155
- # In base command class ShowOne in cliff, abstract method take_action()
156
- # returns a two-part tuple with a tuple of column names and a tuple of
157
- # data to be shown.
158
- columns, data = self.cmd.take_action(parsed_args)
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)
159
186
 
160
- self.volumes_mock.create.assert_called_with(
161
- size=self.new_volume.size,
187
+ self.volume_sdk_client.create_volume.assert_called_with(
188
+ size=self.volume.size,
162
189
  snapshot_id=None,
163
- name=self.new_volume.name,
164
- description=self.new_volume.description,
165
- volume_type=self.new_volume.volume_type,
166
- 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,
167
194
  metadata=None,
168
- imageRef=None,
169
- source_volid=None,
170
- consistencygroup_id=consistency_group.id,
195
+ image_id=None,
196
+ source_volume_id=None,
197
+ consistency_group_id=consistency_group_id,
171
198
  scheduler_hints={'k': 'v'},
172
199
  )
200
+ mock_find_cg.assert_called_once_with(
201
+ self.volume_sdk_client, consistency_group_id
202
+ )
173
203
 
174
204
  self.assertEqual(self.columns, columns)
175
- self.assertCountEqual(self.datalist, data)
205
+ self.assertEqual(self.datalist, data)
176
206
 
177
207
  def test_volume_create_properties(self):
178
208
  arglist = [
@@ -181,39 +211,36 @@ class TestVolumeCreate(TestVolume):
181
211
  '--property',
182
212
  'Beta=b',
183
213
  '--size',
184
- str(self.new_volume.size),
185
- self.new_volume.name,
214
+ str(self.volume.size),
215
+ self.volume.name,
186
216
  ]
187
217
  verifylist = [
188
218
  ('properties', {'Alpha': 'a', 'Beta': 'b'}),
189
- ('size', self.new_volume.size),
190
- ('name', self.new_volume.name),
219
+ ('size', self.volume.size),
220
+ ('name', self.volume.name),
191
221
  ]
192
222
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
193
223
 
194
- # In base command class ShowOne in cliff, abstract method take_action()
195
- # returns a two-part tuple with a tuple of column names and a tuple of
196
- # data to be shown.
197
224
  columns, data = self.cmd.take_action(parsed_args)
198
225
 
199
- self.volumes_mock.create.assert_called_with(
200
- size=self.new_volume.size,
226
+ self.volume_sdk_client.create_volume.assert_called_with(
227
+ size=self.volume.size,
201
228
  snapshot_id=None,
202
- name=self.new_volume.name,
229
+ name=self.volume.name,
203
230
  description=None,
204
231
  volume_type=None,
205
232
  availability_zone=None,
206
233
  metadata={'Alpha': 'a', 'Beta': 'b'},
207
- imageRef=None,
208
- source_volid=None,
209
- consistencygroup_id=None,
234
+ image_id=None,
235
+ source_volume_id=None,
236
+ consistency_group_id=None,
210
237
  scheduler_hints=None,
211
238
  )
212
239
 
213
240
  self.assertEqual(self.columns, columns)
214
- self.assertCountEqual(self.datalist, data)
241
+ self.assertEqual(self.datalist, data)
215
242
 
216
- def test_volume_create_image_id(self):
243
+ def test_volume_create_image(self):
217
244
  image = image_fakes.create_one_image()
218
245
  self.image_client.find_image.return_value = image
219
246
 
@@ -221,152 +248,111 @@ class TestVolumeCreate(TestVolume):
221
248
  '--image',
222
249
  image.id,
223
250
  '--size',
224
- str(self.new_volume.size),
225
- self.new_volume.name,
251
+ str(self.volume.size),
252
+ self.volume.name,
226
253
  ]
227
254
  verifylist = [
228
255
  ('image', image.id),
229
- ('size', self.new_volume.size),
230
- ('name', self.new_volume.name),
256
+ ('size', self.volume.size),
257
+ ('name', self.volume.name),
231
258
  ]
232
259
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
233
260
 
234
- # In base command class ShowOne in cliff, abstract method take_action()
235
- # returns a two-part tuple with a tuple of column names and a tuple of
236
- # data to be shown.
237
261
  columns, data = self.cmd.take_action(parsed_args)
238
262
 
239
- self.volumes_mock.create.assert_called_with(
240
- size=self.new_volume.size,
263
+ self.volume_sdk_client.create_volume.assert_called_with(
264
+ size=self.volume.size,
241
265
  snapshot_id=None,
242
- name=self.new_volume.name,
266
+ name=self.volume.name,
243
267
  description=None,
244
268
  volume_type=None,
245
269
  availability_zone=None,
246
270
  metadata=None,
247
- imageRef=image.id,
248
- source_volid=None,
249
- consistencygroup_id=None,
271
+ image_id=image.id,
272
+ source_volume_id=None,
273
+ consistency_group_id=None,
250
274
  scheduler_hints=None,
251
275
  )
252
-
253
- self.assertEqual(self.columns, columns)
254
- self.assertCountEqual(self.datalist, data)
255
-
256
- def test_volume_create_image_name(self):
257
- image = image_fakes.create_one_image()
258
- self.image_client.find_image.return_value = image
259
-
260
- arglist = [
261
- '--image',
262
- image.name,
263
- '--size',
264
- str(self.new_volume.size),
265
- self.new_volume.name,
266
- ]
267
- verifylist = [
268
- ('image', image.name),
269
- ('size', self.new_volume.size),
270
- ('name', self.new_volume.name),
271
- ]
272
- parsed_args = self.check_parser(self.cmd, arglist, verifylist)
273
-
274
- # In base command class ShowOne in cliff, abstract method take_action()
275
- # returns a two-part tuple with a tuple of column names and a tuple of
276
- # data to be shown.
277
- columns, data = self.cmd.take_action(parsed_args)
278
-
279
- self.volumes_mock.create.assert_called_with(
280
- size=self.new_volume.size,
281
- snapshot_id=None,
282
- name=self.new_volume.name,
283
- description=None,
284
- volume_type=None,
285
- availability_zone=None,
286
- metadata=None,
287
- imageRef=image.id,
288
- source_volid=None,
289
- consistencygroup_id=None,
290
- scheduler_hints=None,
276
+ self.image_client.find_image.assert_called_once_with(
277
+ image.id, ignore_missing=False
291
278
  )
292
279
 
293
280
  self.assertEqual(self.columns, columns)
294
- self.assertCountEqual(self.datalist, data)
281
+ self.assertEqual(self.datalist, data)
295
282
 
296
283
  def test_volume_create_with_snapshot(self):
297
- snapshot = volume_fakes.create_one_snapshot()
298
- 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
+
299
287
  arglist = [
300
288
  '--snapshot',
301
- self.new_volume.snapshot_id,
302
- self.new_volume.name,
289
+ snapshot.id,
290
+ self.volume.name,
303
291
  ]
304
292
  verifylist = [
305
- ('snapshot', self.new_volume.snapshot_id),
306
- ('name', self.new_volume.name),
293
+ ('snapshot', snapshot.id),
294
+ ('name', self.volume.name),
307
295
  ]
308
296
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
309
297
 
310
- self.snapshots_mock.get.return_value = snapshot
311
-
312
- # In base command class ShowOne in cliff, abstract method take_action()
313
- # returns a two-part tuple with a tuple of column names and a tuple of
314
- # data to be shown.
315
298
  columns, data = self.cmd.take_action(parsed_args)
316
299
 
317
- self.volumes_mock.create.assert_called_once_with(
300
+ self.volume_sdk_client.create_volume.assert_called_with(
318
301
  size=snapshot.size,
319
302
  snapshot_id=snapshot.id,
320
- name=self.new_volume.name,
303
+ name=self.volume.name,
321
304
  description=None,
322
305
  volume_type=None,
323
306
  availability_zone=None,
324
307
  metadata=None,
325
- imageRef=None,
326
- source_volid=None,
327
- consistencygroup_id=None,
308
+ image_id=None,
309
+ source_volume_id=None,
310
+ consistency_group_id=None,
328
311
  scheduler_hints=None,
329
312
  )
313
+ self.volume_sdk_client.find_snapshot.assert_called_once_with(
314
+ snapshot.id, ignore_missing=False
315
+ )
330
316
 
331
317
  self.assertEqual(self.columns, columns)
332
- self.assertCountEqual(self.datalist, data)
318
+ self.assertEqual(self.datalist, data)
333
319
 
334
320
  def test_volume_create_with_source_volume(self):
335
- 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
+
336
324
  arglist = [
337
325
  '--source',
338
- self.new_volume.id,
339
- source_vol,
326
+ source_volume.id,
327
+ self.volume.name,
340
328
  ]
341
329
  verifylist = [
342
- ('source', self.new_volume.id),
343
- ('name', source_vol),
330
+ ('source', source_volume.id),
331
+ ('name', self.volume.name),
344
332
  ]
345
333
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
346
334
 
347
- self.volumes_mock.get.return_value = self.new_volume
348
-
349
- # In base command class ShowOne in cliff, abstract method take_action()
350
- # returns a two-part tuple with a tuple of column names and a tuple of
351
- # data to be shown.
352
335
  columns, data = self.cmd.take_action(parsed_args)
353
336
 
354
- self.volumes_mock.create.assert_called_once_with(
355
- size=self.new_volume.size,
337
+ self.volume_sdk_client.create_volume.assert_called_with(
338
+ size=source_volume.size,
356
339
  snapshot_id=None,
357
- name=source_vol,
340
+ name=self.volume.name,
358
341
  description=None,
359
342
  volume_type=None,
360
343
  availability_zone=None,
361
344
  metadata=None,
362
- imageRef=None,
363
- source_volid=self.new_volume.id,
364
- consistencygroup_id=None,
345
+ image_id=None,
346
+ source_volume_id=source_volume.id,
347
+ consistency_group_id=None,
365
348
  scheduler_hints=None,
366
349
  )
350
+ self.volume_sdk_client.find_volume.assert_called_once_with(
351
+ source_volume.id, ignore_missing=False
352
+ )
367
353
 
368
354
  self.assertEqual(self.columns, columns)
369
- self.assertCountEqual(self.datalist, data)
355
+ self.assertEqual(self.datalist, data)
370
356
 
371
357
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
372
358
  def test_volume_create_with_bootable_and_readonly(self, mock_wait):
@@ -374,188 +360,187 @@ class TestVolumeCreate(TestVolume):
374
360
  '--bootable',
375
361
  '--read-only',
376
362
  '--size',
377
- str(self.new_volume.size),
378
- self.new_volume.name,
363
+ str(self.volume.size),
364
+ self.volume.name,
379
365
  ]
380
366
  verifylist = [
381
367
  ('bootable', True),
382
368
  ('read_only', True),
383
- ('size', self.new_volume.size),
384
- ('name', self.new_volume.name),
369
+ ('size', self.volume.size),
370
+ ('name', self.volume.name),
385
371
  ]
386
372
 
387
373
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
388
374
 
389
375
  columns, data = self.cmd.take_action(parsed_args)
390
376
 
391
- self.volumes_mock.create.assert_called_with(
392
- size=self.new_volume.size,
377
+ self.volume_sdk_client.create_volume.assert_called_with(
378
+ size=self.volume.size,
393
379
  snapshot_id=None,
394
- name=self.new_volume.name,
380
+ name=self.volume.name,
395
381
  description=None,
396
382
  volume_type=None,
397
383
  availability_zone=None,
398
384
  metadata=None,
399
- imageRef=None,
400
- source_volid=None,
401
- consistencygroup_id=None,
385
+ image_id=None,
386
+ source_volume_id=None,
387
+ consistency_group_id=None,
402
388
  scheduler_hints=None,
403
389
  )
404
-
405
- self.assertEqual(self.columns, columns)
406
- self.assertCountEqual(self.datalist, data)
407
- self.volumes_mock.set_bootable.assert_called_with(
408
- self.new_volume.id, True
390
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
391
+ self.volume, True
409
392
  )
410
- self.volumes_mock.update_readonly_flag.assert_called_with(
411
- self.new_volume.id, True
393
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
394
+ self.volume, True
412
395
  )
413
396
 
397
+ self.assertEqual(self.columns, columns)
398
+ self.assertEqual(self.datalist, data)
399
+
414
400
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
415
401
  def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
416
402
  arglist = [
417
403
  '--non-bootable',
418
404
  '--read-write',
419
405
  '--size',
420
- str(self.new_volume.size),
421
- self.new_volume.name,
406
+ str(self.volume.size),
407
+ self.volume.name,
422
408
  ]
423
409
  verifylist = [
424
410
  ('bootable', False),
425
411
  ('read_only', False),
426
- ('size', self.new_volume.size),
427
- ('name', self.new_volume.name),
412
+ ('size', self.volume.size),
413
+ ('name', self.volume.name),
428
414
  ]
429
415
 
430
416
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
431
417
 
432
418
  columns, data = self.cmd.take_action(parsed_args)
433
419
 
434
- self.volumes_mock.create.assert_called_with(
435
- size=self.new_volume.size,
420
+ self.volume_sdk_client.create_volume.assert_called_with(
421
+ size=self.volume.size,
436
422
  snapshot_id=None,
437
- name=self.new_volume.name,
423
+ name=self.volume.name,
438
424
  description=None,
439
425
  volume_type=None,
440
426
  availability_zone=None,
441
427
  metadata=None,
442
- imageRef=None,
443
- source_volid=None,
444
- consistencygroup_id=None,
428
+ image_id=None,
429
+ source_volume_id=None,
430
+ consistency_group_id=None,
445
431
  scheduler_hints=None,
446
432
  )
447
-
448
- self.assertEqual(self.columns, columns)
449
- self.assertCountEqual(self.datalist, data)
450
- self.volumes_mock.set_bootable.assert_called_with(
451
- self.new_volume.id, False
433
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
434
+ self.volume, False
452
435
  )
453
- self.volumes_mock.update_readonly_flag.assert_called_with(
454
- self.new_volume.id, False
436
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
437
+ self.volume, False
455
438
  )
456
439
 
440
+ self.assertEqual(self.columns, columns)
441
+ self.assertEqual(self.datalist, data)
442
+
457
443
  @mock.patch.object(volume.LOG, 'error')
458
444
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
459
445
  def test_volume_create_with_bootable_and_readonly_fail(
460
446
  self, mock_wait, mock_error
461
447
  ):
462
- self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
463
-
464
- self.volumes_mock.update_readonly_flag.side_effect = (
465
- 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')
466
453
  )
467
454
 
468
455
  arglist = [
469
456
  '--bootable',
470
457
  '--read-only',
471
458
  '--size',
472
- str(self.new_volume.size),
473
- self.new_volume.name,
459
+ str(self.volume.size),
460
+ self.volume.name,
474
461
  ]
475
462
  verifylist = [
476
463
  ('bootable', True),
477
464
  ('read_only', True),
478
- ('size', self.new_volume.size),
479
- ('name', self.new_volume.name),
465
+ ('size', self.volume.size),
466
+ ('name', self.volume.name),
480
467
  ]
481
468
 
482
469
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
483
470
 
484
471
  columns, data = self.cmd.take_action(parsed_args)
485
472
 
486
- self.volumes_mock.create.assert_called_with(
487
- size=self.new_volume.size,
473
+ self.volume_sdk_client.create_volume.assert_called_with(
474
+ size=self.volume.size,
488
475
  snapshot_id=None,
489
- name=self.new_volume.name,
476
+ name=self.volume.name,
490
477
  description=None,
491
478
  volume_type=None,
492
479
  availability_zone=None,
493
480
  metadata=None,
494
- imageRef=None,
495
- source_volid=None,
496
- consistencygroup_id=None,
481
+ image_id=None,
482
+ source_volume_id=None,
483
+ consistency_group_id=None,
497
484
  scheduler_hints=None,
498
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
+ )
499
492
 
500
493
  self.assertEqual(2, mock_error.call_count)
501
494
  self.assertEqual(self.columns, columns)
502
- self.assertCountEqual(self.datalist, data)
503
- self.volumes_mock.set_bootable.assert_called_with(
504
- self.new_volume.id, True
505
- )
506
- self.volumes_mock.update_readonly_flag.assert_called_with(
507
- self.new_volume.id, True
508
- )
495
+ self.assertEqual(self.datalist, data)
509
496
 
510
497
  @mock.patch.object(volume.LOG, 'error')
511
498
  @mock.patch.object(utils, 'wait_for_status', return_value=False)
512
499
  def test_volume_create_non_available_with_readonly(
513
- self,
514
- mock_wait,
515
- mock_error,
500
+ self, mock_wait, mock_error
516
501
  ):
517
502
  arglist = [
518
503
  '--non-bootable',
519
504
  '--read-only',
520
505
  '--size',
521
- str(self.new_volume.size),
522
- self.new_volume.name,
506
+ str(self.volume.size),
507
+ self.volume.name,
523
508
  ]
524
509
  verifylist = [
525
510
  ('bootable', False),
526
511
  ('read_only', True),
527
- ('size', self.new_volume.size),
528
- ('name', self.new_volume.name),
512
+ ('size', self.volume.size),
513
+ ('name', self.volume.name),
529
514
  ]
530
515
 
531
516
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
532
517
 
533
518
  columns, data = self.cmd.take_action(parsed_args)
534
519
 
535
- self.volumes_mock.create.assert_called_with(
536
- size=self.new_volume.size,
520
+ self.volume_sdk_client.create_volume.assert_called_with(
521
+ size=self.volume.size,
537
522
  snapshot_id=None,
538
- name=self.new_volume.name,
523
+ name=self.volume.name,
539
524
  description=None,
540
525
  volume_type=None,
541
526
  availability_zone=None,
542
527
  metadata=None,
543
- imageRef=None,
544
- source_volid=None,
545
- consistencygroup_id=None,
528
+ image_id=None,
529
+ source_volume_id=None,
530
+ consistency_group_id=None,
546
531
  scheduler_hints=None,
547
532
  )
548
533
 
549
534
  self.assertEqual(2, mock_error.call_count)
550
535
  self.assertEqual(self.columns, columns)
551
- self.assertCountEqual(self.datalist, data)
536
+ self.assertEqual(self.datalist, data)
552
537
 
553
538
  def test_volume_create_without_size(self):
554
539
  arglist = [
555
- self.new_volume.name,
540
+ self.volume.name,
556
541
  ]
557
542
  verifylist = [
558
- ('name', self.new_volume.name),
543
+ ('name', self.volume.name),
559
544
  ]
560
545
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
561
546
 
@@ -572,15 +557,15 @@ class TestVolumeCreate(TestVolume):
572
557
  '--snapshot',
573
558
  'source_snapshot',
574
559
  '--size',
575
- str(self.new_volume.size),
576
- self.new_volume.name,
560
+ str(self.volume.size),
561
+ self.volume.name,
577
562
  ]
578
563
  verifylist = [
579
564
  ('image', 'source_image'),
580
565
  ('source', 'source_volume'),
581
566
  ('snapshot', 'source_snapshot'),
582
- ('size', self.new_volume.size),
583
- ('name', self.new_volume.name),
567
+ ('size', self.volume.size),
568
+ ('name', self.volume.name),
584
569
  ]
585
570
 
586
571
  self.assertRaises(
@@ -599,7 +584,7 @@ class TestVolumeCreate(TestVolume):
599
584
  """
600
585
  arglist = [
601
586
  '--size',
602
- str(self.new_volume.size),
587
+ str(self.volume.size),
603
588
  '--hint',
604
589
  'k=v',
605
590
  '--hint',
@@ -614,10 +599,10 @@ class TestVolumeCreate(TestVolume):
614
599
  'local_to_instance=v6',
615
600
  '--hint',
616
601
  'different_host=v7',
617
- self.new_volume.name,
602
+ self.volume.name,
618
603
  ]
619
604
  verifylist = [
620
- ('size', self.new_volume.size),
605
+ ('size', self.volume.size),
621
606
  (
622
607
  'hint',
623
608
  {
@@ -627,26 +612,23 @@ class TestVolumeCreate(TestVolume):
627
612
  'different_host': ['v5', 'v7'],
628
613
  },
629
614
  ),
630
- ('name', self.new_volume.name),
615
+ ('name', self.volume.name),
631
616
  ]
632
617
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
633
618
 
634
- # In base command class ShowOne in cliff, abstract method take_action()
635
- # returns a two-part tuple with a tuple of column names and a tuple of
636
- # data to be shown.
637
619
  columns, data = self.cmd.take_action(parsed_args)
638
620
 
639
- self.volumes_mock.create.assert_called_with(
640
- size=self.new_volume.size,
621
+ self.volume_sdk_client.create_volume.assert_called_with(
622
+ size=self.volume.size,
641
623
  snapshot_id=None,
642
- name=self.new_volume.name,
624
+ name=self.volume.name,
643
625
  description=None,
644
626
  volume_type=None,
645
627
  availability_zone=None,
646
628
  metadata=None,
647
- imageRef=None,
648
- source_volid=None,
649
- consistencygroup_id=None,
629
+ image_id=None,
630
+ source_volume_id=None,
631
+ consistency_group_id=None,
650
632
  scheduler_hints={
651
633
  'k': 'v2',
652
634
  'same_host': ['v3', 'v4'],
@@ -656,7 +638,7 @@ class TestVolumeCreate(TestVolume):
656
638
  )
657
639
 
658
640
  self.assertEqual(self.columns, columns)
659
- self.assertCountEqual(self.datalist, data)
641
+ self.assertEqual(self.datalist, data)
660
642
 
661
643
 
662
644
  class TestVolumeDelete(volume_fakes.TestVolume):
@@ -1312,69 +1294,80 @@ class TestVolumeList(TestVolume):
1312
1294
  self.assertIn(self.mock_volume.name, each_volume)
1313
1295
 
1314
1296
 
1315
- class TestVolumeMigrate(TestVolume):
1316
- _volume = volume_fakes.create_one_volume()
1317
-
1297
+ class TestVolumeMigrate(volume_fakes.TestVolume):
1318
1298
  def setUp(self):
1319
1299
  super().setUp()
1320
1300
 
1321
- self.volumes_mock.get.return_value = self._volume
1322
- self.volumes_mock.migrate_volume.return_value = None
1323
- # 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
+
1324
1305
  self.cmd = volume.MigrateVolume(self.app, None)
1325
1306
 
1326
1307
  def test_volume_migrate(self):
1327
1308
  arglist = [
1328
1309
  "--host",
1329
1310
  "host@backend-name#pool",
1330
- self._volume.id,
1311
+ self.volume.id,
1331
1312
  ]
1332
1313
  verifylist = [
1333
1314
  ("force_host_copy", False),
1334
1315
  ("lock_volume", False),
1335
1316
  ("host", "host@backend-name#pool"),
1336
- ("volume", self._volume.id),
1317
+ ("volume", self.volume.id),
1337
1318
  ]
1338
1319
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1339
1320
 
1340
1321
  result = self.cmd.take_action(parsed_args)
1341
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1342
- self.volumes_mock.migrate_volume.assert_called_once_with(
1343
- self._volume.id, "host@backend-name#pool", False, False
1344
- )
1345
1322
  self.assertIsNone(result)
1346
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
+
1347
1334
  def test_volume_migrate_with_option(self):
1348
1335
  arglist = [
1349
1336
  "--force-host-copy",
1350
1337
  "--lock-volume",
1351
1338
  "--host",
1352
1339
  "host@backend-name#pool",
1353
- self._volume.id,
1340
+ self.volume.id,
1354
1341
  ]
1355
1342
  verifylist = [
1356
1343
  ("force_host_copy", True),
1357
1344
  ("lock_volume", True),
1358
1345
  ("host", "host@backend-name#pool"),
1359
- ("volume", self._volume.id),
1346
+ ("volume", self.volume.id),
1360
1347
  ]
1361
1348
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1362
1349
 
1363
1350
  result = self.cmd.take_action(parsed_args)
1364
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1365
- self.volumes_mock.migrate_volume.assert_called_once_with(
1366
- self._volume.id, "host@backend-name#pool", True, True
1367
- )
1368
1351
  self.assertIsNone(result)
1369
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
+
1370
1363
  def test_volume_migrate_without_host(self):
1371
1364
  arglist = [
1372
- self._volume.id,
1365
+ self.volume.id,
1373
1366
  ]
1374
1367
  verifylist = [
1375
1368
  ("force_host_copy", False),
1376
1369
  ("lock_volume", False),
1377
- ("volume", self._volume.id),
1370
+ ("volume", self.volume.id),
1378
1371
  ]
1379
1372
 
1380
1373
  self.assertRaises(
@@ -1385,6 +1378,9 @@ class TestVolumeMigrate(TestVolume):
1385
1378
  verifylist,
1386
1379
  )
1387
1380
 
1381
+ self.volume_sdk_client.find_volume.assert_not_called()
1382
+ self.volume_sdk_client.migrate_volume.assert_not_called()
1383
+
1388
1384
 
1389
1385
  class TestVolumeSet(TestVolume):
1390
1386
  volume_type = volume_fakes.create_one_volume_type()
@@ -1627,42 +1623,83 @@ class TestVolumeSet(TestVolume):
1627
1623
  self.assertIsNone(result)
1628
1624
 
1629
1625
 
1630
- class TestVolumeShow(TestVolume):
1626
+ class TestVolumeShow(volume_fakes.TestVolume):
1631
1627
  def setUp(self):
1632
1628
  super().setUp()
1633
1629
 
1634
- self._volume = volume_fakes.create_one_volume()
1635
- self.volumes_mock.get.return_value = self._volume
1636
- # 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
+
1637
1690
  self.cmd = volume.ShowVolume(self.app, None)
1638
1691
 
1639
1692
  def test_volume_show(self):
1640
- arglist = [self._volume.id]
1641
- verifylist = [("volume", self._volume.id)]
1693
+ arglist = [self.volume.id]
1694
+ verifylist = [("volume", self.volume.id)]
1642
1695
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1643
1696
 
1644
1697
  columns, data = self.cmd.take_action(parsed_args)
1645
- self.volumes_mock.get.assert_called_with(self._volume.id)
1646
1698
 
1647
- self.assertEqual(
1648
- tuple(sorted(self._volume.keys())),
1649
- columns,
1650
- )
1651
- self.assertTupleEqual(
1652
- (
1653
- self._volume.attachments,
1654
- self._volume.availability_zone,
1655
- self._volume.bootable,
1656
- self._volume.description,
1657
- self._volume.id,
1658
- self._volume.name,
1659
- format_columns.DictColumn(self._volume.metadata),
1660
- self._volume.size,
1661
- self._volume.snapshot_id,
1662
- self._volume.status,
1663
- self._volume.volume_type,
1664
- ),
1665
- 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
1666
1703
  )
1667
1704
 
1668
1705
 
@@ -1753,31 +1790,47 @@ class TestVolumeUnset(TestVolume):
1753
1790
  )
1754
1791
 
1755
1792
 
1756
- class TestColumns(TestVolume):
1793
+ class TestColumns(volume_fakes.TestVolume):
1757
1794
  def test_attachments_column_without_server_cache(self):
1758
- _volume = volume_fakes.create_one_volume()
1759
- server_id = _volume.attachments[0]['server_id']
1760
- 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']
1761
1806
 
1762
- col = volume.AttachmentsColumn(_volume.attachments, {})
1807
+ col = volume.AttachmentsColumn(vol.attachments, {})
1763
1808
  self.assertEqual(
1764
1809
  f'Attached to {server_id} on {device} ',
1765
1810
  col.human_readable(),
1766
1811
  )
1767
- self.assertEqual(_volume.attachments, col.machine_readable())
1812
+ self.assertEqual(vol.attachments, col.machine_readable())
1768
1813
 
1769
1814
  def test_attachments_column_with_server_cache(self):
1770
- _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
+ )
1771
1824
 
1772
- server_id = _volume.attachments[0]['server_id']
1773
- device = _volume.attachments[0]['device']
1825
+ server_id = vol.attachments[0]['server_id']
1826
+ device = vol.attachments[0]['device']
1774
1827
  fake_server = mock.Mock()
1775
1828
  fake_server.name = 'fake-server-name'
1776
1829
  server_cache = {server_id: fake_server}
1777
1830
 
1778
- col = volume.AttachmentsColumn(_volume.attachments, server_cache)
1831
+ col = volume.AttachmentsColumn(vol.attachments, server_cache)
1779
1832
  self.assertEqual(
1780
1833
  'Attached to {} on {} '.format('fake-server-name', device),
1781
1834
  col.human_readable(),
1782
1835
  )
1783
- self.assertEqual(_volume.attachments, col.machine_readable())
1836
+ self.assertEqual(vol.attachments, col.machine_readable())