Codebase list cinder-tempest-plugin / 1f29ca1
Tests for volume<->image dependencies Detect problems related to Cinder volumes not allowing Glance images to be deleted. This adds the option CONF.volume_feature_enabled.volume_image_dep_tests. This defaults to True because it is expected to pass on all configurations other than pre-Caracal RBD backends. Change-Id: I5fee23951958fc0031b59ce437a963c4cea28529 Eric Harney 2 years ago
2 changed file(s) with 137 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1212 # License for the specific language governing permissions and limitations
1313 # under the License.
1414
15
16 from tempest.common import utils
17 from tempest.common import waiters
1518 from tempest import config
1619 from tempest.lib import decorators
20 import testtools
1721
1822 from cinder_tempest_plugin.api.volume import base
1923
118122 self._delete_vol_and_wait(volume_1)
119123 self._delete_vol_and_wait(volume_2)
120124 self._delete_vol_and_wait(volume_3)
125
126
127 class VolumeImageDependencyTests(base.BaseVolumeTest):
128 """Volume<->image dependency tests.
129
130 These tests perform clones to/from volumes and images,
131 deleting images/volumes that other volumes were cloned from.
132
133 Images and volumes are expected to be independent at the OpenStack
134 level, but in some configurations (i.e. when using Ceph as storage
135 for both Cinder and Glance) it was possible to end up with images
136 or volumes that could not be deleted. This was fixed for RBD in
137 Cinder 2024.1 change I009d0748f.
138
139 """
140
141 min_microversion = '3.40'
142
143 @classmethod
144 def del_image(cls, image_id):
145 images_client = cls.os_primary.image_client_v2
146 images_client.delete_image(image_id)
147 images_client.wait_for_resource_deletion(image_id)
148
149 @testtools.skipUnless(CONF.volume_feature_enabled.volume_image_dep_tests,
150 reason='Volume/image dependency tests not enabled.')
151 @utils.services('image', 'volume')
152 @decorators.idempotent_id('7a9fba78-2e4b-42b1-9898-bb4a60685320')
153 def test_image_volume_dependencies_1(self):
154 # image -> volume
155 image_args = {
156 'disk_format': 'raw',
157 'container_format': 'bare',
158 'name': 'image-for-test-7a9fba78-2e4b-42b1-9898-bb4a60685320'
159 }
160 image = self.create_image_with_data(**image_args)
161
162 # create a volume from the image
163 vol_args = {'name': ('volume1-for-test'
164 '7a9fba78-2e4b-42b1-9898-bb4a60685320'),
165 'imageRef': image['id']}
166 volume1 = self.create_volume(**vol_args)
167 waiters.wait_for_volume_resource_status(self.volumes_client,
168 volume1['id'],
169 'available')
170
171 self.volumes_client.delete_volume(volume1['id'])
172 self.volumes_client.wait_for_resource_deletion(volume1['id'])
173
174 self.del_image(image['id'])
175
176 @testtools.skipUnless(CONF.volume_feature_enabled.volume_image_dep_tests,
177 reason='Volume/image dependency tests not enabled.')
178 @utils.services('image', 'volume')
179 @decorators.idempotent_id('0e20bd6e-440f-41d8-9b5d-fc047ac00423')
180 def test_image_volume_dependencies_2(self):
181 # image -> volume -> volume
182
183 image_args = {
184 'disk_format': 'raw',
185 'container_format': 'bare',
186 'name': 'image-for-test-0e20bd6e-440f-41d8-9b5d-fc047ac00423'
187 }
188 image = self.create_image_with_data(**image_args)
189
190 # create a volume from the image
191 vol_args = {'name': ('volume1-for-test'
192 '0e20bd6e-440f-41d8-9b5d-fc047ac00423'),
193 'imageRef': image['id']}
194 volume1 = self.create_volume(**vol_args)
195 waiters.wait_for_volume_resource_status(self.volumes_client,
196 volume1['id'],
197 'available')
198
199 vol2_args = {'name': ('volume2-for-test-'
200 '0e20bd6e-440f-41d8-9b5d-fc047ac00423'),
201 'source_volid': volume1['id']}
202 volume2 = self.create_volume(**vol2_args)
203 waiters.wait_for_volume_resource_status(self.volumes_client,
204 volume2['id'],
205 'available')
206
207 self.volumes_client.delete_volume(volume1['id'])
208 self.volumes_client.wait_for_resource_deletion(volume1['id'])
209
210 self.del_image(image['id'])
211
212 @testtools.skipUnless(CONF.volume_feature_enabled.volume_image_dep_tests,
213 reason='Volume/image dependency tests not enabled.')
214 @decorators.idempotent_id('e6050452-06bd-4c7f-9912-45178c83e379')
215 @utils.services('image', 'volume')
216 def test_image_volume_dependencies_3(self):
217 # image -> volume -> snap -> volume
218
219 image_args = {
220 'disk_format': 'raw',
221 'container_format': 'bare',
222 'name': 'image-for-test-e6050452-06bd-4c7f-9912-45178c83e379'
223 }
224 image = self.create_image_with_data(**image_args)
225
226 # create a volume from the image
227 vol_args = {'name': ('volume1-for-test'
228 'e6050452-06bd-4c7f-9912-45178c83e379'),
229 'imageRef': image['id']}
230 volume1 = self.create_volume(**vol_args)
231 waiters.wait_for_volume_resource_status(self.volumes_client,
232 volume1['id'],
233 'available')
234
235 snapshot1 = self.create_snapshot(volume1['id'])
236
237 vol2_args = {'name': ('volume2-for-test-'
238 'e6050452-06bd-4c7f-9912-45178c83e379'),
239 'snapshot_id': snapshot1['id']}
240 volume2 = self.create_volume(**vol2_args)
241 waiters.wait_for_volume_resource_status(self.volumes_client,
242 volume2['id'],
243 'available')
244
245 self.snapshots_client.delete_snapshot(snapshot1['id'])
246 self.snapshots_client.wait_for_resource_deletion(snapshot1['id'])
247
248 self.volumes_client.delete_volume(volume2['id'])
249 self.volumes_client.wait_for_resource_deletion(volume2['id'])
250
251 self.del_image(image['id'])
252
253 self.volumes_client.delete_volume(volume1['id'])
254 self.volumes_client.wait_for_resource_deletion(volume1['id'])
2121 cfg.BoolOpt('volume_revert',
2222 default=False,
2323 help='Enable to run Cinder volume revert tests'),
24 cfg.BoolOpt('volume_image_dep_tests',
25 default=True,
26 help='Run tests for dependencies between images and volumes')
2427 ]
2528
2629 # The barbican service is discovered by config_tempest [1], and will appear