blob: 64f185493fe9d9300024078bd4c975855fd591ce [file] [log] [blame]
Attila Fazekas46a1d922013-01-11 10:19:42 +01001# 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
ivan-zhu1feeb382013-01-24 10:14:39 +080018import testtools
Attila Fazekas46a1d922013-01-11 10:19:42 +010019
Sean Dague1937d092013-05-17 16:36:38 -040020from tempest.api import compute
21from tempest.api.compute import base
Attila Fazekas46a1d922013-01-11 10:19:42 +010022from tempest import clients
23from tempest.common.utils.data_utils import parse_image_id
24from tempest.common.utils.data_utils import rand_name
Attila Fazekas46a1d922013-01-11 10:19:42 +010025from tempest import exceptions
Chris Yeoh9465b0b2013-02-09 22:19:15 +103026from tempest.test import attr
Attila Fazekas46a1d922013-01-11 10:19:42 +010027
28
Attila Fazekas19044d52013-02-16 07:35:06 +010029class ImagesOneServerTestJSON(base.BaseComputeTest):
30 _interface = 'json'
31
Attila Fazekas46a1d922013-01-11 10:19:42 +010032 def tearDown(self):
33 """Terminate test instances created after a test is executed."""
34 for image_id in self.image_ids:
35 self.client.delete_image(image_id)
36 self.image_ids.remove(image_id)
Attila Fazekas19044d52013-02-16 07:35:06 +010037 super(ImagesOneServerTestJSON, self).tearDown()
38
39 @classmethod
40 def setUpClass(cls):
41 super(ImagesOneServerTestJSON, cls).setUpClass()
42 cls.client = cls.images_client
Matthew Treinish853ae442013-07-19 16:36:07 -040043 if not cls.config.service_available.glance:
44 skip_msg = ("%s skipped as glance is not available" % cls.__name__)
45 raise cls.skipException(skip_msg)
ivan-zhubf88a632013-03-26 13:29:21 +080046
47 try:
48 resp, cls.server = cls.create_server(wait_until='ACTIVE')
49 except Exception:
50 cls.tearDownClass()
51 raise
Attila Fazekas19044d52013-02-16 07:35:06 +010052
53 cls.image_ids = []
54
55 if compute.MULTI_USER:
56 if cls.config.compute.allow_tenant_isolation:
57 creds = cls._get_isolated_creds()
58 username, tenant_name, password = creds
59 cls.alt_manager = clients.Manager(username=username,
60 password=password,
61 tenant_name=tenant_name)
62 else:
63 # Use the alt_XXX credentials in the config file
64 cls.alt_manager = clients.AltManager()
65 cls.alt_client = cls.alt_manager.images_client
Attila Fazekas46a1d922013-01-11 10:19:42 +010066
Matthew Treinish770e5a42013-03-22 15:35:16 -040067 @testtools.skip("Until Bug #1006725 is fixed")
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040068 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010069 def test_create_image_specify_multibyte_character_image_name(self):
70 # Return an error if the image name has multi-byte characters
Chris Yeohe04628e2013-02-25 17:12:21 +103071 snapshot_name = rand_name('\xef\xbb\xbf')
72 self.assertRaises(exceptions.BadRequest,
73 self.client.create_image, self.server['id'],
74 snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +010075
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040076 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010077 def test_create_image_specify_invalid_metadata(self):
78 # Return an error when creating image with invalid metadata
Chris Yeohe04628e2013-02-25 17:12:21 +103079 snapshot_name = rand_name('test-snap-')
80 meta = {'': ''}
81 self.assertRaises(exceptions.BadRequest, self.client.create_image,
82 self.server['id'], snapshot_name, meta)
Attila Fazekas46a1d922013-01-11 10:19:42 +010083
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040084 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010085 def test_create_image_specify_metadata_over_limits(self):
86 # Return an error when creating image with meta data over 256 chars
Chris Yeohe04628e2013-02-25 17:12:21 +103087 snapshot_name = rand_name('test-snap-')
88 meta = {'a' * 260: 'b' * 260}
Prem Karat586136a2013-04-25 17:03:48 +053089 self.assertRaises(exceptions.BadRequest, self.client.create_image,
Chris Yeohe04628e2013-02-25 17:12:21 +103090 self.server['id'], snapshot_name, meta)
Attila Fazekas46a1d922013-01-11 10:19:42 +010091
ivan-zhu1feeb382013-01-24 10:14:39 +080092 @testtools.skipUnless(compute.MULTI_USER,
93 'Need multiple users for this test.')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040094 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010095 def test_delete_image_of_another_tenant(self):
96 # Return an error while trying to delete another tenant's image
97 self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
98 snapshot_name = rand_name('test-snap-')
99 resp, body = self.client.create_image(self.server['id'], snapshot_name)
100 image_id = parse_image_id(resp['location'])
101 self.image_ids.append(image_id)
102 self.client.wait_for_image_resp_code(image_id, 200)
103 self.client.wait_for_image_status(image_id, 'ACTIVE')
104
105 # Delete image
106 self.assertRaises(exceptions.NotFound,
107 self.alt_client.delete_image, image_id)
108
Mate Lakatba417262013-07-05 18:03:11 +0100109 def _get_default_flavor_disk_size(self, flavor_id):
110 resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
111 return flavor['disk']
112
ivan-zhu1feeb382013-01-24 10:14:39 +0800113 @testtools.skipUnless(compute.CREATE_IMAGE_ENABLED,
114 'Environment unable to create images.')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400115 @attr(type='smoke')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100116 def test_create_delete_image(self):
117
118 # Create a new image
119 name = rand_name('image')
120 meta = {'image_type': 'test'}
121 resp, body = self.client.create_image(self.server['id'], name, meta)
122 self.assertEqual(202, resp.status)
123 image_id = parse_image_id(resp['location'])
124 self.client.wait_for_image_resp_code(image_id, 200)
125 self.client.wait_for_image_status(image_id, 'ACTIVE')
126
127 # Verify the image was created correctly
128 resp, image = self.client.get_image(image_id)
129 self.assertEqual(name, image['name'])
130 self.assertEqual('test', image['metadata']['image_type'])
131
Attila Fazekas46a1d922013-01-11 10:19:42 +0100132 resp, original_image = self.client.get_image(self.image_ref)
Mate Lakatba417262013-07-05 18:03:11 +0100133
134 # Verify minRAM is the same as the original image
135 self.assertEqual(image['minRam'], original_image['minRam'])
136
137 # Verify minDisk is the same as the original image or the flavor size
138 flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref)
139 self.assertIn(str(image['minDisk']),
140 (str(original_image['minDisk']), str(flavor_disk_size)))
Attila Fazekas46a1d922013-01-11 10:19:42 +0100141
Prem Karat325ed282013-04-24 23:57:24 +0530142 # Verify the image was deleted correctly
143 resp, body = self.client.delete_image(image_id)
144 self.assertEqual('204', resp['status'])
Matthew Treinish0d660492013-06-04 17:26:09 -0400145 self.client.wait_for_resource_deletion(image_id)
Prem Karat325ed282013-04-24 23:57:24 +0530146
ivan-zhu1feeb382013-01-24 10:14:39 +0800147 @testtools.skipUnless(compute.MULTI_USER,
148 'Need multiple users for this test.')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400149 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100150 def test_create_image_for_server_in_another_tenant(self):
151 # Creating image of another tenant's server should be return error
152
153 snapshot_name = rand_name('test-snap-')
154 self.assertRaises(exceptions.NotFound, self.alt_client.create_image,
155 self.server['id'], snapshot_name)
156
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400157 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100158 def test_create_second_image_when_first_image_is_being_saved(self):
159 # Disallow creating another image when first image is being saved
160
Chris Yeohe04628e2013-02-25 17:12:21 +1030161 # Create first snapshot
162 snapshot_name = rand_name('test-snap-')
163 resp, body = self.client.create_image(self.server['id'],
164 snapshot_name)
165 self.assertEqual(202, resp.status)
166 image_id = parse_image_id(resp['location'])
167 self.image_ids.append(image_id)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100168
Chris Yeohe04628e2013-02-25 17:12:21 +1030169 # Create second snapshot
170 alt_snapshot_name = rand_name('test-snap-')
171 self.assertRaises(exceptions.Duplicate, self.client.create_image,
172 self.server['id'], alt_snapshot_name)
173 self.client.wait_for_image_status(image_id, 'ACTIVE')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100174
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400175 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100176 def test_create_image_specify_name_over_256_chars(self):
177 # Return an error if snapshot name over 256 characters is passed
178
Chris Yeohe04628e2013-02-25 17:12:21 +1030179 snapshot_name = rand_name('a' * 260)
180 self.assertRaises(exceptions.BadRequest, self.client.create_image,
181 self.server['id'], snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100182
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400183 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100184 def test_delete_image_that_is_not_yet_active(self):
185 # Return an error while trying to delete an image what is creating
186
187 snapshot_name = rand_name('test-snap-')
188 resp, body = self.client.create_image(self.server['id'], snapshot_name)
189 self.assertEqual(202, resp.status)
190 image_id = parse_image_id(resp['location'])
191 self.image_ids.append(image_id)
192
193 # Do not wait, attempt to delete the image, ensure it's successful
194 resp, body = self.client.delete_image(image_id)
195 self.assertEqual('204', resp['status'])
196 self.image_ids.remove(image_id)
197
198 self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
199
200
Attila Fazekas19044d52013-02-16 07:35:06 +0100201class ImagesOneServerTestXML(ImagesOneServerTestJSON):
202 _interface = 'xml'