blob: 2557f1647567b6682c566a4c47baea4bc2e86ac5 [file] [log] [blame]
Jay Pipes13b479b2012-06-11 14:52:27 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
Matthew Treinisha83a16e2012-12-07 13:44:02 -050018import nose
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060019from nose.plugins.attrib import attr
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060020import unittest2 as unittest
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060021
Matthew Treinish481466b2012-12-20 17:16:01 -050022from tempest import clients
Matthew Treinisha83a16e2012-12-07 13:44:02 -050023from tempest.common.utils.data_utils import parse_image_id
24from tempest.common.utils.data_utils import rand_name
Brian Waldon738cd632011-12-12 18:45:09 -050025import tempest.config
Jay Pipes13b479b2012-06-11 14:52:27 -040026from tempest import exceptions
Jay Pipesf38eaac2012-06-21 13:37:35 -040027from tempest.tests import compute
Matthew Treinisha83a16e2012-12-07 13:44:02 -050028from tempest.tests.compute import base
Jay Pipes7f757632011-12-02 15:53:32 -050029
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060030
Dan Smithe7316bb2012-08-14 12:35:34 -070031class ImagesTestBase(object):
Rohit Karajgiea462ae2012-05-27 21:23:21 -070032
33 def tearDown(self):
Sean Daguef237ccb2013-01-04 15:19:14 -050034 """Terminate test instances created after a test is executed."""
Rohit Karajgiea462ae2012-05-27 21:23:21 -070035 for server in self.servers:
36 resp, body = self.servers_client.delete_server(server['id'])
37 if resp['status'] == '204':
38 self.servers.remove(server)
39 self.servers_client.wait_for_server_termination(server['id'])
40
41 for image_id in self.image_ids:
42 self.client.delete_image(image_id)
43 self.image_ids.remove(image_id)
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060044
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080045 @attr(type='negative')
46 def test_create_image_from_deleted_server(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050047 # An image should not be created if the server instance is removed
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080048 server_name = rand_name('server')
49 resp, server = self.servers_client.create_server(server_name,
50 self.image_ref,
51 self.flavor_ref)
52 self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
53
54 # Delete server before trying to create server
55 self.servers_client.delete_server(server['id'])
56
57 try:
58 # Create a new image after server is deleted
59 name = rand_name('image')
60 meta = {'image_type': 'test'}
61 resp, body = self.client.create_image(server['id'], name, meta)
62
Matthew Treinish05d9fb92012-12-07 16:14:05 -050063 except Exception:
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080064 pass
65
66 else:
Jay Pipesf38eaac2012-06-21 13:37:35 -040067 image_id = parse_image_id(resp['location'])
Daryl Walleckade49f92012-01-16 23:14:26 -060068 self.client.wait_for_image_resp_code(image_id, 200)
69 self.client.wait_for_image_status(image_id, 'ACTIVE')
Jay Pipes04b70812012-01-11 10:53:24 -050070 self.client.delete_image(image_id)
Daryl Walleckade49f92012-01-16 23:14:26 -060071 self.fail("Should not create snapshot from deleted instance!")
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053072
73 @attr(type='negative')
74 def test_create_image_from_invalid_server(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050075 # An image should not be created with invalid server id
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053076 try:
77 # Create a new image with invalid server id
78 name = rand_name('image')
79 meta = {'image_type': 'test'}
80 resp = {}
81 resp['status'] = None
82 resp, body = self.client.create_image('!@#$%^&*()', name, meta)
83
84 except exceptions.NotFound:
85 pass
86
87 finally:
Zhongyue Luoe471d6e2012-09-17 17:02:43 +080088 if (resp['status'] is not None):
Jay Pipesf38eaac2012-06-21 13:37:35 -040089 image_id = parse_image_id(resp['location'])
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053090 resp, _ = self.client.delete_image(image_id)
Zhongyue Luoe0884a32012-09-25 17:24:17 +080091 self.fail("An image should not be created "
92 "with invalid server id")
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053093
94 @attr(type='negative')
Attila Fazekas46a1d922013-01-11 10:19:42 +010095 def test_create_image_when_server_is_terminating(self):
96 # Return an error when creating image of server that is terminating
Rohit Karajgiea462ae2012-05-27 21:23:21 -070097 server = self.create_server()
Attila Fazekas46a1d922013-01-11 10:19:42 +010098 self.servers_client.delete_server(server['id'])
Rohit Karajgiea462ae2012-05-27 21:23:21 -070099
100 snapshot_name = rand_name('test-snap-')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100101 self.assertRaises(exceptions.Duplicate, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700102 server['id'], snapshot_name)
103
104 @attr(type='negative')
105 def test_create_image_when_server_is_building(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500106 # Return error when creating an image of a server that is building
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700107 server_name = rand_name('test-vm-')
108 resp, server = self.servers_client.create_server(server_name,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800109 self.image_ref,
110 self.flavor_ref)
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700111 self.servers.append(server)
112 snapshot_name = rand_name('test-snap-')
113 self.assertRaises(exceptions.Duplicate, self.client.create_image,
114 server['id'], snapshot_name)
115
David Kranz0312b692012-08-21 17:51:17 -0400116 @unittest.skip("Until Bug 1039739 is fixed")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700117 @attr(type='negative')
118 def test_create_image_when_server_is_rebooting(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500119 # Return error when creating an image of server that is rebooting
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700120 server = self.create_server()
121 self.servers_client.reboot(server['id'], 'HARD')
122
123 snapshot_name = rand_name('test-snap-')
124 self.assertRaises(exceptions.Duplicate, self.client.create_image,
125 server['id'], snapshot_name)
126
127 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700128 def test_create_image_specify_uuid_35_characters_or_less(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500129 # Return an error if Image ID passed is 35 characters or less
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700130 try:
131 snapshot_name = rand_name('test-snap-')
132 test_uuid = ('a' * 35)
Joe Gordonf26620f2012-09-13 12:34:35 -0700133 self.assertRaises(exceptions.NotFound, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700134 test_uuid, snapshot_name)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500135 except Exception:
Joe Gordonf26620f2012-09-13 12:34:35 -0700136 self.fail("Should return 404 Not Found if server uuid is 35"
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700137 " characters or less")
138
139 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700140 def test_create_image_specify_uuid_37_characters_or_more(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500141 # Return an error if Image ID passed is 37 characters or more
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700142 try:
143 snapshot_name = rand_name('test-snap-')
144 test_uuid = ('a' * 37)
Joe Gordonf26620f2012-09-13 12:34:35 -0700145 self.assertRaises(exceptions.NotFound, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700146 test_uuid, snapshot_name)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500147 except Exception:
Joe Gordonf26620f2012-09-13 12:34:35 -0700148 self.fail("Should return 404 Not Found if server uuid is 37"
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700149 " characters or more")
150
151 @attr(type='negative')
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +0530152 def test_delete_image_with_invalid_image_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500153 # An image should not be deleted with invalid image id
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +0530154 try:
155 # Delete an image with invalid image id
156 resp, _ = self.client.delete_image('!@$%^&*()')
157
158 except exceptions.NotFound:
159 pass
160
161 else:
Zhongyue Luoe0884a32012-09-25 17:24:17 +0800162 self.fail("DELETE image request should rasie NotFound exception "
163 "when requested with invalid image")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700164
165 @attr(type='negative')
166 def test_delete_non_existent_image(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500167 # Return an error while trying to delete a non-existent image
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700168
169 non_existent_image_id = '11a22b9-12a9-5555-cc11-00ab112223fa'
170 self.assertRaises(exceptions.NotFound, self.client.delete_image,
171 non_existent_image_id)
172
173 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700174 def test_delete_image_blank_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500175 # Return an error while trying to delete an image with blank Id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700176
177 try:
David Kranz28e35c52012-07-10 10:14:38 -0400178 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700179 '')
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500180 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400181 self.fail("Did not return HTTP 404 NotFound for blank image id")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700182
183 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700184 def test_delete_image_non_hex_string_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500185 # Return an error while trying to delete an image with non hex id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700186
187 image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
188 try:
David Kranz28e35c52012-07-10 10:14:38 -0400189 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800190 image_id)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500191 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400192 self.fail("Did not return HTTP 404 NotFound for non hex image")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700193
194 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700195 def test_delete_image_negative_image_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500196 # Return an error while trying to delete an image with negative id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700197
198 try:
David Kranz28e35c52012-07-10 10:14:38 -0400199 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700200 -1)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500201 except Exception:
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800202 self.fail("Did not return HTTP 404 NotFound for negative image id")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700203
204 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700205 def test_delete_image_id_is_over_35_character_limit(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500206 # Return an error while trying to delete image with id over limit
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700207
208 try:
David Kranz28e35c52012-07-10 10:14:38 -0400209 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700210 '11a22b9-120q-5555-cc11-00ab112223gj-3fac')
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500211 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400212 self.fail("Did not return HTTP 404 NotFound for image id that "
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700213 "exceeds 35 character ID length limit")
214
Dan Smithe7316bb2012-08-14 12:35:34 -0700215
James E. Blaire6d8ee12013-01-18 21:33:45 +0000216class ImagesTestJSON(base.BaseComputeTestJSON,
217 ImagesTestBase):
Dan Smithe7316bb2012-08-14 12:35:34 -0700218 def tearDown(self):
219 ImagesTestBase.tearDown(self)
220
221 @classmethod
222 def setUpClass(cls):
James E. Blaire6d8ee12013-01-18 21:33:45 +0000223 super(ImagesTestJSON, cls).setUpClass()
224 cls.client = cls.images_client
225 cls.servers_client = cls.servers_client
226
227 cls.image_ids = []
228
229 if compute.MULTI_USER:
230 if cls.config.compute.allow_tenant_isolation:
231 creds = cls._get_isolated_creds()
232 username, tenant_name, password = creds
233 cls.alt_manager = clients.Manager(username=username,
234 password=password,
235 tenant_name=tenant_name)
236 else:
237 # Use the alt_XXX credentials in the config file
238 cls.alt_manager = clients.AltManager()
239 cls.alt_client = cls.alt_manager.images_client
240
241
242class ImagesTestXML(base.BaseComputeTestXML,
243 ImagesTestBase):
244 def tearDown(self):
245 ImagesTestBase.tearDown(self)
246
247 @classmethod
248 def setUpClass(cls):
249 super(ImagesTestXML, cls).setUpClass()
Dan Smithe7316bb2012-08-14 12:35:34 -0700250 cls.client = cls.images_client
251 cls.servers_client = cls.servers_client
252
253 cls.image_ids = []
254
255 if compute.MULTI_USER:
256 if cls.config.compute.allow_tenant_isolation:
257 creds = cls._get_isolated_creds()
258 username, tenant_name, password = creds
Matthew Treinish481466b2012-12-20 17:16:01 -0500259 cls.alt_manager = clients.Manager(username=username,
260 password=password,
261 tenant_name=tenant_name)
Dan Smithe7316bb2012-08-14 12:35:34 -0700262 else:
263 # Use the alt_XXX credentials in the config file
Matthew Treinish481466b2012-12-20 17:16:01 -0500264 cls.alt_manager = clients.AltManager()
Dan Smithe7316bb2012-08-14 12:35:34 -0700265 cls.alt_client = cls.alt_manager.images_client