24bf0f2091c2de54d6b9ac5b3425b4c567ede28a
[snaps.git] / snaps / openstack / tests / create_image_tests.py
1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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 import os
16 import shutil
17 import uuid
18 import unittest
19
20 from snaps import file_utils
21 from snaps.openstack.create_image import ImageSettings
22
23 import openstack_tests
24 from snaps.openstack.utils import glance_utils, nova_utils
25 from snaps.openstack import create_image
26 from snaps.openstack import os_credentials
27 from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
28
29 __author__ = 'spisarski'
30
31
32 class ImageSettingsUnitTests(unittest.TestCase):
33     """
34     Tests the construction of the ImageSettings class
35     """
36
37     def test_no_params(self):
38         with self.assertRaises(Exception):
39             ImageSettings()
40
41     def test_empty_config(self):
42         with self.assertRaises(Exception):
43             ImageSettings(config=dict())
44
45     def test_name_only(self):
46         with self.assertRaises(Exception):
47             ImageSettings(name='foo')
48
49     def test_config_with_name_only(self):
50         with self.assertRaises(Exception):
51             ImageSettings(config={'name': 'foo'})
52
53     def test_name_user_only(self):
54         with self.assertRaises(Exception):
55             ImageSettings(name='foo', image_user='bar')
56
57     def test_config_with_name_user_only(self):
58         with self.assertRaises(Exception):
59             ImageSettings(config={'name': 'foo', 'image_user': 'bar'})
60
61     def test_name_user_format_only(self):
62         with self.assertRaises(Exception):
63             ImageSettings(name='foo', image_user='bar', img_format='qcow2')
64
65     def test_config_with_name_user_format_only(self):
66         with self.assertRaises(Exception):
67             ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2'})
68
69     def test_name_user_format_url_file_only(self):
70         with self.assertRaises(Exception):
71             ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com',
72                           image_file='/foo/bar.qcow')
73
74     def test_config_with_name_user_format_url_file_only(self):
75         with self.assertRaises(Exception):
76             ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
77                                   'download_url': 'http://foo.com', 'image_file': '/foo/bar.qcow'})
78
79     def test_name_user_format_url_only(self):
80         settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com')
81         self.assertEquals('foo', settings.name)
82         self.assertEquals('bar', settings.image_user)
83         self.assertEquals('qcow2', settings.format)
84         self.assertEquals('http://foo.com', settings.url)
85         self.assertIsNone(settings.image_file)
86         self.assertIsNone(settings.nic_config_pb_loc)
87
88     def test_config_with_name_user_format_url_only(self):
89         settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
90                                          'download_url': 'http://foo.com'})
91         self.assertEquals('foo', settings.name)
92         self.assertEquals('bar', settings.image_user)
93         self.assertEquals('qcow2', settings.format)
94         self.assertEquals('http://foo.com', settings.url)
95         self.assertIsNone(settings.image_file)
96         self.assertIsNone(settings.nic_config_pb_loc)
97
98     def test_name_user_format_file_only(self):
99         settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow')
100         self.assertEquals('foo', settings.name)
101         self.assertEquals('bar', settings.image_user)
102         self.assertEquals('qcow2', settings.format)
103         self.assertIsNone(settings.url)
104         self.assertEquals('/foo/bar.qcow', settings.image_file)
105         self.assertIsNone(settings.nic_config_pb_loc)
106
107     def test_config_with_name_user_format_file_only(self):
108         settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
109                                          'image_file': '/foo/bar.qcow'})
110         self.assertEquals('foo', settings.name)
111         self.assertEquals('bar', settings.image_user)
112         self.assertEquals('qcow2', settings.format)
113         self.assertIsNone(settings.url)
114         self.assertEquals('/foo/bar.qcow', settings.image_file)
115         self.assertIsNone(settings.nic_config_pb_loc)
116
117     def test_all_url(self):
118         settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', url='http://foo.com',
119                                  nic_config_pb_loc='/foo/bar')
120         self.assertEquals('foo', settings.name)
121         self.assertEquals('bar', settings.image_user)
122         self.assertEquals('qcow2', settings.format)
123         self.assertEquals('http://foo.com', settings.url)
124         self.assertIsNone(settings.image_file)
125         self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
126
127     def test_config_all_url(self):
128         settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
129                                          'download_url': 'http://foo.com', 'nic_config_pb_loc': '/foo/bar'})
130         self.assertEquals('foo', settings.name)
131         self.assertEquals('bar', settings.image_user)
132         self.assertEquals('qcow2', settings.format)
133         self.assertEquals('http://foo.com', settings.url)
134         self.assertIsNone(settings.image_file)
135         self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
136
137     def test_all_file(self):
138         settings = ImageSettings(name='foo', image_user='bar', img_format='qcow2', image_file='/foo/bar.qcow',
139                                  nic_config_pb_loc='/foo/bar')
140         self.assertEquals('foo', settings.name)
141         self.assertEquals('bar', settings.image_user)
142         self.assertEquals('qcow2', settings.format)
143         self.assertIsNone(settings.url)
144         self.assertEquals('/foo/bar.qcow', settings.image_file)
145         self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
146
147     def test_config_all_file(self):
148         settings = ImageSettings(config={'name': 'foo', 'image_user': 'bar', 'format': 'qcow2',
149                                          'image_file': '/foo/bar.qcow', 'nic_config_pb_loc': '/foo/bar'})
150         self.assertEquals('foo', settings.name)
151         self.assertEquals('bar', settings.image_user)
152         self.assertEquals('qcow2', settings.format)
153         self.assertIsNone(settings.url)
154         self.assertEquals('/foo/bar.qcow', settings.image_file)
155         self.assertEquals('/foo/bar', settings.nic_config_pb_loc)
156
157
158 class CreateImageSuccessTests(OSIntegrationTestCase):
159     """
160     Test for the CreateImage class defined in create_image.py
161     """
162
163     def setUp(self):
164         """
165         Instantiates the CreateImage object that is responsible for downloading and creating an OS image file
166         within OpenStack
167         """
168         super(self.__class__, self).__start__()
169
170         guid = uuid.uuid4()
171         self.image_name = self.__class__.__name__ + '-' + str(guid)
172
173         self.nova = nova_utils.nova_client(self.os_creds)
174         self.glance = glance_utils.glance_client(self.os_creds)
175
176         self.tmp_dir = 'tmp/' + str(guid)
177         if not os.path.exists(self.tmp_dir):
178             os.makedirs(self.tmp_dir)
179
180     def tearDown(self):
181         """
182         Cleans the image and downloaded image file
183         """
184         if self.image_creator:
185             self.image_creator.clean()
186
187         if os.path.exists(self.tmp_dir) and os.path.isdir(self.tmp_dir):
188             shutil.rmtree(self.tmp_dir)
189
190         super(self.__class__, self).__clean__()
191
192     def test_create_image_clean_url(self):
193         """
194         Tests the creation of an OpenStack image from a URL.
195         """
196         # Create Image
197         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
198         self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
199
200         created_image = self.image_creator.create()
201         self.assertIsNotNone(created_image)
202
203         retrieved_image = glance_utils.get_image(self.nova, self.glance, os_image_settings.name)
204         self.assertIsNotNone(retrieved_image)
205
206         self.assertEquals(created_image.name, retrieved_image.name)
207         self.assertEquals(created_image.id, retrieved_image.id)
208
209     def test_create_image_clean_file(self):
210         """
211         Tests the creation of an OpenStack image from a file.
212         """
213         url_image_settings = openstack_tests.cirros_url_image('foo')
214         image_file = file_utils.download(url_image_settings.url, self.tmp_dir)
215         file_image_settings = openstack_tests.file_image_test_settings(name=self.image_name, file_path=image_file.name)
216         self.image_creator = create_image.OpenStackImage(self.os_creds, file_image_settings)
217
218         self.image = self.image_creator.create()
219         self.assertIsNotNone(self.image)
220         self.assertEqual(self.image_name, self.image.name)
221
222         created_image = self.image_creator.create()
223         self.assertIsNotNone(created_image)
224
225         retrieved_image = glance_utils.get_image(self.nova, self.glance, file_image_settings.name)
226         self.assertIsNotNone(retrieved_image)
227
228         self.assertEquals(created_image.name, retrieved_image.name)
229         self.assertEquals(created_image.id, retrieved_image.id)
230
231     def test_create_delete_image(self):
232         """
233         Tests the creation then deletion of an OpenStack image to ensure clean() does not raise an Exception.
234         """
235         # Create Image
236         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
237         self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
238         created_image = self.image_creator.create()
239         self.assertIsNotNone(created_image)
240
241         # Delete Image manually
242         glance_utils.delete_image(self.glance, created_image)
243
244         self.assertIsNone(glance_utils.get_image(self.nova, self.glance, self.image_creator.image_settings.name))
245
246         # Must not throw an exception when attempting to cleanup non-existent image
247         self.image_creator.clean()
248         self.assertIsNone(self.image_creator.get_image())
249
250     def test_create_same_image(self):
251         """
252         Tests the creation of an OpenStack image when the image already exists.
253         """
254         # Create Image
255         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
256         self.image_creator = create_image.OpenStackImage(self.os_creds, os_image_settings)
257         image1 = self.image_creator.create()
258         # Should be retrieving the instance data
259         os_image_2 = create_image.OpenStackImage(self.os_creds, os_image_settings)
260         image2 = os_image_2.create()
261         self.assertEquals(image1.id, image2.id)
262
263
264 class CreateImageNegativeTests(OSIntegrationTestCase):
265     """
266     Negative test cases for the CreateImage class
267     """
268
269     def setUp(self):
270         super(self.__class__, self).__start__()
271
272         self.image_name = self.__class__.__name__ + '-' + str(uuid.uuid4())
273         self.image_creator = None
274
275     def tearDown(self):
276         if self.image_creator:
277             self.image_creator.clean()
278
279         super(self.__class__, self).__clean__()
280
281     def test_none_image_name(self):
282         """
283         Expect an exception when the image name is None
284         """
285         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
286         with self.assertRaises(Exception):
287             self.image_creator = create_image.OpenStackImage(
288                 self.os_creds, create_image.ImageSettings(
289                     name=None, image_user=os_image_settings.image_user, img_format=os_image_settings.format,
290                     url=os_image_settings.url))
291
292             self.fail('Exception should have been thrown prior to this line')
293
294     def test_bad_image_url(self):
295         """
296         Expect an exception when the image download url is bad
297         """
298         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
299         self.image_creator = create_image.OpenStackImage(self.os_creds, create_image.ImageSettings(
300             name=os_image_settings.name, image_user=os_image_settings.image_user,
301             img_format=os_image_settings.format, url="http://foo.bar"))
302         with self.assertRaises(Exception):
303             self.image_creator.create()
304
305     def test_bad_image_file(self):
306         """
307         Expect an exception when the image file does not exist
308         """
309         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
310         self.image_creator = create_image.OpenStackImage(
311             self.os_creds,
312             create_image.ImageSettings(name=os_image_settings.name, image_user=os_image_settings.image_user,
313                                        img_format=os_image_settings.format, image_file="/foo/bar.qcow"))
314         with self.assertRaises(Exception):
315             self.image_creator.create()
316
317     def test_none_proj_name(self):
318         """
319         Expect an exception when the project name is None
320         """
321         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
322         with self.assertRaises(Exception):
323             self.image_creator = create_image.OpenStackImage(
324                 os_credentials.OSCreds(self.os_creds.username, self.os_creds.password, self.os_creds.auth_url, None,
325                                        proxy_settings=self.os_creds.proxy_settings),
326                 os_image_settings)
327             self.image_creator.create()
328
329     def test_none_auth_url(self):
330         """
331         Expect an exception when the project name is None
332         """
333         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
334         with self.assertRaises(Exception):
335             self.image_creator = create_image.OpenStackImage(
336                 os_credentials.OSCreds(self.os_creds.username, self.os_creds.password, None,
337                                        self.os_creds.project_name, proxy_settings=self.os_creds.proxy_settings),
338                 os_image_settings)
339             self.image_creator.create()
340
341     def test_none_password(self):
342         """
343         Expect an exception when the project name is None
344         """
345         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
346         with self.assertRaises(Exception):
347             self.image_creator = create_image.OpenStackImage(
348                 os_credentials.OSCreds(self.os_creds.username, None, self.os_creds.os_auth_url,
349                                        self.os_creds.project_name, proxy_settings=self.os_creds.proxy_settings),
350                 os_image_settings)
351
352     def test_none_user(self):
353         """
354         Expect an exception when the project name is None
355         """
356         os_image_settings = openstack_tests.cirros_url_image(name=self.image_name)
357         with self.assertRaises(Exception):
358             self.image_creator = create_image.OpenStackImage(
359                 os_credentials.OSCreds(None, self.os_creds.password, self.os_creds.os_auth_url,
360                                        self.os_creds.project_name,
361                                        proxy_settings=self.os_creds.proxy_settings),
362                 os_image_settings)