1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 from cinderclient.exceptions import NotFound, BadRequest
17 from snaps.openstack.create_image import OpenStackImage
18 from snaps.openstack.create_volume_type import (
19 VolumeTypeSettings, OpenStackVolumeType)
20 from snaps.openstack.tests import openstack_tests
23 from urllib.request import URLError
25 from urllib2 import URLError
31 from snaps.openstack.create_volume import (
32 VolumeSettings, VolumeSettingsError, OpenStackVolume)
33 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
34 from snaps.openstack.utils import cinder_utils
36 __author__ = 'spisarski'
38 logger = logging.getLogger('create_volume_tests')
41 class VolumeSettingsUnitTests(unittest.TestCase):
43 Tests the construction of the VolumeSettings class
46 def test_no_params(self):
47 with self.assertRaises(VolumeSettingsError):
50 def test_empty_config(self):
51 with self.assertRaises(VolumeSettingsError):
52 VolumeSettings(**dict())
54 def test_name_only(self):
55 settings = VolumeSettings(name='foo')
56 self.assertEqual('foo', settings.name)
57 self.assertIsNone(settings.description)
58 self.assertEquals(1, settings.size)
59 self.assertIsNone(settings.image_name)
60 self.assertIsNone(settings.type_name)
61 self.assertIsNone(settings.availability_zone)
62 self.assertFalse(settings.multi_attach)
64 def test_config_with_name_only(self):
65 settings = VolumeSettings(**{'name': 'foo'})
66 self.assertEqual('foo', settings.name)
67 self.assertIsNone(settings.description)
68 self.assertEquals(1, settings.size)
69 self.assertIsNone(settings.image_name)
70 self.assertIsNone(settings.type_name)
71 self.assertIsNone(settings.availability_zone)
72 self.assertFalse(settings.multi_attach)
74 def test_all_strings(self):
75 settings = VolumeSettings(
76 name='foo', description='desc', size='2', image_name='image',
77 type_name='type', availability_zone='zone1', multi_attach='true')
79 self.assertEqual('foo', settings.name)
80 self.assertEqual('desc', settings.description)
81 self.assertEqual(2, settings.size)
82 self.assertEqual('image', settings.image_name)
83 self.assertEqual('type', settings.type_name)
84 self.assertEqual('zone1', settings.availability_zone)
85 self.assertTrue(settings.multi_attach)
87 def test_all_correct_type(self):
88 settings = VolumeSettings(
89 name='foo', description='desc', size=2, image_name='image',
90 type_name='bar', availability_zone='zone1', multi_attach=True)
92 self.assertEqual('foo', settings.name)
93 self.assertEqual('desc', settings.description)
94 self.assertEqual(2, settings.size)
95 self.assertEqual('image', settings.image_name)
96 self.assertEqual('bar', settings.type_name)
97 self.assertEqual('zone1', settings.availability_zone)
98 self.assertTrue(settings.multi_attach)
100 def test_config_all(self):
101 settings = VolumeSettings(
102 **{'name': 'foo', 'description': 'desc', 'size': '2',
103 'image_name': 'foo', 'type_name': 'bar',
104 'availability_zone': 'zone1', 'multi_attach': 'true'})
106 self.assertEqual('foo', settings.name)
107 self.assertEqual('desc', settings.description)
108 self.assertEqual(2, settings.size)
109 self.assertEqual('foo', settings.image_name)
110 self.assertEqual('bar', settings.type_name)
111 self.assertEqual('zone1', settings.availability_zone)
112 self.assertTrue(settings.multi_attach)
115 class CreateSimpleVolumeSuccessTests(OSIntegrationTestCase):
117 Test for the CreateVolume class defined in create_volume.py
122 Instantiates the CreateVolume object that is responsible for
123 downloading and creating an OS volume file within OpenStack
125 super(self.__class__, self).__start__()
128 self.volume_settings = VolumeSettings(
129 name=self.__class__.__name__ + '-' + str(guid))
131 self.cinder = cinder_utils.cinder_client(self.os_creds)
132 self.volume_creator = None
136 Cleans the volume and downloaded volume file
138 if self.volume_creator:
139 self.volume_creator.clean()
141 super(self.__class__, self).__clean__()
143 def test_create_volume_simple(self):
145 Tests the creation of a simple OpenStack volume.
148 self.volume_creator = OpenStackVolume(
149 self.os_creds, self.volume_settings)
150 created_volume = self.volume_creator.create(block=True)
151 self.assertIsNotNone(created_volume)
153 retrieved_volume = cinder_utils.get_volume(
154 self.cinder, volume_settings=self.volume_settings)
156 self.assertIsNotNone(retrieved_volume)
157 self.assertEqual(created_volume.id, retrieved_volume.id)
158 self.assertTrue(created_volume == retrieved_volume)
160 def test_create_delete_volume(self):
162 Tests the creation then deletion of an OpenStack volume to ensure
163 clean() does not raise an Exception.
166 self.volume_creator = OpenStackVolume(
167 self.os_creds, self.volume_settings)
168 created_volume = self.volume_creator.create(block=True)
169 self.assertIsNotNone(created_volume)
171 retrieved_volume = cinder_utils.get_volume(
172 self.cinder, volume_settings=self.volume_settings)
173 self.assertIsNotNone(retrieved_volume)
174 self.assertEqual(created_volume, retrieved_volume)
176 # Delete Volume manually
177 self.volume_creator.clean()
179 self.assertIsNone(cinder_utils.get_volume(
180 self.cinder, volume_settings=self.volume_settings))
182 # Must not throw an exception when attempting to cleanup non-existent
184 self.volume_creator.clean()
185 self.assertIsNone(self.volume_creator.get_volume())
187 def test_create_same_volume(self):
189 Tests the creation of an OpenStack volume when one already exists.
192 self.volume_creator = OpenStackVolume(
193 self.os_creds, self.volume_settings)
194 volume1 = self.volume_creator.create(block=True)
196 retrieved_volume = cinder_utils.get_volume(
197 self.cinder, volume_settings=self.volume_settings)
198 self.assertEqual(volume1, retrieved_volume)
200 # Should be retrieving the instance data
201 os_volume_2 = OpenStackVolume(
202 self.os_creds, self.volume_settings)
203 volume2 = os_volume_2.create(block=True)
204 self.assertEqual(volume1, volume2)
207 class CreateSimpleVolumeFailureTests(OSIntegrationTestCase):
209 Test for the CreateVolume class defined in create_volume.py
214 Instantiates the CreateVolume object that is responsible for
215 downloading and creating an OS volume file within OpenStack
217 super(self.__class__, self).__start__()
219 self.guid = uuid.uuid4()
220 self.cinder = cinder_utils.cinder_client(self.os_creds)
221 self.volume_creator = None
225 Cleans the volume and downloaded volume file
227 if self.volume_creator:
228 self.volume_creator.clean()
230 super(self.__class__, self).__clean__()
232 def test_create_volume_bad_size(self):
234 Tests the creation of an OpenStack volume with a negative size to
235 ensure it raises a BadRequest exception.
237 volume_settings = VolumeSettings(
238 name=self.__class__.__name__ + '-' + str(self.guid), size=-1)
241 self.volume_creator = OpenStackVolume(self.os_creds, volume_settings)
243 with self.assertRaises(BadRequest):
244 self.volume_creator.create(block=True)
246 def test_create_volume_bad_type(self):
248 Tests the creation of an OpenStack volume with a type that does not
249 exist to ensure it raises a NotFound exception.
251 volume_settings = VolumeSettings(
252 name=self.__class__.__name__ + '-' + str(self.guid),
256 self.volume_creator = OpenStackVolume(self.os_creds, volume_settings)
258 with self.assertRaises(NotFound):
259 self.volume_creator.create(block=True)
261 def test_create_volume_bad_image(self):
263 Tests the creation of an OpenStack volume with an image that does not
264 exist to ensure it raises a BadRequest exception.
266 volume_settings = VolumeSettings(
267 name=self.__class__.__name__ + '-' + str(self.guid),
271 self.volume_creator = OpenStackVolume(self.os_creds, volume_settings)
273 with self.assertRaises(BadRequest):
274 self.volume_creator.create(block=True)
276 def test_create_volume_bad_zone(self):
278 Tests the creation of an OpenStack volume with an availability zone
279 that does not exist to ensure it raises a BadRequest exception.
281 volume_settings = VolumeSettings(
282 name=self.__class__.__name__ + '-' + str(self.guid),
283 availability_zone='foo')
286 self.volume_creator = OpenStackVolume(self.os_creds, volume_settings)
288 with self.assertRaises(BadRequest):
289 self.volume_creator.create(block=True)
292 class CreateVolumeWithTypeTests(OSIntegrationTestCase):
294 Test cases for the CreateVolume when attempting to associate it to a
299 super(self.__class__, self).__start__()
301 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
302 self.volume_name = guid + '-vol'
303 self.volume_type_name = guid + '-vol-type'
305 self.volume_type_creator = OpenStackVolumeType(
306 self.os_creds, VolumeTypeSettings(name=self.volume_type_name))
307 self.volume_type_creator.create()
308 self.volume_creator = None
311 if self.volume_creator:
312 self.volume_creator.clean()
313 if self.volume_type_creator:
314 self.volume_type_creator.clean()
316 super(self.__class__, self).__clean__()
318 def test_bad_volume_type(self):
320 Expect a NotFound to be raised when the volume type does not exist
322 self.volume_creator = OpenStackVolume(
324 VolumeSettings(name=self.volume_name, type_name='foo'))
326 with self.assertRaises(NotFound):
327 self.volume_creator.create()
329 def test_valid_volume_type(self):
331 Expect a NotFound to be raised when the volume type does not exist
333 self.volume_creator = OpenStackVolume(
335 VolumeSettings(name=self.volume_name,
336 type_name=self.volume_type_name))
338 created_volume = self.volume_creator.create(block=True)
339 self.assertIsNotNone(created_volume)
340 self.assertEqual(self.volume_type_name, created_volume.type)
343 class CreateVolumeWithImageTests(OSIntegrationTestCase):
345 Test cases for the CreateVolume when attempting to associate it to an Image
349 super(self.__class__, self).__start__()
351 self.cinder = cinder_utils.cinder_client(self.os_creds)
353 guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
354 self.volume_name = guid + '-vol'
355 self.image_name = guid + '-image'
357 os_image_settings = openstack_tests.cirros_image_settings(
358 name=self.image_name, image_metadata=self.image_metadata)
360 self.image_creator = OpenStackImage(self.os_creds,
362 self.image_creator.create()
363 self.volume_creator = None
366 if self.volume_creator:
368 self.volume_creator.clean()
371 if self.image_creator:
373 self.image_creator.clean()
377 super(self.__class__, self).__clean__()
379 def test_bad_image_name(self):
381 Tests OpenStackVolume#create() method to ensure a volume is NOT created
382 when associating it to an invalid image name
384 self.volume_creator = OpenStackVolume(
386 VolumeSettings(name=self.volume_name, image_name='foo'))
388 with self.assertRaises(BadRequest):
389 self.volume_creator.create(block=True)
391 def test_valid_volume_image(self):
393 Tests OpenStackVolume#create() method to ensure a volume is NOT created
394 when associating it to an invalid image name
396 self.volume_creator = OpenStackVolume(
398 VolumeSettings(name=self.volume_name, image_name=self.image_name))
400 created_volume = self.volume_creator.create(block=True)
401 self.assertIsNotNone(created_volume)
403 self.volume_creator.volume_settings.name, created_volume.name)
404 self.assertTrue(self.volume_creator.volume_active())
406 retrieved_volume = cinder_utils.get_volume_by_id(
407 self.cinder, created_volume.id)
409 self.assertEqual(created_volume, retrieved_volume)