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
@@ -13,15 +13,19 @@
13
13
 
14
14
  import copy
15
15
  from unittest import mock
16
+ import uuid
16
17
 
18
+ from openstack.block_storage.v3 import backup as _backup
17
19
  from openstack.block_storage.v3 import block_storage_summary as _summary
18
20
  from openstack.block_storage.v3 import snapshot as _snapshot
19
21
  from openstack.block_storage.v3 import volume as _volume
22
+ from openstack import exceptions as sdk_exceptions
20
23
  from openstack.test import fakes as sdk_fakes
21
24
  from osc_lib.cli import format_columns
22
25
  from osc_lib import exceptions
23
26
  from osc_lib import utils
24
27
 
28
+ from openstackclient.api import volume_v3
25
29
  from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
26
30
  from openstackclient.tests.unit.image.v2 import fakes as image_fakes
27
31
  from openstackclient.tests.unit import utils as test_utils
@@ -29,55 +33,81 @@ from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
29
33
  from openstackclient.volume.v3 import volume
30
34
 
31
35
 
32
- # TODO(stephenfin): Combine these two test classes
33
- class TestVolumeCreateLegacy(volume_fakes.TestVolume):
34
- project = identity_fakes.FakeProject.create_one_project()
35
- user = identity_fakes.FakeUser.create_one_user()
36
-
36
+ class TestVolumeCreate(volume_fakes.TestVolume):
37
37
  columns = (
38
38
  'attachments',
39
39
  'availability_zone',
40
40
  'bootable',
41
+ 'cluster_name',
42
+ 'consistencygroup_id',
43
+ 'consumes_quota',
44
+ 'created_at',
41
45
  'description',
46
+ 'encrypted',
47
+ 'encryption_key_id',
48
+ 'group_id',
42
49
  'id',
50
+ 'multiattach',
43
51
  'name',
52
+ 'os-vol-host-attr:host',
53
+ 'os-vol-mig-status-attr:migstat',
54
+ 'os-vol-mig-status-attr:name_id',
55
+ 'os-vol-tenant-attr:tenant_id',
44
56
  'properties',
57
+ 'provider_id',
58
+ 'replication_status',
59
+ 'service_uuid',
60
+ 'shared_targets',
45
61
  'size',
46
62
  'snapshot_id',
63
+ 'source_volid',
47
64
  'status',
48
65
  'type',
66
+ 'updated_at',
67
+ 'user_id',
68
+ 'volume_image_metadata',
69
+ 'volume_type_id',
49
70
  )
50
71
 
51
72
  def setUp(self):
52
73
  super().setUp()
53
74
 
54
- self.volumes_mock = self.volume_client.volumes
55
- self.volumes_mock.reset_mock()
56
-
57
- self.consistencygroups_mock = self.volume_client.consistencygroups
58
- self.consistencygroups_mock.reset_mock()
59
-
60
- self.snapshots_mock = self.volume_client.volume_snapshots
61
- self.snapshots_mock.reset_mock()
62
-
63
- self.backups_mock = self.volume_client.backups
64
- self.backups_mock.reset_mock()
65
-
66
- self.new_volume = volume_fakes.create_one_volume()
67
- self.volumes_mock.create.return_value = self.new_volume
75
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
76
+ self.volume_sdk_client.create_volume.return_value = self.volume
68
77
 
69
78
  self.datalist = (
70
- self.new_volume.attachments,
71
- self.new_volume.availability_zone,
72
- self.new_volume.bootable,
73
- self.new_volume.description,
74
- self.new_volume.id,
75
- self.new_volume.name,
76
- format_columns.DictColumn(self.new_volume.metadata),
77
- self.new_volume.size,
78
- self.new_volume.snapshot_id,
79
- self.new_volume.status,
80
- self.new_volume.volume_type,
79
+ self.volume.attachments,
80
+ self.volume.availability_zone,
81
+ self.volume.is_bootable,
82
+ self.volume.cluster_name,
83
+ self.volume.consistency_group_id,
84
+ self.volume.consumes_quota,
85
+ self.volume.created_at,
86
+ self.volume.description,
87
+ self.volume.is_encrypted,
88
+ self.volume.encryption_key_id,
89
+ self.volume.group_id,
90
+ self.volume.id,
91
+ self.volume.is_multiattach,
92
+ self.volume.name,
93
+ self.volume.host,
94
+ self.volume.migration_status,
95
+ self.volume.migration_id,
96
+ self.volume.project_id,
97
+ format_columns.DictColumn(self.volume.metadata),
98
+ self.volume.provider_id,
99
+ self.volume.replication_status,
100
+ self.volume.service_uuid,
101
+ self.volume.shared_targets,
102
+ self.volume.size,
103
+ self.volume.snapshot_id,
104
+ self.volume.source_volume_id,
105
+ self.volume.status,
106
+ self.volume.volume_type,
107
+ self.volume.updated_at,
108
+ self.volume.user_id,
109
+ self.volume.volume_image_metadata,
110
+ self.volume.volume_type_id,
81
111
  )
82
112
 
83
113
  # Get the command object to test
@@ -86,87 +116,88 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
86
116
  def test_volume_create_min_options(self):
87
117
  arglist = [
88
118
  '--size',
89
- str(self.new_volume.size),
119
+ str(self.volume.size),
90
120
  ]
91
121
  verifylist = [
92
- ('size', self.new_volume.size),
122
+ ('size', self.volume.size),
93
123
  ]
94
124
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
95
125
 
96
- # In base command class ShowOne in cliff, abstract method take_action()
97
- # returns a two-part tuple with a tuple of column names and a tuple of
98
- # data to be shown.
99
126
  columns, data = self.cmd.take_action(parsed_args)
100
127
 
