blob: 1fc03b8d75ae406d83ee74aa661822fc53665fc4 [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
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060018from nose.plugins.attrib import attr
ivan-zhu1feeb382013-01-24 10:14:39 +080019import testtools
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060020
Matthew Treinish481466b2012-12-20 17:16:01 -050021from tempest import clients
Matthew Treinisha83a16e2012-12-07 13:44:02 -050022from tempest.common.utils.data_utils import parse_image_id
23from tempest.common.utils.data_utils import rand_name
Brian Waldon738cd632011-12-12 18:45:09 -050024import tempest.config
Jay Pipes13b479b2012-06-11 14:52:27 -040025from tempest import exceptions
Jay Pipesf38eaac2012-06-21 13:37:35 -040026from tempest.tests import compute
Matthew Treinisha83a16e2012-12-07 13:44:02 -050027from tempest.tests.compute import base
Jay Pipes7f757632011-12-02 15:53:32 -050028
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060029
Dan Smithe7316bb2012-08-14 12:35:34 -070030class ImagesTestBase(object):
Rohit Karajgiea462ae2012-05-27 21:23:21 -070031
32 def tearDown(self):
Sean Daguef237ccb2013-01-04 15:19:14 -050033 """Terminate test instances created after a test is executed."""
Rohit Karajgiea462ae2012-05-27 21:23:21 -070034 for server in self.servers:
35 resp, body = self.servers_client.delete_server(server['id'])
36 if resp['status'] == '204':
37 self.servers.remove(server)
38 self.servers_client.wait_for_server_termination(server['id'])
39
40 for image_id in self.image_ids:
41 self.client.delete_image(image_id)
42 self.image_ids.remove(image_id)
Daryl Walleck73a9e7a2011-11-15 17:43:31 -060043
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080044 @attr(type='negative')
45 def test_create_image_from_deleted_server(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050046 # An image should not be created if the server instance is removed
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080047 server_name = rand_name('server')
48 resp, server = self.servers_client.create_server(server_name,
49 self.image_ref,
50 self.flavor_ref)
51 self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
52
53 # Delete server before trying to create server
54 self.servers_client.delete_server(server['id'])
55
56 try:
57 # Create a new image after server is deleted
58 name = rand_name('image')
59 meta = {'image_type': 'test'}
60 resp, body = self.client.create_image(server['id'], name, meta)
61
Matthew Treinish05d9fb92012-12-07 16:14:05 -050062 except Exception:
Ravikumar Venkatesan94d81172012-01-09 21:53:14 -080063 pass
64
65 else:
Jay Pipesf38eaac2012-06-21 13:37:35 -040066 image_id = parse_image_id(resp['location'])
Daryl Walleckade49f92012-01-16 23:14:26 -060067 self.client.wait_for_image_resp_code(image_id, 200)
68 self.client.wait_for_image_status(image_id, 'ACTIVE')
Jay Pipes04b70812012-01-11 10:53:24 -050069 self.client.delete_image(image_id)
Daryl Walleckade49f92012-01-16 23:14:26 -060070 self.fail("Should not create snapshot from deleted instance!")
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053071
72 @attr(type='negative')
73 def test_create_image_from_invalid_server(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050074 # An image should not be created with invalid server id
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053075 try:
76 # Create a new image with invalid server id
77 name = rand_name('image')
78 meta = {'image_type': 'test'}
79 resp = {}
80 resp['status'] = None
81 resp, body = self.client.create_image('!@#$%^&*()', name, meta)
82
83 except exceptions.NotFound:
84 pass
85
86 finally:
Zhongyue Luoe471d6e2012-09-17 17:02:43 +080087 if (resp['status'] is not None):
Jay Pipesf38eaac2012-06-21 13:37:35 -040088 image_id = parse_image_id(resp['location'])
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053089 resp, _ = self.client.delete_image(image_id)
Zhongyue Luoe0884a32012-09-25 17:24:17 +080090 self.fail("An image should not be created "
91 "with invalid server id")
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +053092
93 @attr(type='negative')
Attila Fazekas46a1d922013-01-11 10:19:42 +010094 def test_create_image_when_server_is_terminating(self):
95 # Return an error when creating image of server that is terminating
Rohit Karajgiea462ae2012-05-27 21:23:21 -070096 server = self.create_server()
Attila Fazekas46a1d922013-01-11 10:19:42 +010097 self.servers_client.delete_server(server['id'])
Rohit Karajgiea462ae2012-05-27 21:23:21 -070098
99 snapshot_name = rand_name('test-snap-')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100100 self.assertRaises(exceptions.Duplicate, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700101 server['id'], snapshot_name)
102
103 @attr(type='negative')
104 def test_create_image_when_server_is_building(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500105 # Return error when creating an image of a server that is building
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700106 server_name = rand_name('test-vm-')
107 resp, server = self.servers_client.create_server(server_name,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800108 self.image_ref,
109 self.flavor_ref)
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700110 self.servers.append(server)
111 snapshot_name = rand_name('test-snap-')
112 self.assertRaises(exceptions.Duplicate, self.client.create_image,
113 server['id'], snapshot_name)
114
ivan-zhu1feeb382013-01-24 10:14:39 +0800115 @testtools.skip("Until Bug 1039739 is fixed")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700116 @attr(type='negative')
117 def test_create_image_when_server_is_rebooting(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500118 # Return error when creating an image of server that is rebooting
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700119 server = self.create_server()
120 self.servers_client.reboot(server['id'], 'HARD')
121
122 snapshot_name = rand_name('test-snap-')
123 self.assertRaises(exceptions.Duplicate, self.client.create_image,
124 server['id'], snapshot_name)
125
126 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700127 def test_create_image_specify_uuid_35_characters_or_less(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500128 # Return an error if Image ID passed is 35 characters or less
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700129 try:
130 snapshot_name = rand_name('test-snap-')
131 test_uuid = ('a' * 35)
Joe Gordonf26620f2012-09-13 12:34:35 -0700132 self.assertRaises(exceptions.NotFound, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700133 test_uuid, snapshot_name)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500134 except Exception:
Joe Gordonf26620f2012-09-13 12:34:35 -0700135 self.fail("Should return 404 Not Found if server uuid is 35"
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700136 " characters or less")
137
138 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700139 def test_create_image_specify_uuid_37_characters_or_more(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500140 # Return an error if Image ID passed is 37 characters or more
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700141 try:
142 snapshot_name = rand_name('test-snap-')
143 test_uuid = ('a' * 37)
Joe Gordonf26620f2012-09-13 12:34:35 -0700144 self.assertRaises(exceptions.NotFound, self.client.create_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700145 test_uuid, snapshot_name)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500146 except Exception:
Joe Gordonf26620f2012-09-13 12:34:35 -0700147 self.fail("Should return 404 Not Found if server uuid is 37"
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700148 " characters or more")
149
150 @attr(type='negative')
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +0530151 def test_delete_image_with_invalid_image_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500152 # An image should not be deleted with invalid image id
rajalakshmi-ganesan32f8db62012-05-18 19:13:40 +0530153 try:
154 # Delete an image with invalid image id
155 resp, _ = self.client.delete_image('!@$%^&*()')
156
157 except exceptions.NotFound:
158 pass
159
160 else:
Zhongyue Luoe0884a32012-09-25 17:24:17 +0800161 self.fail("DELETE image request should rasie NotFound exception "
162 "when requested with invalid image")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700163
164 @attr(type='negative')
165 def test_delete_non_existent_image(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500166 # Return an error while trying to delete a non-existent image
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700167
168 non_existent_image_id = '11a22b9-12a9-5555-cc11-00ab112223fa'
169 self.assertRaises(exceptions.NotFound, self.client.delete_image,
170 non_existent_image_id)
171
172 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700173 def test_delete_image_blank_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500174 # Return an error while trying to delete an image with blank Id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700175
176 try:
David Kranz28e35c52012-07-10 10:14:38 -0400177 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700178 '')
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500179 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400180 self.fail("Did not return HTTP 404 NotFound for blank image id")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700181
182 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700183 def test_delete_image_non_hex_string_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500184 # Return an error while trying to delete an image with non hex id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700185
186 image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
187 try:
David Kranz28e35c52012-07-10 10:14:38 -0400188 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800189 image_id)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500190 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400191 self.fail("Did not return HTTP 404 NotFound for non hex image")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700192
193 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700194 def test_delete_image_negative_image_id(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500195 # Return an error while trying to delete an image with negative id
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700196
197 try:
David Kranz28e35c52012-07-10 10:14:38 -0400198 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700199 -1)
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500200 except Exception:
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800201 self.fail("Did not return HTTP 404 NotFound for negative image id")
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700202
203 @attr(type='negative')
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700204 def test_delete_image_id_is_over_35_character_limit(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500205 # Return an error while trying to delete image with id over limit
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700206
207 try:
David Kranz28e35c52012-07-10 10:14:38 -0400208 self.assertRaises(exceptions.NotFound, self.client.delete_image,
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700209 '11a22b9-120q-5555-cc11-00ab112223gj-3fac')
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500210 except Exception:
David Kranz28e35c52012-07-10 10:14:38 -0400211 self.fail("Did not return HTTP 404 NotFound for image id that "
Rohit Karajgiea462ae2012-05-27 21:23:21 -0700212 "exceeds 35 character ID length limit")
213
Dan Smithe7316bb2012-08-14 12:35:34 -0700214
James E. Blaire6d8ee12013-01-18 21:33:45 +0000215class ImagesTestJSON(base.BaseComputeTestJSON,
216 ImagesTestBase):
Dan Smithe7316bb2012-08-14 12:35:34 -0700217 def tearDown(self):
218 ImagesTestBase.tearDown(self)
ivan-zhu1feeb382013-01-24 10:14:39 +0800219 base.BaseComputeTestJSON.tearDown(self)
Dan Smithe7316bb2012-08-14 12:35:34 -0700220
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)
ivan-zhu1feeb382013-01-24 10:14:39 +0800246 base.BaseComputeTestXML.tearDown(self)
James E. Blaire6d8ee12013-01-18 21:33:45 +0000247
248 @classmethod
249 def setUpClass(cls):
250 super(ImagesTestXML, cls).setUpClass()
Dan Smithe7316bb2012-08-14 12:35:34 -0700251 cls.client = cls.images_client
252 cls.servers_client = cls.servers_client
253
254 cls.image_ids = []
255
256 if compute.MULTI_USER:
257 if cls.config.compute.allow_tenant_isolation:
258 creds = cls._get_isolated_creds()
259 username, tenant_name, password = creds
Matthew Treinish481466b2012-12-20 17:16:01 -0500260 cls.alt_manager = clients.Manager(username=username,
261 password=password,
262 tenant_name=tenant_name)
Dan Smithe7316bb2012-08-14 12:35:34 -0700263 else:
264 # Use the alt_XXX credentials in the config file
Matthew Treinish481466b2012-12-20 17:16:01 -0500265 cls.alt_manager = clients.AltManager()
Dan Smithe7316bb2012-08-14 12:35:34 -0700266 cls.alt_client = cls.alt_manager.images_client