blob: 06e9ab2591d6eb9d413cf76b1049acb96ecc976f [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:
Matthew Treinishb86cda92013-07-29 11:22:23 -040057 creds = cls.isolated_creds.get_alt_creds()
Attila Fazekas19044d52013-02-16 07:35:06 +010058 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
Giulio Fidente6cc3ade2013-08-23 17:21:03 +020067 @testtools.skip("Skipped until the Bug #1006725 is resolved.")
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
Mate Lakatba417262013-07-05 18:03:11 +010092 def _get_default_flavor_disk_size(self, flavor_id):
93 resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
94 return flavor['disk']
95
ivan-zhu1feeb382013-01-24 10:14:39 +080096 @testtools.skipUnless(compute.CREATE_IMAGE_ENABLED,
97 'Environment unable to create images.')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040098 @attr(type='smoke')
Attila Fazekas46a1d922013-01-11 10:19:42 +010099 def test_create_delete_image(self):
100
101 # Create a new image
102 name = rand_name('image')
103 meta = {'image_type': 'test'}
104 resp, body = self.client.create_image(self.server['id'], name, meta)
105 self.assertEqual(202, resp.status)
106 image_id = parse_image_id(resp['location'])
107 self.client.wait_for_image_resp_code(image_id, 200)
108 self.client.wait_for_image_status(image_id, 'ACTIVE')
109
110 # Verify the image was created correctly
111 resp, image = self.client.get_image(image_id)
112 self.assertEqual(name, image['name'])
113 self.assertEqual('test', image['metadata']['image_type'])
114
Attila Fazekas46a1d922013-01-11 10:19:42 +0100115 resp, original_image = self.client.get_image(self.image_ref)
Mate Lakatba417262013-07-05 18:03:11 +0100116
117 # Verify minRAM is the same as the original image
118 self.assertEqual(image['minRam'], original_image['minRam'])
119
120 # Verify minDisk is the same as the original image or the flavor size
121 flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref)
122 self.assertIn(str(image['minDisk']),
123 (str(original_image['minDisk']), str(flavor_disk_size)))
Attila Fazekas46a1d922013-01-11 10:19:42 +0100124
Prem Karat325ed282013-04-24 23:57:24 +0530125 # Verify the image was deleted correctly
126 resp, body = self.client.delete_image(image_id)
127 self.assertEqual('204', resp['status'])
Matthew Treinish0d660492013-06-04 17:26:09 -0400128 self.client.wait_for_resource_deletion(image_id)
Prem Karat325ed282013-04-24 23:57:24 +0530129
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400130 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100131 def test_create_second_image_when_first_image_is_being_saved(self):
132 # Disallow creating another image when first image is being saved
133
Chris Yeohe04628e2013-02-25 17:12:21 +1030134 # Create first snapshot
135 snapshot_name = rand_name('test-snap-')
136 resp, body = self.client.create_image(self.server['id'],
137 snapshot_name)
138 self.assertEqual(202, resp.status)
139 image_id = parse_image_id(resp['location'])
140 self.image_ids.append(image_id)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100141
Chris Yeohe04628e2013-02-25 17:12:21 +1030142 # Create second snapshot
143 alt_snapshot_name = rand_name('test-snap-')
144 self.assertRaises(exceptions.Duplicate, self.client.create_image,
145 self.server['id'], alt_snapshot_name)
146 self.client.wait_for_image_status(image_id, 'ACTIVE')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100147
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400148 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100149 def test_create_image_specify_name_over_256_chars(self):
150 # Return an error if snapshot name over 256 characters is passed
151
Chris Yeohe04628e2013-02-25 17:12:21 +1030152 snapshot_name = rand_name('a' * 260)
153 self.assertRaises(exceptions.BadRequest, self.client.create_image,
154 self.server['id'], snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100155
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400156 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100157 def test_delete_image_that_is_not_yet_active(self):
158 # Return an error while trying to delete an image what is creating
159
160 snapshot_name = rand_name('test-snap-')
161 resp, body = self.client.create_image(self.server['id'], snapshot_name)
162 self.assertEqual(202, resp.status)
163 image_id = parse_image_id(resp['location'])
164 self.image_ids.append(image_id)
165
166 # Do not wait, attempt to delete the image, ensure it's successful
167 resp, body = self.client.delete_image(image_id)
168 self.assertEqual('204', resp['status'])
169 self.image_ids.remove(image_id)
170
171 self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
172
173
Attila Fazekas19044d52013-02-16 07:35:06 +0100174class ImagesOneServerTestXML(ImagesOneServerTestJSON):
175 _interface = 'xml'