101
- self.volumes_mock.create.assert_called_with(
102
- size=self.new_volume.size,
128
+ self.volume_sdk_client.create_volume.assert_called_with(
129
+ size=self.volume.size,
103
130
  snapshot_id=None,
104
131
  name=None,
105
132
  description=None,
106
133
  volume_type=None,
107
134
  availability_zone=None,
108
135
  metadata=None,
109
- imageRef=None,
110
- source_volid=None,
111
- consistencygroup_id=None,
136
+ image_id=None,
137
+ source_volume_id=None,
138
+ consistency_group_id=None,
112
139
  scheduler_hints=None,
113
140
  backup_id=None,
114
141
  )
115
142
 
116
143
  self.assertEqual(self.columns, columns)
117
- self.assertCountEqual(self.datalist, data)
144
+ self.assertEqual(self.datalist, data)
118
145
 
119
146
  def test_volume_create_options(self):
120
- consistency_group = volume_fakes.create_one_consistency_group()
121
- self.consistencygroups_mock.get.return_value = consistency_group
147
+ consistency_group_id = 'cg123'
122
148
  arglist = [
123
149
  '--size',
124
- str(self.new_volume.size),
150
+ str(self.volume.size),
125
151
  '--description',
126
- self.new_volume.description,
152
+ self.volume.description,
127
153
  '--type',
128
- self.new_volume.volume_type,
154
+ self.volume.volume_type,
129
155
  '--availability-zone',
130
- self.new_volume.availability_zone,
156
+ self.volume.availability_zone,
131
157
  '--consistency-group',
132
- consistency_group.id,
158
+ consistency_group_id,
133
159
  '--hint',
134
160
  'k=v',
135
- self.new_volume.name,
161
+ self.volume.name,
136
162
  ]
137
163
  verifylist = [
138
- ('size', self.new_volume.size),
139
- ('description', self.new_volume.description),
140
- ('type', self.new_volume.volume_type),
141
- ('availability_zone', self.new_volume.availability_zone),
142
- ('consistency_group', consistency_group.id),
164
+ ('size', self.volume.size),
165
+ ('description', self.volume.description),
166
+ ('type', self.volume.volume_type),
167
+ ('availability_zone', self.volume.availability_zone),
168
+ ('consistency_group', consistency_group_id),
143
169
  ('hint', {'k': 'v'}),
144
- ('name', self.new_volume.name),
170
+ ('name', self.volume.name),
145
171
  ]
146
172
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
147
173
 
148
- # In base command class ShowOne in cliff, abstract method take_action()
149
- # returns a two-part tuple with a tuple of column names and a tuple of
150
- # data to be shown.
151
- columns, data = self.cmd.take_action(parsed_args)
152
-
153
- self.volumes_mock.create.assert_called_with(
154
- size=self.new_volume.size,
174
+ with mock.patch.object(
175
+ volume_v3,
176
+ 'find_consistency_group',
177
+ return_value={'id': consistency_group_id},
178
+ ) as mock_find_cg:
179
+ columns, data = self.cmd.take_action(parsed_args)
180
+
181
+ self.volume_sdk_client.create_volume.assert_called_with(
182
+ size=self.volume.size,
155
183
  snapshot_id=None,
156
- name=self.new_volume.name,
157
- description=self.new_volume.description,
158
- volume_type=self.new_volume.volume_type,
159
- availability_zone=self.new_volume.availability_zone,
184
+ name=self.volume.name,
185
+ description=self.volume.description,
186
+ volume_type=self.volume.volume_type,
187
+ availability_zone=self.volume.availability_zone,
160
188
  metadata=None,
161
- imageRef=None,
162
- source_volid=None,
163
- consistencygroup_id=consistency_group.id,
189
+ image_id=None,
190
+ source_volume_id=None,
191
+ consistency_group_id=consistency_group_id,
164
192
  scheduler_hints={'k': 'v'},
165
193
  backup_id=None,
166
194
  )
195
+ mock_find_cg.assert_called_once_with(
196
+ self.volume_sdk_client, consistency_group_id
197
+ )
167
198
 
168
199
  self.assertEqual(self.columns, columns)
169
- self.assertCountEqual(self.datalist, data)
200
+ self.assertEqual(self.datalist, data)
170
201
 
171
202
  def test_volume_create_properties(self):
172
203
  arglist = [
@@ -175,38 +206,35 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
175
206
  '--property',
176
207
  'Beta=b',
177
208
  '--size',
178
- str(self.new_volume.size),
179
- self.new_volume.name,
209
+ str(self.volume.size),
210
+ self.volume.name,
180
211
  ]
181
212
  verifylist = [
182
- ('property', {'Alpha': 'a', 'Beta': 'b'}),
183
- ('size', self.new_volume.size),
184
- ('name', self.new_volume.name),
213
+ ('properties', {'Alpha': 'a', 'Beta': 'b'}),
214
+ ('size', self.volume.size),
215
+ ('name', self.volume.name),
185
216
  ]
186
217
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
187
218
 
188
- # In base command class ShowOne in cliff, abstract method take_action()
189
- # returns a two-part tuple with a tuple of column names and a tuple of
190
- # data to be shown.
191
219
  columns, data = self.cmd.take_action(parsed_args)
192
220
 
193
- self.volumes_mock.create.assert_called_with(
194
- size=self.new_volume.size,
221
+ self.volume_sdk_client.create_volume.assert_called_with(
222
+ size=self.volume.size,
195
223
  snapshot_id=None,
196
- name=self.new_volume.name,
224
+ name=self.volume.name,
197
225
  description=None,
198
226
  volume_type=None,
199
227
  availability_zone=None,
200
228
  metadata={'Alpha': 'a', 'Beta': 'b'},
201
- imageRef=None,
202
- source_volid=None,
203
- consistencygroup_id=None,
229
+ image_id=None,
230
+ source_volume_id=None,
231
+ consistency_group_id=None,
204
232
  scheduler_hints=None,
205
233
  backup_id=None,
206
234
  )
207
235
 
208
236
  self.assertEqual(self.columns, columns)
209
- self.assertCountEqual(self.datalist, data)
237
+ self.assertEqual(self.datalist, data)
210
238
 
211
239
  def test_volume_create_image_id(self):
212
240
  image = image_fakes.create_one_image()
@@ -216,38 +244,35 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
216
244
  '--image',
217
245
  image.id,
218
246
  '--size',
219
- str(self.new_volume.size),
220
- self.new_volume.name,
247
+ str(self.volume.size),
248
+ self.volume.name,
221
249
  ]
222
250
  verifylist = [
223
251
  ('image', image.id),
224
- ('size', self.new_volume.size),
225
- ('name', self.new_volume.name),
252
+ ('size', self.volume.size),
253
+ ('name', self.volume.name),
226
254
  ]
227
255
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
228
256
 
229
- # In base command class ShowOne in cliff, abstract method take_action()
230
- # returns a two-part tuple with a tuple of column names and a tuple of
231
- # data to be shown.
232
257
  columns, data = self.cmd.take_action(parsed_args)
233
258
 
234
- self.volumes_mock.create.assert_called_with(
235
- size=self.new_volume.size,
259
+ self.volume_sdk_client.create_volume.assert_called_with(
260
+ size=self.volume.size,
236
261
  snapshot_id=None,
237
- name=self.new_volume.name,
262
+ name=self.volume.name,
238
263
  description=None,
239
264
  volume_type=None,
240
265
  availability_zone=None,
241
266
  metadata=None,
242
- imageRef=image.id,
243
- source_volid=None,
244
- consistencygroup_id=None,
267
+ image_id=image.id,
268
+ source_volume_id=None,
269
+ consistency_group_id=None,
245
270
  scheduler_hints=None,
246
271
  backup_id=None,
247
272
  )
248
273
 
249
274
  self.assertEqual(self.columns, columns)
250
- self.assertCountEqual(self.datalist, data)
275
+ self.assertEqual(self.datalist, data)
251
276
 
252
277
  def test_volume_create_image_name(self):
253
278
  image = image_fakes.create_one_image()
@@ -257,177 +282,173 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
257
282
  '--image',
258
283
  image.name,
259
284
  '--size',
260
- str(self.new_volume.size),
261
- self.new_volume.name,
285
+ str(self.volume.size),
286
+ self.volume.name,
262
287
  ]
263
288
  verifylist = [
264
289
  ('image', image.name),
265
- ('size', self.new_volume.size),
266
- ('name', self.new_volume.name),
290
+ ('size', self.volume.size),
291
+ ('name', self.volume.name),
267
292
  ]
268
293
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
269
294
 
270
- # In base command class ShowOne in cliff, abstract method take_action()
271
- # returns a two-part tuple with a tuple of column names and a tuple of
272
- # data to be shown.
273
295
  columns, data = self.cmd.take_action(parsed_args)
274
296
 
275
- self.volumes_mock.create.assert_called_with(
276
- size=self.new_volume.size,
297
+ self.volume_sdk_client.create_volume.assert_called_with(
298
+ size=self.volume.size,
277
299
  snapshot_id=None,
278
- name=self.new_volume.name,
300
+ name=self.volume.name,
279
301
  description=None,
280
302
  volume_type=None,
281
303
  availability_zone=None,
282
304
  metadata=None,
283
- imageRef=image.id,
284
- source_volid=None,
285
- consistencygroup_id=None,
305
+ image_id=image.id,
306
+ source_volume_id=None,
307
+ consistency_group_id=None,
286
308
  scheduler_hints=None,
287
309
  backup_id=None,
288
310
  )
289
311
 
290
312
  self.assertEqual(self.columns, columns)
291
- self.assertCountEqual(self.datalist, data)
313
+ self.assertEqual(self.datalist, data)
292
314
 
293
315
  def test_volume_create_with_snapshot(self):
294
- snapshot = volume_fakes.create_one_snapshot()
295
- self.new_volume.snapshot_id = snapshot.id
316
+ snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
317
+ self.volume_sdk_client.find_snapshot.return_value = snapshot
318
+
296
319
  arglist = [
297
320
  '--snapshot',
298
- self.new_volume.snapshot_id,
299
- self.new_volume.name,
321
+ snapshot.id,
322
+ self.volume.name,
300
323
  ]
301
324
  verifylist = [
302
- ('snapshot', self.new_volume.snapshot_id),
303
- ('name', self.new_volume.name),
325
+ ('snapshot', snapshot.id),
326
+ ('name', self.volume.name),
304
327
  ]
305
328
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
306
329
 
307
- self.snapshots_mock.get.return_value = snapshot
308
-
309
- # In base command class ShowOne in cliff, abstract method take_action()
310
- # returns a two-part tuple with a tuple of column names and a tuple of
311
- # data to be shown.
312
330
  columns, data = self.cmd.take_action(parsed_args)
313
331
 
314
- self.volumes_mock.create.assert_called_once_with(
332
+ self.volume_sdk_client.create_volume.assert_called_with(
315
333
  size=snapshot.size,
316
334
  snapshot_id=snapshot.id,
317
- name=self.new_volume.name,
335
+ name=self.volume.name,
318
336
  description=None,
319
337
  volume_type=None,
320
338
  availability_zone=None,
321
339
  metadata=None,
322
- imageRef=None,
323
- source_volid=None,
324
- consistencygroup_id=None,
340
+ image_id=None,
341
+ source_volume_id=None,
342
+ consistency_group_id=None,
325
343
  scheduler_hints=None,
326
344
  backup_id=None,
327
345
  )
346
+ self.volume_sdk_client.find_snapshot.assert_called_once_with(
347
+ snapshot.id, ignore_missing=False
348
+ )
328
349
 
329
350
  self.assertEqual(self.columns, columns)
330
- self.assertCountEqual(self.datalist, data)
351
+ self.assertEqual(self.datalist, data)
331
352
 
332
353
  def test_volume_create_with_backup(self):
333
354
  self.set_volume_api_version('3.47')
334
355
 
335
- backup = volume_fakes.create_one_backup()
336
- self.new_volume.backup_id = backup.id
356
+ backup = sdk_fakes.generate_fake_resource(_backup.Backup)
357
+ self.volume_sdk_client.find_backup.return_value = backup
358
+
337
359
  arglist = [
338
360
  '--backup',
339
- self.new_volume.backup_id,
340
- self.new_volume.name,
361
+ backup.id,
362
+ self.volume.name,
341
363
  ]
342
364
  verifylist = [
343
- ('backup', self.new_volume.backup_id),
344
- ('name', self.new_volume.name),
365
+ ('backup', backup.id),
366
+ ('name', self.volume.name),
345
367
  ]
346
368
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
347
369
 
348
- self.backups_mock.get.return_value = backup
349
-
350
- # In base command class ShowOne in cliff, abstract method take_action()
351
- # returns a two-part tuple with a tuple of column names and a tuple of
352
- # data to be shown.
353
370
  columns, data = self.cmd.take_action(parsed_args)
354
371
 
355
- self.volumes_mock.create.assert_called_once_with(
372
+ self.volume_sdk_client.create_volume.assert_called_with(
356
373
  size=backup.size,
357
374
  snapshot_id=None,
358
- name=self.new_volume.name,
375
+ name=self.volume.name,
359
376
  description=None,
360
377
  volume_type=None,
361
378
  availability_zone=None,
362
379
  metadata=None,
363
- imageRef=None,
364
- source_volid=None,
365
- consistencygroup_id=None,
380
+ image_id=None,
381
+ source_volume_id=None,
382
+ consistency_group_id=None,
366
383
  scheduler_hints=None,
367
384
  backup_id=backup.id,
368
385
  )
386
+ self.volume_sdk_client.find_backup.assert_called_once_with(
387
+ backup.id, ignore_missing=False
388
+ )
369
389
 
370
390
  self.assertEqual(self.columns, columns)
371
- self.assertCountEqual(self.datalist, data)
391
+ self.assertEqual(self.datalist, data)
372
392
 
373
393
  def test_volume_create_with_backup_pre_v347(self):
374
- backup = volume_fakes.create_one_backup()
375
- self.new_volume.backup_id = backup.id
394
+ backup = sdk_fakes.generate_fake_resource(_backup.Backup)
395
+ self.volume_sdk_client.find_backup.return_value = backup
396
+
376
397
  arglist = [
377
398
  '--backup',
378
- self.new_volume.backup_id,
379
- self.new_volume.name,
399
+ backup.id,
400
+ self.volume.name,
380
401
  ]
381
402
  verifylist = [
382
- ('backup', self.new_volume.backup_id),
383
- ('name', self.new_volume.name),
403
+ ('backup', backup.id),
404
+ ('name', self.volume.name),
384
405
  ]
385
406
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
386
407
 
387
- self.backups_mock.get.return_value = backup
388
-
389
408
  exc = self.assertRaises(
390
409
  exceptions.CommandError, self.cmd.take_action, parsed_args
391
410
  )
392
411
  self.assertIn("--os-volume-api-version 3.47 or greater", str(exc))
393
412
 
413
+ self.volume_sdk_client.create_volume.assert_not_called()
414
+
394
415
  def test_volume_create_with_source_volume(self):
395
- source_vol = "source_vol"
416
+ source_volume = sdk_fakes.generate_fake_resource(_volume.Volume)
417
+ self.volume_sdk_client.find_volume.return_value = source_volume
418
+
396
419
  arglist = [
397
420
  '--source',
398
- self.new_volume.id,
399
- source_vol,
421
+ source_volume.id,
422
+ self.volume.name,
400
423
  ]
401
424
  verifylist = [
402
- ('source', self.new_volume.id),
403
- ('name', source_vol),
425
+ ('source', source_volume.id),
426
+ ('name', self.volume.name),
404
427
  ]
405
428
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
406
429
 
407
- self.volumes_mock.get.return_value = self.new_volume
408
-
409
- # In base command class ShowOne in cliff, abstract method take_action()
410
- # returns a two-part tuple with a tuple of column names and a tuple of
411
- # data to be shown.
412
430
  columns, data = self.cmd.take_action(parsed_args)
413
431
 
414
- self.volumes_mock.create.assert_called_once_with(
415
- size=self.new_volume.size,
432
+ self.volume_sdk_client.create_volume.assert_called_with(
433
+ size=source_volume.size,
416
434
  snapshot_id=None,
417
- name=source_vol,
435
+ name=self.volume.name,
418
436
  description=None,
419
437
  volume_type=None,
420
438
  availability_zone=None,
421
439
  metadata=None,
422
- imageRef=None,
423
- source_volid=self.new_volume.id,
424
- consistencygroup_id=None,
440
+ image_id=None,
441
+ source_volume_id=source_volume.id,
442
+ consistency_group_id=None,
425
443
  scheduler_hints=None,
426
444
  backup_id=None,
427
445
  )
446
+ self.volume_sdk_client.find_volume.assert_called_once_with(
447
+ source_volume.id, ignore_missing=False
448
+ )
428
449
 
429
450
  self.assertEqual(self.columns, columns)
430
- self.assertCountEqual(self.datalist, data)
451
+ self.assertEqual(self.datalist, data)
431
452
 
432
453
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
433
454
  def test_volume_create_with_bootable_and_readonly(self, mock_wait):
@@ -435,200 +456,191 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
435
456
  '--bootable',
436
457
  '--read-only',
437
458
  '--size',
438
- str(self.new_volume.size),
439
- self.new_volume.name,
459
+ str(self.volume.size),
460
+ self.volume.name,
440
461
  ]
441
462
  verifylist = [
442
463
  ('bootable', True),
443
- ('non_bootable', False),
444
464
  ('read_only', True),
445
- ('read_write', False),
446
- ('size', self.new_volume.size),
447
- ('name', self.new_volume.name),
465
+ ('size', self.volume.size),
466
+ ('name', self.volume.name),
448
467
  ]
449
468
 
450
469
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
451
470
 
452
471
  columns, data = self.cmd.take_action(parsed_args)
453
472
 
454
- self.volumes_mock.create.assert_called_with(
455
- size=self.new_volume.size,
473
+ self.volume_sdk_client.create_volume.assert_called_with(
474
+ size=self.volume.size,
456
475
  snapshot_id=None,
457
- name=self.new_volume.name,
476
+ name=self.volume.name,
458
477
  description=None,
459
478
  volume_type=None,
460
479
  availability_zone=None,
461
480
  metadata=None,
462
- imageRef=None,
463
- source_volid=None,
464
- consistencygroup_id=None,
481
+ image_id=None,
482
+ source_volume_id=None,
483
+ consistency_group_id=None,
465
484
  scheduler_hints=None,
466
485
  backup_id=None,
467
486
  )
468
-
469
- self.assertEqual(self.columns, columns)
470
- self.assertCountEqual(self.datalist, data)
471
- self.volumes_mock.set_bootable.assert_called_with(
472
- self.new_volume.id, True
487
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
488
+ self.volume, True
473
489
  )
474
- self.volumes_mock.update_readonly_flag.assert_called_with(
475
- self.new_volume.id, True
490
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
491
+ self.volume, True
476
492
  )
477
493
 
494
+ self.assertEqual(self.columns, columns)
495
+ self.assertEqual(self.datalist, data)
496
+
478
497
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
479
498
  def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
480
499
  arglist = [
481
500
  '--non-bootable',
482
501
  '--read-write',
483
502
  '--size',
484
- str(self.new_volume.size),
485
- self.new_volume.name,
503
+ str(self.volume.size),
504
+ self.volume.name,
486
505
  ]
487
506
  verifylist = [
488
507
  ('bootable', False),
489
- ('non_bootable', True),
490
508
  ('read_only', False),
491
- ('read_write', True),
492
- ('size', self.new_volume.size),
493
- ('name', self.new_volume.name),
509
+ ('size', self.volume.size),
510
+ ('name', self.volume.name),
494
511
  ]
495
512
 
496
513
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
497
514
 
498
515
  columns, data = self.cmd.take_action(parsed_args)
499
516
 
500
- self.volumes_mock.create.assert_called_with(
501
- size=self.new_volume.size,
517
+ self.volume_sdk_client.create_volume.assert_called_with(
518
+ size=self.volume.size,
502
519
  snapshot_id=None,
503
- name=self.new_volume.name,
520
+ name=self.volume.name,
504
521
  description=None,
505
522
  volume_type=None,
506
523
  availability_zone=None,
507
524
  metadata=None,
508
- imageRef=None,
509
- source_volid=None,
510
- consistencygroup_id=None,
525
+ image_id=None,
526
+ source_volume_id=None,
527
+ consistency_group_id=None,
511
528
  scheduler_hints=None,
512
529
  backup_id=None,
513
530
  )
514
-
515
- self.assertEqual(self.columns, columns)
516
- self.assertCountEqual(self.datalist, data)
517
- self.volumes_mock.set_bootable.assert_called_with(
518
- self.new_volume.id, False
531
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
532
+ self.volume, False
519
533
  )
520
- self.volumes_mock.update_readonly_flag.assert_called_with(
521
- self.new_volume.id, False
534
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
535
+ self.volume, False
522
536
  )
523
537
 
538
+ self.assertEqual(self.columns, columns)
539
+ self.assertEqual(self.datalist, data)
540
+
524
541
  @mock.patch.object(volume.LOG, 'error')
525
542
  @mock.patch.object(utils, 'wait_for_status', return_value=True)
526
543
  def test_volume_create_with_bootable_and_readonly_fail(
527
544
  self, mock_wait, mock_error
528
545
  ):
529
- self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
530
-
531
- self.volumes_mock.update_readonly_flag.side_effect = (
532
- exceptions.CommandError()
546
+ self.volume_sdk_client.set_volume_bootable_status.side_effect = (
547
+ sdk_exceptions.NotFoundException('foo')
548
+ )
549
+ self.volume_sdk_client.set_volume_readonly.side_effect = (
550
+ sdk_exceptions.NotFoundException('foo')
533
551
  )
534
552
 
535
553
  arglist = [
536
554
  '--bootable',
537
555
  '--read-only',
538
556
  '--size',
539
- str(self.new_volume.size),
540
- self.new_volume.name,
557
+ str(self.volume.size),
558
+ self.volume.name,
541
559
  ]
542
560
  verifylist = [
543
561
  ('bootable', True),
544
- ('non_bootable', False),
545
562
  ('read_only', True),
546
- ('read_write', False),
547
- ('size', self.new_volume.size),
548
- ('name', self.new_volume.name),
563
+ ('size', self.volume.size),
564
+ ('name', self.volume.name),
549
565
  ]
550
566
 
551
567
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
552
568
 
553
569
  columns, data = self.cmd.take_action(parsed_args)
554
570
 
555
- self.volumes_mock.create.assert_called_with(
556
- size=self.new_volume.size,
571
+ self.volume_sdk_client.create_volume.assert_called_with(
572
+ size=self.volume.size,
557
573
  snapshot_id=None,
558
- name=self.new_volume.name,
574
+ name=self.volume.name,
559
575
  description=None,
560
576
  volume_type=None,
561
577
  availability_zone=None,
562
578
  metadata=None,
563
- imageRef=None,
564
- source_volid=None,
565
- consistencygroup_id=None,
579
+ image_id=None,
580
+ source_volume_id=None,
581
+ consistency_group_id=None,
566
582
  scheduler_hints=None,
567
583
  backup_id=None,
568
584
  )
585
+ self.volume_sdk_client.set_volume_bootable_status.assert_called_once_with(
586
+ self.volume, True
587
+ )
588
+ self.volume_sdk_client.set_volume_readonly.assert_called_once_with(
589
+ self.volume, True
590
+ )
569
591
 
570
592
  self.assertEqual(2, mock_error.call_count)
571
593
  self.assertEqual(self.columns, columns)
572
- self.assertCountEqual(self.datalist, data)
573
- self.volumes_mock.set_bootable.assert_called_with(
574
- self.new_volume.id, True
575
- )
576
- self.volumes_mock.update_readonly_flag.assert_called_with(
577
- self.new_volume.id, True
578
- )
594
+ self.assertEqual(self.datalist, data)
579
595
 
580
596
  @mock.patch.object(volume.LOG, 'error')
581
597
  @mock.patch.object(utils, 'wait_for_status', return_value=False)
582
598
  def test_volume_create_non_available_with_readonly(
583
- self,
584
- mock_wait,
585
- mock_error,
599
+ self, mock_wait, mock_error
586
600
  ):
587
601
  arglist = [
588
602
  '--non-bootable',
589
603
  '--read-only',
590
604
  '--size',
591
- str(self.new_volume.size),
592
- self.new_volume.name,
605
+ str(self.volume.size),
606
+ self.volume.name,
593
607
  ]
594
608
  verifylist = [
595
609
  ('bootable', False),
596
- ('non_bootable', True),
597
610
  ('read_only', True),
598
- ('read_write', False),
599
- ('size', self.new_volume.size),
600
- ('name', self.new_volume.name),
611
+ ('size', self.volume.size),
612
+ ('name', self.volume.name),
601
613
  ]
602
614
 
603
615
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
604
616
 
605
617
  columns, data = self.cmd.take_action(parsed_args)
606
618
 
607
- self.volumes_mock.create.assert_called_with(
608
- size=self.new_volume.size,
619
+ self.volume_sdk_client.create_volume.assert_called_with(
620
+ size=self.volume.size,
609
621
  snapshot_id=None,
610
- name=self.new_volume.name,
622
+ name=self.volume.name,
611
623
  description=None,
612
624
  volume_type=None,
613
625
  availability_zone=None,
614
626
  metadata=None,
615
- imageRef=None,
616
- source_volid=None,
617
- consistencygroup_id=None,
627
+ image_id=None,
628
+ source_volume_id=None,
629
+ consistency_group_id=None,
618
630
  scheduler_hints=None,
619
631
  backup_id=None,
620
632
  )
621
633
 
622
634
  self.assertEqual(2, mock_error.call_count)
623
635
  self.assertEqual(self.columns, columns)
624
- self.assertCountEqual(self.datalist, data)
636
+ self.assertEqual(self.datalist, data)
625
637
 
626
638
  def test_volume_create_without_size(self):
627
639
  arglist = [
628
- self.new_volume.name,
640
+ self.volume.name,
629
641
  ]
630
642
  verifylist = [
631
- ('name', self.new_volume.name),
643
+ ('name', self.volume.name),
632
644
  ]
633
645
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
634
646
 
@@ -645,15 +657,15 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
645
657
  '--snapshot',
646
658
  'source_snapshot',
647
659
  '--size',
648
- str(self.new_volume.size),
649
- self.new_volume.name,
660
+ str(self.volume.size),
661
+ self.volume.name,
650
662
  ]
651
663
  verifylist = [
652
664
  ('image', 'source_image'),
653
665
  ('source', 'source_volume'),
654
666
  ('snapshot', 'source_snapshot'),
655
- ('size', self.new_volume.size),
656
- ('name', self.new_volume.name),
667
+ ('size', self.volume.size),
668
+ ('name', self.volume.name),
657
669
  ]
658
670
 
659
671
  self.assertRaises(
@@ -672,7 +684,7 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
672
684
  """
673
685
  arglist = [
674
686
  '--size',
675
- str(self.new_volume.size),
687
+ str(self.volume.size),
676
688
  '--hint',
677
689
  'k=v',
678
690
  '--hint',
@@ -687,10 +699,10 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
687
699
  'local_to_instance=v6',
688
700
  '--hint',
689
701
  'different_host=v7',
690
- self.new_volume.name,
702
+ self.volume.name,
691
703
  ]
692
704
  verifylist = [
693
- ('size', self.new_volume.size),
705
+ ('size', self.volume.size),
694
706
  (
695
707
  'hint',
696
708
  {
@@ -700,26 +712,23 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
700
712
  'different_host': ['v5', 'v7'],
701
713
  },
702
714
  ),
703
- ('name', self.new_volume.name),
715
+ ('name', self.volume.name),
704
716
  ]
705
717
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
706
718
 
707
- # In base command class ShowOne in cliff, abstract method take_action()
708
- # returns a two-part tuple with a tuple of column names and a tuple of
709
- # data to be shown.
710
719
  columns, data = self.cmd.take_action(parsed_args)
711
720
 
712
- self.volumes_mock.create.assert_called_with(
713
- size=self.new_volume.size,
721
+ self.volume_sdk_client.create_volume.assert_called_with(
722
+ size=self.volume.size,
714
723
  snapshot_id=None,
715
- name=self.new_volume.name,
724
+ name=self.volume.name,
716
725
  description=None,
717
726
  volume_type=None,
718
727
  availability_zone=None,
719
728
  metadata=None,
720
- imageRef=None,
721
- source_volid=None,
722
- consistencygroup_id=None,
729
+ image_id=None,
730
+ source_volume_id=None,
731
+ consistency_group_id=None,
723
732
  scheduler_hints={
724
733
  'k': 'v2',
725
734
  'same_host': ['v3', 'v4'],
@@ -730,102 +739,22 @@ class TestVolumeCreateLegacy(volume_fakes.TestVolume):
730
739
  )
731
740
 
732
741
  self.assertEqual(self.columns, columns)
733
- self.assertCountEqual(self.datalist, data)
734
-
735
-
736
- class TestVolumeCreate(volume_fakes.TestVolume):
737
- columns = (
738
- 'attachments',
739
- 'availability_zone',
740
- 'consistency_group_id',
741
- 'created_at',
742
- 'description',
743
- 'extended_replication_status',
744
- 'group_id',
745
- 'host',
746
- 'id',
747
- 'image_id',
748
- 'is_bootable',
749
- 'is_encrypted',
750
- 'is_multiattach',
751
- 'location',
752
- 'metadata',
753
- 'migration_id',
754
- 'migration_status',
755
- 'name',
756
- 'project_id',
757
- 'provider_id',
758
- 'replication_driver_data',
759
- 'replication_status',
760
- 'scheduler_hints',
761
- 'size',
762
- 'snapshot_id',
763
- 'source_volume_id',
764
- 'status',
765
- 'updated_at',
766
- 'user_id',
767
- 'volume_image_metadata',
768
- 'volume_type',
769
- )
770
-
771
- def setUp(self):
772
- super().setUp()
773
-
774
- self.new_volume = sdk_fakes.generate_fake_resource(
775
- _volume.Volume, **{'size': 1}
776
- )
777
-
778
- self.datalist = (
779
- self.new_volume.attachments,
780
- self.new_volume.availability_zone,
781
- self.new_volume.consistency_group_id,
782
- self.new_volume.created_at,
783
- self.new_volume.description,
784
- self.new_volume.extended_replication_status,
785
- self.new_volume.group_id,
786
- self.new_volume.host,
787
- self.new_volume.id,
788
- self.new_volume.image_id,
789
- self.new_volume.is_bootable,
790
- self.new_volume.is_encrypted,
791
- self.new_volume.is_multiattach,
792
- self.new_volume.location,
793
- self.new_volume.metadata,
794
- self.new_volume.migration_id,
795
- self.new_volume.migration_status,
796
- self.new_volume.name,
797
- self.new_volume.project_id,
798
- self.new_volume.provider_id,
799
- self.new_volume.replication_driver_data,
800
- self.new_volume.replication_status,
801
- self.new_volume.scheduler_hints,
802
- self.new_volume.size,
803
- self.new_volume.snapshot_id,
804
- self.new_volume.source_volume_id,
805
- self.new_volume.status,
806
- self.new_volume.updated_at,
807
- self.new_volume.user_id,
808
- self.new_volume.volume_image_metadata,
809
- self.new_volume.volume_type,
810
- )
811
-
812
- # Get the command object to test
813
- self.cmd = volume.CreateVolume(self.app, None)
742
+ self.assertEqual(self.datalist, data)
814
743
 
815
744
  def test_volume_create_remote_source(self):
816
- self.volume_sdk_client.manage_volume.return_value = self.new_volume
745
+ self.volume_sdk_client.manage_volume.return_value = self.volume
817
746
 
818
747
  arglist = [
819
748
  '--remote-source',
820
749
  'key=val',
821
750
  '--host',
822
751
  'fake_host',
823
- self.new_volume.name,
752
+ self.volume.name,
824
753
  ]
825
754
  verifylist = [
826
755
  ('remote_source', {'key': 'val'}),
827
756
  ('host', 'fake_host'),
828
- ('name', self.new_volume.name),
757
+ ('name', self.volume.name),
829
758
  ]
830
759
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
831
760
 
@@ -838,13 +767,13 @@ class TestVolumeCreate(volume_fakes.TestVolume):
838
767
  description=parsed_args.description,
839
768
  volume_type=parsed_args.type,
840
769
  availability_zone=parsed_args.availability_zone,
841
- metadata=parsed_args.property,
770
+ metadata=parsed_args.properties,
842
771
  bootable=parsed_args.bootable,
843
772
  cluster=getattr(parsed_args, 'cluster', None),
844
773
  )
845
774
 
846
775
  self.assertEqual(self.columns, columns)
847
- self.assertCountEqual(self.datalist, data)
776
+ self.assertEqual(self.datalist, data)
848
777
 
849
778
  def test_volume_create_remote_source_pre_v316(self):
850
779
  self.set_volume_api_version('3.15')
@@ -853,12 +782,12 @@ class TestVolumeCreate(volume_fakes.TestVolume):
853
782
  'key=val',
854
783
  '--cluster',
855
784
  'fake_cluster',
856
- self.new_volume.name,
785
+ self.volume.name,
857
786
  ]
858
787
  verifylist = [
859
788
  ('remote_source', {'key': 'val'}),
860
789
  ('cluster', 'fake_cluster'),
861
- ('name', self.new_volume.name),
790
+ ('name', self.volume.name),
862
791
  ]
863
792
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
864
793
 
@@ -878,13 +807,13 @@ class TestVolumeCreate(volume_fakes.TestVolume):
878
807
  'fake_host',
879
808
  '--cluster',
880
809
  'fake_cluster',
881
- self.new_volume.name,
810
+ self.volume.name,
882
811
  ]
883
812
  verifylist = [
884
813
  ('remote_source', {'key': 'val'}),
885
814
  ('host', 'fake_host'),
886
815
  ('cluster', 'fake_cluster'),
887
- ('name', self.new_volume.name),
816
+ ('name', self.volume.name),
888
817
  ]
889
818
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
890
819
 
@@ -899,11 +828,11 @@ class TestVolumeCreate(volume_fakes.TestVolume):
899
828
  arglist = [
900
829
  '--remote-source',
901
830
  'key=val',
902
- self.new_volume.name,
831
+ self.volume.name,
903
832
  ]
904
833
  verifylist = [
905
834
  ('remote_source', {'key': 'val'}),
906
- ('name', self.new_volume.name),
835
+ ('name', self.volume.name),
907
836
  ]
908
837
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
909
838
 
@@ -917,15 +846,15 @@ class TestVolumeCreate(volume_fakes.TestVolume):
917
846
  def test_volume_create_remote_source_size(self):
918
847
  arglist = [
919
848
  '--size',
920
- str(self.new_volume.size),
849
+ str(self.volume.size),
921
850
  '--remote-source',
922
851
  'key=val',
923
- self.new_volume.name,
852
+ self.volume.name,
924
853
  ]
925
854
  verifylist = [
926
- ('size', self.new_volume.size),
855
+ ('size', self.volume.size),
927
856
  ('remote_source', {'key': 'val'}),
928
- ('name', self.new_volume.name),
857
+ ('name', self.volume.name),
929
858
  ]
930
859
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
931
860
 
@@ -941,15 +870,15 @@ class TestVolumeCreate(volume_fakes.TestVolume):
941
870
  def test_volume_create_host_no_remote_source(self):
942
871
  arglist = [
943
872
  '--size',
944
- str(self.new_volume.size),
873
+ str(self.volume.size),
945
874
  '--host',
946
875
  'fake_host',
947
- self.new_volume.name,
876
+ self.volume.name,
948
877
  ]
949
878
  verifylist = [
950
- ('size', self.new_volume.size),
879
+ ('size', self.volume.size),
951
880
  ('host', 'fake_host'),
952
- ('name', self.new_volume.name),
881
+ ('name', self.volume.name),
953
882
  ]
954
883
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
955
884
 
@@ -962,16 +891,17 @@ class TestVolumeCreate(volume_fakes.TestVolume):
962
891
  )
963
892
 
964
893
 
965
- class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
894
+ class TestVolumeDelete(volume_fakes.TestVolume):
966
895
  def setUp(self):
967
896
  super().setUp()
968
897
 
969
898
  self.volumes_mock = self.volume_client.volumes
970
899
  self.volumes_mock.reset_mock()
971
900
 
972
- self.volumes_mock.delete.return_value = None
973
- self.volumes = volume_fakes.create_volumes(count=1)
974
- self.volumes_mock.get = volume_fakes.get_volumes(self.volumes, 0)
901
+ self.volumes = list(sdk_fakes.generate_fake_resources(_volume.Volume))
902
+ self.volume_sdk_client.find_volume.side_effect = self.volumes
903
+ self.volume_sdk_client.delete_volume.return_value = None
904
+ self.volume_sdk_client.unmanage_volume.return_value = None
975
905
 
976
906
  # Get the command object to mock
977
907
  self.cmd = volume.DeleteVolume(self.app, None)
@@ -986,11 +916,14 @@ class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
986
916
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
987
917
 
988
918
  result = self.cmd.take_action(parsed_args)
919
+ self.assertIsNone(result)
989
920
 
990
- self.volumes_mock.delete.assert_called_once_with(
991
- self.volumes[0].id, cascade=False
921
+ self.volume_sdk_client.find_volume.assert_called_once_with(
922
+ self.volumes[0].id, ignore_missing=False
923
+ )
924
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
925
+ self.volumes[0].id, cascade=False, force=False
992
926
  )
993
- self.assertIsNone(result)
994
927
 
995
928
  def test_volume_delete_multi_volumes(self):
996
929
  arglist = [v.id for v in self.volumes]
@@ -1002,12 +935,21 @@ class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
1002
935
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1003
936
 
1004
937
  result = self.cmd.take_action(parsed_args)
1005
-
1006
- calls = [mock.call(v.id, cascade=False) for v in self.volumes]
1007
- self.volumes_mock.delete.assert_has_calls(calls)
1008
938
  self.assertIsNone(result)
1009
939
 
940
+ self.volume_sdk_client.find_volume.assert_has_calls(
941
+ [mock.call(v.id, ignore_missing=False) for v in self.volumes]
942
+ )
943
+ self.volume_sdk_client.delete_volume.assert_has_calls(
944
+ [mock.call(v.id, cascade=False, force=False) for v in self.volumes]
945
+ )
946
+
1010
947
  def test_volume_delete_multi_volumes_with_exception(self):
948
+ self.volume_sdk_client.find_volume.side_effect = [
949
+ self.volumes[0],
950
+ sdk_exceptions.NotFoundException(),
951
+ ]
952
+
1011
953
  arglist = [
1012
954
  self.volumes[0].id,
1013
955
  'unexist_volume',
@@ -1015,27 +957,28 @@ class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
1015
957
  verifylist = [
1016
958
  ('force', False),
1017
959
  ('purge', False),
1018
- ('volumes', arglist),
960
+ ('volumes', [self.volumes[0].id, 'unexist_volume']),
1019
961
  ]
1020
962
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1021
963
 
1022
- find_mock_result = [self.volumes[0], exceptions.CommandError]
1023
- with mock.patch.object(
1024
- utils, 'find_resource', side_effect=find_mock_result
1025
- ) as find_mock:
1026
- try:
1027
- self.cmd.take_action(parsed_args)
1028
- self.fail('CommandError should be raised.')
1029
- except exceptions.CommandError as e:
1030
- self.assertEqual('1 of 2 volumes failed to delete.', str(e))
1031
-
1032
- find_mock.assert_any_call(self.volumes_mock, self.volumes[0].id)
1033
- find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
1034
-
1035
- self.assertEqual(2, find_mock.call_count)
1036
- self.volumes_mock.delete.assert_called_once_with(
1037
- self.volumes[0].id, cascade=False
1038
- )
964
+ exc = self.assertRaises(
965
+ exceptions.CommandError,
966
+ self.cmd.take_action,
967
+ parsed_args,
968
+ )
969
+ self.assertEqual('1 of 2 volumes failed to delete.', str(exc))
970
+
971
+ self.volume_sdk_client.find_volume.assert_has_calls(
972
+ [
973
+ mock.call(self.volumes[0].id, ignore_missing=False),
974
+ mock.call('unexist_volume', ignore_missing=False),
975
+ ]
976
+ )
977
+ self.volume_sdk_client.delete_volume.assert_has_calls(
978
+ [
979
+ mock.call(self.volumes[0].id, cascade=False, force=False),
980
+ ]
981
+ )
1039
982
 
1040
983
  def test_volume_delete_with_purge(self):
1041
984
  arglist = [
@@ -1050,11 +993,14 @@ class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
1050
993
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1051
994
 
1052
995
  result = self.cmd.take_action(parsed_args)
996
+ self.assertIsNone(result)
1053
997
 
1054
- self.volumes_mock.delete.assert_called_once_with(
1055
- self.volumes[0].id, cascade=True
998
+ self.volume_sdk_client.find_volume.assert_called_once_with(
999
+ self.volumes[0].id, ignore_missing=False
1000
+ )
1001
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
1002
+ self.volumes[0].id, cascade=True, force=False
1056
1003
  )
1057
- self.assertIsNone(result)
1058
1004
 
1059
1005
  def test_volume_delete_with_force(self):
1060
1006
  arglist = [
@@ -1069,49 +1015,38 @@ class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
1069
1015
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1070
1016
 
1071
1017
  result = self.cmd.take_action(parsed_args)
1072
-
1073
- self.volumes_mock.force_delete.assert_called_once_with(
1074
- self.volumes[0].id
1075
- )
1076
1018
  self.assertIsNone(result)
1077
1019
 
1078
-
1079
- class TestVolumeDelete(volume_fakes.TestVolume):
1080
- def setUp(self):
1081
- super().setUp()
1082
-
1083
- self.volumes_mock = self.volume_client.volumes
1084
- self.volumes_mock.reset_mock()
1085
- self.volume_sdk_client.unmanage_volume.return_value = None
1086
-
1087
- # Get the command object to mock
1088
- self.cmd = volume.DeleteVolume(self.app, None)
1020
+ self.volume_sdk_client.find_volume.assert_called_once_with(
1021
+ self.volumes[0].id, ignore_missing=False
1022
+ )
1023
+ self.volume_sdk_client.delete_volume.assert_called_once_with(
1024
+ self.volumes[0].id, cascade=False, force=True
1025
+ )
1089
1026
 
1090
1027
  def test_volume_delete_remote(self):
1091
- vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
1092
- self.volumes_mock.get.return_value = vol
1093
-
1094
- arglist = ['--remote', vol.id]
1028
+ arglist = ['--remote', self.volumes[0].id]
1095
1029
  verifylist = [
1096
1030
  ("remote", True),
1097
1031
  ("force", False),
1098
1032
  ("purge", False),
1099
- ("volumes", [vol.id]),
1033
+ ("volumes", [self.volumes[0].id]),
1100
1034
  ]
1101
1035
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1102
1036
 
1103
1037
  result = self.cmd.take_action(parsed_args)
1104
-
1105
- self.volume_sdk_client.unmanage_volume.assert_called_once_with(vol.id)
1106
1038
  self.assertIsNone(result)
1107
1039
 
1108
- def test_volume_delete_multi_volumes_remote(self):
1109
- volumes = sdk_fakes.generate_fake_resources(
1110
- _volume.Volume, count=3, attrs={'size': 1}
1040
+ self.volume_sdk_client.find_volume.assert_called_once_with(
1041
+ self.volumes[0].id, ignore_missing=False
1042
+ )
1043
+ self.volume_sdk_client.delete_volume.assert_not_called()
1044
+ self.volume_sdk_client.unmanage_volume.assert_called_once_with(
1045
+ self.volumes[0].id
1111
1046
  )
1112
1047
 
1113
- arglist = ['--remote']
1114
- arglist += [v.id for v in volumes]
1048
+ def test_volume_delete_multi_volumes_remote(self):
1049
+ arglist = ['--remote'] + [v.id for v in self.volumes]
1115
1050
  verifylist = [
1116
1051
  ('remote', True),
1117
1052
  ('force', False),
@@ -1121,24 +1056,27 @@ class TestVolumeDelete(volume_fakes.TestVolume):
1121
1056
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1122
1057
 
1123
1058
  result = self.cmd.take_action(parsed_args)
1124
-
1125
- calls = [mock.call(v.id) for v in volumes]
1126
- self.volume_sdk_client.unmanage_volume.assert_has_calls(calls)
1127
1059
  self.assertIsNone(result)
1128
1060
 
1129
- def test_volume_delete_remote_with_purge(self):
1130
- vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
1061
+ self.volume_sdk_client.find_volume.assert_has_calls(
1062
+ [mock.call(v.id, ignore_missing=False) for v in self.volumes]
1063
+ )
1064
+ self.volume_sdk_client.delete_volume.assert_not_called()
1065
+ self.volume_sdk_client.unmanage_volume.assert_has_calls(
1066
+ [mock.call(v.id) for v in self.volumes]
1067
+ )
1131
1068
 
1069
+ def test_volume_delete_remote_with_purge(self):
1132
1070
  arglist = [
1133
1071
  '--remote',
1134
1072
  '--purge',
1135
- vol.id,
1073
+ self.volumes[0].id,
1136
1074
  ]
1137
1075
  verifylist = [
1138
1076
  ('remote', True),
1139
1077
  ('force', False),
1140
1078
  ('purge', True),
1141
- ('volumes', [vol.id]),
1079
+ ('volumes', [self.volumes[0].id]),
1142
1080
  ]
1143
1081
 
1144
1082
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1151,19 +1089,21 @@ class TestVolumeDelete(volume_fakes.TestVolume):
1151
1089
  str(exc),
1152
1090
  )
1153
1091
 
1154
- def test_volume_delete_remote_with_force(self):
1155
- vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
1092
+ self.volume_sdk_client.find_volume.assert_not_called()
1093
+ self.volume_sdk_client.delete_volume.assert_not_called()
1094
+ self.volume_sdk_client.unmanage_volume.assert_not_called()
1156
1095
 
1096
+ def test_volume_delete_remote_with_force(self):
1157
1097
  arglist = [
1158
1098
  '--remote',
1159
1099
  '--force',
1160
- vol.id,
1100
+ self.volumes[0].id,
1161
1101
  ]
1162
1102
  verifylist = [
1163
1103
  ('remote', True),
1164
1104
  ('force', True),
1165
1105
  ('purge', False),
1166
- ('volumes', [vol.id]),
1106
+ ('volumes', [self.volumes[0].id]),
1167
1107
  ]
1168
1108
 
1169
1109
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1176,6 +1116,10 @@ class TestVolumeDelete(volume_fakes.TestVolume):
1176
1116
  str(exc),
1177
1117
  )
1178
1118
 
1119
+ self.volume_sdk_client.find_volume.assert_not_called()
1120
+ self.volume_sdk_client.delete_volume.assert_not_called()
1121
+ self.volume_sdk_client.unmanage_volume.assert_not_called()
1122
+
1179
1123
 
1180
1124
  class TestVolumeList(volume_fakes.TestVolume):
1181
1125
  project = identity_fakes.FakeProject.create_one_project()
@@ -1231,6 +1175,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1231
1175
  'user_id': None,
1232
1176
  'name': None,
1233
1177
  'status': None,
1178
+ 'metadata': None,
1234
1179
  }
1235
1180
  self.volumes_mock.list.assert_called_once_with(
1236
1181
  search_opts=search_opts,
@@ -1274,6 +1219,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1274
1219
  'user_id': None,
1275
1220
  'name': None,
1276
1221
  'status': None,
1222
+ 'metadata': None,
1277
1223
  }
1278
1224
  self.volumes_mock.list.assert_called_once_with(
1279
1225
  search_opts=search_opts,
@@ -1320,6 +1266,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1320
1266
  'user_id': None,
1321
1267
  'name': None,
1322
1268
  'status': None,
1269
+ 'metadata': None,
1323
1270
  }
1324
1271
  self.volumes_mock.list.assert_called_once_with(
1325
1272
  search_opts=search_opts,
@@ -1363,6 +1310,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1363
1310
  'user_id': self.user.id,
1364
1311
  'name': None,
1365
1312
  'status': None,
1313
+ 'metadata': None,
1366
1314
  }
1367
1315
  self.volumes_mock.list.assert_called_once_with(
1368
1316
  search_opts=search_opts,
@@ -1408,6 +1356,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1408
1356
  'user_id': self.user.id,
1409
1357
  'name': None,
1410
1358
  'status': None,
1359
+ 'metadata': None,
1411
1360
  }
1412
1361
  self.volumes_mock.list.assert_called_once_with(
1413
1362
  search_opts=search_opts,
@@ -1451,6 +1400,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1451
1400
  'user_id': None,
1452
1401
  'name': self.mock_volume.name,
1453
1402
  'status': None,
1403
+ 'metadata': None,
1454
1404
  }
1455
1405
  self.volumes_mock.list.assert_called_once_with(
1456
1406
  search_opts=search_opts,
@@ -1494,6 +1444,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1494
1444
  'user_id': None,
1495
1445
  'name': None,
1496
1446
  'status': self.mock_volume.status,
1447
+ 'metadata': None,
1497
1448
  }
1498
1449
  self.volumes_mock.list.assert_called_once_with(
1499
1450
  search_opts=search_opts,
@@ -1536,6 +1487,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1536
1487
  'user_id': None,
1537
1488
  'name': None,
1538
1489
  'status': None,
1490
+ 'metadata': None,
1539
1491
  }
1540
1492
  self.volumes_mock.list.assert_called_once_with(
1541
1493
  search_opts=search_opts,
@@ -1579,6 +1531,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1579
1531
  'user_id': None,
1580
1532
  'name': None,
1581
1533
  'status': None,
1534
+ 'metadata': None,
1582
1535
  }
1583
1536
  self.volumes_mock.list.assert_called_once_with(
1584
1537
  search_opts=search_opts,
@@ -1652,6 +1605,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1652
1605
  'user_id': None,
1653
1606
  'name': None,
1654
1607
  'all_tenants': False,
1608
+ 'metadata': None,
1655
1609
  },
1656
1610
  )
1657
1611
  self.assertCountEqual(datalist, tuple(data))
@@ -1696,6 +1650,7 @@ class TestVolumeList(volume_fakes.TestVolume):
1696
1650
  'user_id': None,
1697
1651
  'name': None,
1698
1652
  'status': None,
1653
+ 'metadata': None,
1699
1654
  }
1700
1655
  self.volumes_mock.list.assert_called_once_with(
1701
1656
  search_opts=search_opts,
@@ -1711,71 +1666,79 @@ class TestVolumeList(volume_fakes.TestVolume):
1711
1666
 
1712
1667
 
1713
1668
  class TestVolumeMigrate(volume_fakes.TestVolume):
1714
- _volume = volume_fakes.create_one_volume()
1715
-
1716
1669
  def setUp(self):
1717
1670
  super().setUp()
1718
1671
 
1719
- self.volumes_mock = self.volume_client.volumes
1720
- self.volumes_mock.reset_mock()
1672
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
1673
+ self.volume_sdk_client.find_volume.return_value = self.volume
1674
+ self.volume_sdk_client.migrate_volume.return_value = None
1721
1675
 
1722
- self.volumes_mock.get.return_value = self._volume
1723
- self.volumes_mock.migrate_volume.return_value = None
1724
- # Get the command object to test
1725
1676
  self.cmd = volume.MigrateVolume(self.app, None)
1726
1677
 
1727
1678
  def test_volume_migrate(self):
1728
1679
  arglist = [
1729
1680
  "--host",
1730
1681
  "host@backend-name#pool",
1731
- self._volume.id,
1682
+ self.volume.id,
1732
1683
  ]
1733
1684
  verifylist = [
1734
1685
  ("force_host_copy", False),
1735
1686
  ("lock_volume", False),
1736
1687
  ("host", "host@backend-name#pool"),
1737
- ("volume", self._volume.id),
1688
+ ("volume", self.volume.id),
1738
1689
  ]
1739
1690
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1740
1691
 
1741
1692
  result = self.cmd.take_action(parsed_args)
1742
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1743
- self.volumes_mock.migrate_volume.assert_called_once_with(
1744
- self._volume.id, "host@backend-name#pool", False, False
1745
- )
1746
1693
  self.assertIsNone(result)
1747
1694
 
1695
+ self.volume_sdk_client.find_volume.assert_called_with(
1696
+ self.volume.id, ignore_missing=False
1697
+ )
1698
+ self.volume_sdk_client.migrate_volume.assert_called_once_with(
1699
+ self.volume.id,
1700
+ host="host@backend-name#pool",
1701
+ force_host_copy=False,
1702
+ lock_volume=False,
1703
+ )
1704
+
1748
1705
  def test_volume_migrate_with_option(self):
1749
1706
  arglist = [
1750
1707
  "--force-host-copy",
1751
1708
  "--lock-volume",
1752
1709
  "--host",
1753
1710
  "host@backend-name#pool",
1754
- self._volume.id,
1711
+ self.volume.id,
1755
1712
  ]
1756
1713
  verifylist = [
1757
1714
  ("force_host_copy", True),
1758
1715
  ("lock_volume", True),
1759
1716
  ("host", "host@backend-name#pool"),
1760
- ("volume", self._volume.id),
1717
+ ("volume", self.volume.id),
1761
1718
  ]
1762
1719
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1763
1720
 
1764
1721
  result = self.cmd.take_action(parsed_args)
1765
- self.volumes_mock.get.assert_called_once_with(self._volume.id)
1766
- self.volumes_mock.migrate_volume.assert_called_once_with(
1767
- self._volume.id, "host@backend-name#pool", True, True
1768
- )
1769
1722
  self.assertIsNone(result)
1770
1723
 
1724
+ self.volume_sdk_client.find_volume.assert_called_with(
1725
+ self.volume.id, ignore_missing=False
1726
+ )
1727
+ self.volume_sdk_client.migrate_volume.assert_called_once_with(
1728
+ self.volume.id,
1729
+ host="host@backend-name#pool",
1730
+ force_host_copy=True,
1731
+ lock_volume=True,
1732
+ )
1733
+
1771
1734
  def test_volume_migrate_without_host(self):
1772
1735
  arglist = [
1773
- self._volume.id,
1736
+ self.volume.id,
1774
1737
  ]
1775
1738
  verifylist = [
1776
1739
  ("force_host_copy", False),
1777
1740
  ("lock_volume", False),
1778
- ("volume", self._volume.id),
1741
+ ("volume", self.volume.id),
1779
1742
  ]
1780
1743
 
1781
1744
  self.assertRaises(
@@ -1786,6 +1749,9 @@ class TestVolumeMigrate(volume_fakes.TestVolume):
1786
1749
  verifylist,
1787
1750
  )
1788
1751
 
1752
+ self.volume_sdk_client.find_volume.assert_not_called()
1753
+ self.volume_sdk_client.migrate_volume.assert_not_called()
1754
+
1789
1755
 
1790
1756
  class TestVolumeSet(volume_fakes.TestVolume):
1791
1757
  volume_type = volume_fakes.create_one_volume_type()
@@ -1815,16 +1781,16 @@ class TestVolumeSet(volume_fakes.TestVolume):
1815
1781
  self.new_volume.id,
1816
1782
  ]
1817
1783
  verifylist = [
1818
- ('property', {'a': 'b', 'c': 'd'}),
1784
+ ('properties', {'a': 'b', 'c': 'd'}),
1785
+ ('read_only', None),
1786
+ ('bootable', None),
1819
1787
  ('volume', self.new_volume.id),
1820
- ('bootable', False),
1821
- ('non_bootable', False),
1822
1788
  ]
1823
1789
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1824
1790
 
1825
1791
  self.cmd.take_action(parsed_args)
1826
1792
  self.volumes_mock.set_metadata.assert_called_with(
1827
- self.new_volume.id, parsed_args.property
1793
+ self.new_volume.id, parsed_args.properties
1828
1794
  )
1829
1795
 
1830
1796
  def test_volume_set_image_property(self):
@@ -1836,10 +1802,10 @@ class TestVolumeSet(volume_fakes.TestVolume):
1836
1802
  self.new_volume.id,
1837
1803
  ]
1838
1804
  verifylist = [
1839
- ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
1805
+ ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
1806
+ ('read_only', None),
1807
+ ('bootable', None),
1840
1808
  ('volume', self.new_volume.id),
1841
- ('bootable', False),
1842
- ('non_bootable', False),
1843
1809
  ]
1844
1810
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1845
1811
 
@@ -1847,15 +1813,15 @@ class TestVolumeSet(volume_fakes.TestVolume):
1847
1813
  # returns nothing
1848
1814
  self.cmd.take_action(parsed_args)
1849
1815
  self.volumes_mock.set_image_metadata.assert_called_with(
1850
- self.new_volume.id, parsed_args.image_property
1816
+ self.new_volume.id, parsed_args.image_properties
1851
1817
  )
1852
1818
 
1853
1819
  def test_volume_set_state(self):
1854
1820
  arglist = ['--state', 'error', self.new_volume.id]
1855
1821
  verifylist = [
1856
- ('read_only', False),
1857
- ('read_write', False),
1858
1822
  ('state', 'error'),
1823
+ ('read_only', None),
1824
+ ('bootable', None),
1859
1825
  ('volume', self.new_volume.id),
1860
1826
  ]
1861
1827
 
@@ -1919,36 +1885,40 @@ class TestVolumeSet(volume_fakes.TestVolume):
1919
1885
 
1920
1886
  def test_volume_set_bootable(self):
1921
1887
  arglist = [
1922
- ['--bootable', self.new_volume.id],
1923
- ['--non-bootable', self.new_volume.id],
1888
+ '--bootable',
1889
+ self.new_volume.id,
1924
1890
  ]
1925
1891
  verifylist = [
1926
- [
1927
- ('bootable', True),
1928
- ('non_bootable', False),
1929
- ('volume', self.new_volume.id),
1930
- ],
1931
- [
1932
- ('bootable', False),
1933
- ('non_bootable', True),
1934
- ('volume', self.new_volume.id),
1935
- ],
1892
+ ('bootable', True),
1893
+ ('volume', self.new_volume.id),
1936
1894
  ]
1937
- for index in range(len(arglist)):
1938
- parsed_args = self.check_parser(
1939
- self.cmd, arglist[index], verifylist[index]
1940
- )
1895
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1941
1896
 
1942
- self.cmd.take_action(parsed_args)
1943
- self.volumes_mock.set_bootable.assert_called_with(
1944
- self.new_volume.id, verifylist[index][0][1]
1945
- )
1897
+ self.cmd.take_action(parsed_args)
1898
+ self.volumes_mock.set_bootable.assert_called_with(
1899
+ self.new_volume.id, verifylist[0][1]
1900
+ )
1901
+
1902
+ def test_volume_set_non_bootable(self):
1903
+ arglist = [
1904
+ '--non-bootable',
1905
+ self.new_volume.id,
1906
+ ]
1907
+ verifylist = [
1908
+ ('bootable', False),
1909
+ ('volume', self.new_volume.id),
1910
+ ]
1911
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1912
+
1913
+ self.cmd.take_action(parsed_args)
1914
+ self.volumes_mock.set_bootable.assert_called_with(
1915
+ self.new_volume.id, verifylist[0][1]
1916
+ )
1946
1917
 
1947
1918
  def test_volume_set_readonly(self):
1948
1919
  arglist = ['--read-only', self.new_volume.id]
1949
1920
  verifylist = [
1950
1921
  ('read_only', True),
1951
- ('read_write', False),
1952
1922
  ('volume', self.new_volume.id),
1953
1923
  ]
1954
1924
 
@@ -1964,7 +1934,6 @@ class TestVolumeSet(volume_fakes.TestVolume):
1964
1934
  arglist = ['--read-write', self.new_volume.id]
1965
1935
  verifylist = [
1966
1936
  ('read_only', False),
1967
- ('read_write', True),
1968
1937
  ('volume', self.new_volume.id),
1969
1938
  ]
1970
1939
 
@@ -2036,41 +2005,91 @@ class TestVolumeShow(volume_fakes.TestVolume):
2036
2005
  def setUp(self):
2037
2006
  super().setUp()
2038
2007
 
2039
- self.volumes_mock = self.volume_client.volumes
2040
- self.volumes_mock.reset_mock()
2008
+ self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
2009
+ self.volume_sdk_client.find_volume.return_value = self.volume
2010
+
2011
+ self.columns = (
2012
+ 'attachments',
2013
+ 'availability_zone',
2014
+ 'bootable',
2015
+ 'cluster_name',
2016
+ 'consistencygroup_id',
2017
+ 'consumes_quota',
2018
+ 'created_at',
2019
+ 'description',
2020
+ 'encrypted',
2021
+ 'encryption_key_id',
2022
+ 'group_id',
2023
+ 'id',
2024
+ 'multiattach',
2025
+ 'name',
2026
+ 'os-vol-host-attr:host',
2027
+ 'os-vol-mig-status-attr:migstat',
2028
+ 'os-vol-mig-status-attr:name_id',
2029
+ 'os-vol-tenant-attr:tenant_id',
2030
+ 'properties',
2031
+ 'provider_id',
2032
+ 'replication_status',
2033
+ 'service_uuid',
2034
+ 'shared_targets',
2035
+ 'size',
2036
+ 'snapshot_id',
2037
+ 'source_volid',
2038
+ 'status',
2039
+ 'type',
2040
+ 'updated_at',
2041
+ 'user_id',
2042
+ 'volume_image_metadata',
2043
+ 'volume_type_id',
2044
+ )
2045
+ self.data = (
2046
+ self.volume.attachments,
2047
+ self.volume.availability_zone,
2048
+ self.volume.is_bootable,
2049
+ self.volume.cluster_name,
2050
+ self.volume.consistency_group_id,
2051
+ self.volume.consumes_quota,
2052
+ self.volume.created_at,
2053
+ self.volume.description,
2054
+ self.volume.is_encrypted,
2055
+ self.volume.encryption_key_id,
2056
+ self.volume.group_id,
2057
+ self.volume.id,
2058
+ self.volume.is_multiattach,
2059
+ self.volume.name,
2060
+ self.volume.host,
2061
+ self.volume.migration_status,
2062
+ self.volume.migration_id,
2063
+ self.volume.project_id,
2064
+ format_columns.DictColumn(self.volume.metadata),
2065
+ self.volume.provider_id,
2066
+ self.volume.replication_status,
2067
+ self.volume.service_uuid,
2068
+ self.volume.shared_targets,
2069
+ self.volume.size,
2070
+ self.volume.snapshot_id,
2071
+ self.volume.source_volume_id,
2072
+ self.volume.status,
2073
+ self.volume.volume_type,
2074
+ self.volume.updated_at,
2075
+ self.volume.user_id,
2076
+ self.volume.volume_image_metadata,
2077
+ self.volume.volume_type_id,
2078
+ )
2041
2079
 
2042
- self._volume = volume_fakes.create_one_volume()
2043
- self.volumes_mock.get.return_value = self._volume
2044
- # Get the command object to test
2045
2080
  self.cmd = volume.ShowVolume(self.app, None)
2046
2081
 
2047
2082
  def test_volume_show(self):
2048
- arglist = [self._volume.id]
2049
- verifylist = [("volume", self._volume.id)]
2083
+ arglist = [self.volume.id]
2084
+ verifylist = [("volume", self.volume.id)]
2050
2085
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2051
2086
 
2052
2087
  columns, data = self.cmd.take_action(parsed_args)
2053
- self.volumes_mock.get.assert_called_with(self._volume.id)
2054
2088
 
2055
- self.assertEqual(
2056
- tuple(sorted(self._volume.keys())),
2057
- columns,
2058
- )
2059
- self.assertTupleEqual(
2060
- (
2061
- self._volume.attachments,
2062
- self._volume.availability_zone,
2063
- self._volume.bootable,
2064
- self._volume.description,
2065
- self._volume.id,
2066
- self._volume.name,
2067
- format_columns.DictColumn(self._volume.metadata),
2068
- self._volume.size,
2069
- self._volume.snapshot_id,
2070
- self._volume.status,
2071
- self._volume.volume_type,
2072
- ),
2073
- data,
2089
+ self.assertEqual(self.columns, columns)
2090
+ self.assertEqual(self.data, data)
2091
+ self.volume_sdk_client.find_volume.assert_called_with(
2092
+ self.volume.id, ignore_missing=False
2074
2093
  )
2075
2094
 
2076
2095
 
@@ -2100,7 +2119,7 @@ class TestVolumeUnset(volume_fakes.TestVolume):
2100
2119
  self.new_volume.id,
2101
2120
  ]
2102
2121
  verifylist = [
2103
- ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
2122
+ ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
2104
2123
  ('volume', self.new_volume.id),
2105
2124
  ]
2106
2125
  parsed_args = self.check_parser(self.cmd_set, arglist, verifylist)
@@ -2116,7 +2135,7 @@ class TestVolumeUnset(volume_fakes.TestVolume):
2116
2135
  self.new_volume.id,
2117
2136
  ]
2118
2137
  verifylist_unset = [
2119
- ('image_property', ['Alpha']),
2138
+ ('image_properties', ['Alpha']),
2120
2139
  ('volume', self.new_volume.id),
2121
2140
  ]
2122
2141
  parsed_args_unset = self.check_parser(
@@ -2128,7 +2147,7 @@ class TestVolumeUnset(volume_fakes.TestVolume):
2128
2147
  self.cmd_unset.take_action(parsed_args_unset)
2129
2148
 
2130
2149
  self.volumes_mock.delete_image_metadata.assert_called_with(
2131
- self.new_volume.id, parsed_args_unset.image_property
2150
+ self.new_volume.id, parsed_args_unset.image_properties
2132
2151
  )
2133
2152
 
2134
2153
  def test_volume_unset_image_property_fail(self):
@@ -2143,8 +2162,8 @@ class TestVolumeUnset(volume_fakes.TestVolume):
2143
2162
  self.new_volume.id,
2144
2163
  ]
2145
2164
  verifylist = [
2146
- ('image_property', ['Alpha']),
2147
- ('property', ['Beta']),
2165
+ ('image_properties', ['Alpha']),
2166
+ ('properties', ['Beta']),
2148
2167
  ('volume', self.new_volume.id),
2149
2168
  ]
2150
2169
  parsed_args = self.check_parser(self.cmd_unset, arglist, verifylist)
@@ -2157,10 +2176,10 @@ class TestVolumeUnset(volume_fakes.TestVolume):
2157
2176
  'One or more of the unset operations failed', str(e)
2158
2177
  )
2159
2178
  self.volumes_mock.delete_image_metadata.assert_called_with(
2160
- self.new_volume.id, parsed_args.image_property
2179
+ self.new_volume.id, parsed_args.image_properties
2161
2180
  )
2162
2181
  self.volumes_mock.delete_metadata.assert_called_with(
2163
- self.new_volume.id, parsed_args.property
2182
+ self.new_volume.id, parsed_args.properties
2164
2183
  )
2165
2184
 
2166
2185
 
@@ -2316,29 +2335,45 @@ class TestVolumeRevertToSnapshot(volume_fakes.TestVolume):
2316
2335
 
2317
2336
  class TestColumns(volume_fakes.TestVolume):
2318
2337
  def test_attachments_column_without_server_cache(self):
2319
- _volume = volume_fakes.create_one_volume()
2320
- server_id = _volume.attachments[0]['server_id']
2321
- device = _volume.attachments[0]['device']
2338
+ vol = sdk_fakes.generate_fake_resource(
2339
+ _volume.Volume,
2340
+ attachments=[
2341
+ {
2342
+ 'device': '/dev/' + uuid.uuid4().hex,
2343
+ 'server_id': uuid.uuid4().hex,
2344
+ },
2345
+ ],
2346
+ )
2347
+ server_id = vol.attachments[0]['server_id']
2348
+ device = vol.attachments[0]['device']
2322
2349
 
2323
- col = volume.AttachmentsColumn(_volume.attachments, {})
2350
+ col = volume.AttachmentsColumn(vol.attachments, {})
2324
2351
  self.assertEqual(
2325
2352
  f'Attached to {server_id} on {device} ',
2326
2353
  col.human_readable(),
2327
2354
  )
2328
- self.assertEqual(_volume.attachments, col.machine_readable())
2355
+ self.assertEqual(vol.attachments, col.machine_readable())
2329
2356
 
2330
2357
  def test_attachments_column_with_server_cache(self):
2331
- _volume = volume_fakes.create_one_volume()
2358
+ vol = sdk_fakes.generate_fake_resource(
2359
+ _volume.Volume,
2360
+ attachments=[
2361
+ {
2362
+ 'device': '/dev/' + uuid.uuid4().hex,
2363
+ 'server_id': uuid.uuid4().hex,
2364
+ },
2365
+ ],
2366
+ )
2332
2367
 
2333
- server_id = _volume.attachments[0]['server_id']
2334
- device = _volume.attachments[0]['device']
2368
+ server_id = vol.attachments[0]['server_id']
2369
+ device = vol.attachments[0]['device']
2335
2370
  fake_server = mock.Mock()
2336
2371
  fake_server.name = 'fake-server-name'
2337
2372
  server_cache = {server_id: fake_server}
2338
2373
 
2339
- col = volume.AttachmentsColumn(_volume.attachments, server_cache)
2374
+ col = volume.AttachmentsColumn(vol.attachments, server_cache)
2340
2375
  self.assertEqual(
2341
2376
  'Attached to {} on {} '.format('fake-server-name', device),
2342
2377
  col.human_readable(),
2343
2378
  )
2344
- self.assertEqual(_volume.attachments, col.machine_readable())
2379
+ self.assertEqual(vol.attachments, col.machine_readable())