blob: d0bed57a9a698c0c821127534bc8cc0c8ca60b5f [file] [log] [blame]
Attila Fazekas46a1d922013-01-11 10:19:42 +01001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
ZhiQiang Fan39f97222013-09-20 04:49:44 +08003# Copyright 2012 OpenStack Foundation
Attila Fazekas46a1d922013-01-11 10:19:42 +01004# 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
Attila Fazekas4629a232013-10-16 17:20:45 +020026from tempest.openstack.common import log as logging
Chris Yeoh9465b0b2013-02-09 22:19:15 +103027from tempest.test import attr
Giulio Fidente83181a92013-10-01 06:02:24 +020028from tempest.test import skip_because
Attila Fazekas46a1d922013-01-11 10:19:42 +010029
Attila Fazekas4629a232013-10-16 17:20:45 +020030LOG = logging.getLogger(__name__)
31
Attila Fazekas46a1d922013-01-11 10:19:42 +010032
ivan-zhuf2b00502013-10-18 10:06:52 +080033class ImagesOneServerTestJSON(base.BaseV2ComputeTest):
Attila Fazekas19044d52013-02-16 07:35:06 +010034 _interface = 'json'
35
Attila Fazekas46a1d922013-01-11 10:19:42 +010036 def tearDown(self):
37 """Terminate test instances created after a test is executed."""
38 for image_id in self.image_ids:
39 self.client.delete_image(image_id)
40 self.image_ids.remove(image_id)
Attila Fazekas19044d52013-02-16 07:35:06 +010041 super(ImagesOneServerTestJSON, self).tearDown()
42
Attila Fazekas4629a232013-10-16 17:20:45 +020043 def setUp(self):
44 # NOTE(afazekas): Normally we use the same server with all test cases,
45 # but if it has an issue, we build a new one
46 super(ImagesOneServerTestJSON, self).setUp()
47 # Check if the server is in a clean state after test
48 try:
Sreeram Yerrapragada62c1d9c2013-10-21 14:14:43 -070049 self.servers_client.wait_for_server_status(self.server_id,
50 'ACTIVE')
Attila Fazekas4629a232013-10-16 17:20:45 +020051 except Exception as exc:
52 LOG.exception(exc)
53 # Rebuild server if cannot reach the ACTIVE state
54 # Usually it means the server had a serius accident
55 self.rebuild_server()
56
Attila Fazekas19044d52013-02-16 07:35:06 +010057 @classmethod
58 def setUpClass(cls):
59 super(ImagesOneServerTestJSON, cls).setUpClass()
60 cls.client = cls.images_client
Matthew Treinish853ae442013-07-19 16:36:07 -040061 if not cls.config.service_available.glance:
62 skip_msg = ("%s skipped as glance is not available" % cls.__name__)
63 raise cls.skipException(skip_msg)
ivan-zhubf88a632013-03-26 13:29:21 +080064
65 try:
Ken'ichi Ohmichicfc052e2013-10-23 11:50:04 +090066 resp, server = cls.create_test_server(wait_until='ACTIVE')
Attila Fazekas4629a232013-10-16 17:20:45 +020067 cls.server_id = server['id']
ivan-zhubf88a632013-03-26 13:29:21 +080068 except Exception:
69 cls.tearDownClass()
70 raise
Attila Fazekas19044d52013-02-16 07:35:06 +010071
72 cls.image_ids = []
73
74 if compute.MULTI_USER:
75 if cls.config.compute.allow_tenant_isolation:
Matthew Treinishb86cda92013-07-29 11:22:23 -040076 creds = cls.isolated_creds.get_alt_creds()
Attila Fazekas19044d52013-02-16 07:35:06 +010077 username, tenant_name, password = creds
78 cls.alt_manager = clients.Manager(username=username,
79 password=password,
80 tenant_name=tenant_name)
81 else:
82 # Use the alt_XXX credentials in the config file
83 cls.alt_manager = clients.AltManager()
84 cls.alt_client = cls.alt_manager.images_client
Attila Fazekas46a1d922013-01-11 10:19:42 +010085
Giulio Fidente83181a92013-10-01 06:02:24 +020086 @skip_because(bug="1006725")
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040087 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010088 def test_create_image_specify_multibyte_character_image_name(self):
89 # Return an error if the image name has multi-byte characters
Chris Yeohe04628e2013-02-25 17:12:21 +103090 snapshot_name = rand_name('\xef\xbb\xbf')
91 self.assertRaises(exceptions.BadRequest,
Attila Fazekas4629a232013-10-16 17:20:45 +020092 self.client.create_image, self.server_id,
Chris Yeohe04628e2013-02-25 17:12:21 +103093 snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +010094
Giampaolo Lauriae9c77022013-05-22 01:23:58 -040095 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +010096 def test_create_image_specify_invalid_metadata(self):
97 # Return an error when creating image with invalid metadata
Chris Yeohe04628e2013-02-25 17:12:21 +103098 snapshot_name = rand_name('test-snap-')
99 meta = {'': ''}
100 self.assertRaises(exceptions.BadRequest, self.client.create_image,
Attila Fazekas4629a232013-10-16 17:20:45 +0200101 self.server_id, snapshot_name, meta)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100102
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400103 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100104 def test_create_image_specify_metadata_over_limits(self):
105 # Return an error when creating image with meta data over 256 chars
Chris Yeohe04628e2013-02-25 17:12:21 +1030106 snapshot_name = rand_name('test-snap-')
107 meta = {'a' * 260: 'b' * 260}
Prem Karat586136a2013-04-25 17:03:48 +0530108 self.assertRaises(exceptions.BadRequest, self.client.create_image,
Attila Fazekas4629a232013-10-16 17:20:45 +0200109 self.server_id, snapshot_name, meta)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100110
Mate Lakatba417262013-07-05 18:03:11 +0100111 def _get_default_flavor_disk_size(self, flavor_id):
112 resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
113 return flavor['disk']
114
ivan-zhu1feeb382013-01-24 10:14:39 +0800115 @testtools.skipUnless(compute.CREATE_IMAGE_ENABLED,
116 'Environment unable to create images.')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400117 @attr(type='smoke')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100118 def test_create_delete_image(self):
119
120 # Create a new image
121 name = rand_name('image')
122 meta = {'image_type': 'test'}
Attila Fazekas4629a232013-10-16 17:20:45 +0200123 resp, body = self.client.create_image(self.server_id, name, meta)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100124 self.assertEqual(202, resp.status)
125 image_id = parse_image_id(resp['location'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100126 self.client.wait_for_image_status(image_id, 'ACTIVE')
127
128 # Verify the image was created correctly
129 resp, image = self.client.get_image(image_id)
130 self.assertEqual(name, image['name'])
131 self.assertEqual('test', image['metadata']['image_type'])
132
Attila Fazekas46a1d922013-01-11 10:19:42 +0100133 resp, original_image = self.client.get_image(self.image_ref)
Mate Lakatba417262013-07-05 18:03:11 +0100134
135 # Verify minRAM is the same as the original image
136 self.assertEqual(image['minRam'], original_image['minRam'])
137
138 # Verify minDisk is the same as the original image or the flavor size
139 flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref)
140 self.assertIn(str(image['minDisk']),
141 (str(original_image['minDisk']), str(flavor_disk_size)))
Attila Fazekas46a1d922013-01-11 10:19:42 +0100142
Prem Karat325ed282013-04-24 23:57:24 +0530143 # Verify the image was deleted correctly
144 resp, body = self.client.delete_image(image_id)
145 self.assertEqual('204', resp['status'])
Matthew Treinish0d660492013-06-04 17:26:09 -0400146 self.client.wait_for_resource_deletion(image_id)
Prem Karat325ed282013-04-24 23:57:24 +0530147
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400148 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100149 def test_create_second_image_when_first_image_is_being_saved(self):
150 # Disallow creating another image when first image is being saved
151
Chris Yeohe04628e2013-02-25 17:12:21 +1030152 # Create first snapshot
153 snapshot_name = rand_name('test-snap-')
Attila Fazekas4629a232013-10-16 17:20:45 +0200154 resp, body = self.client.create_image(self.server_id,
Chris Yeohe04628e2013-02-25 17:12:21 +1030155 snapshot_name)
156 self.assertEqual(202, resp.status)
157 image_id = parse_image_id(resp['location'])
158 self.image_ids.append(image_id)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100159
Chris Yeohe04628e2013-02-25 17:12:21 +1030160 # Create second snapshot
161 alt_snapshot_name = rand_name('test-snap-')
Anju5c3e510c2013-10-18 06:40:29 +0530162 self.assertRaises(exceptions.Conflict, self.client.create_image,
Attila Fazekas4629a232013-10-16 17:20:45 +0200163 self.server_id, alt_snapshot_name)
Chris Yeohe04628e2013-02-25 17:12:21 +1030164 self.client.wait_for_image_status(image_id, 'ACTIVE')
Attila Fazekas46a1d922013-01-11 10:19:42 +0100165
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400166 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100167 def test_create_image_specify_name_over_256_chars(self):
168 # Return an error if snapshot name over 256 characters is passed
169
Chris Yeohe04628e2013-02-25 17:12:21 +1030170 snapshot_name = rand_name('a' * 260)
171 self.assertRaises(exceptions.BadRequest, self.client.create_image,
Attila Fazekas4629a232013-10-16 17:20:45 +0200172 self.server_id, snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100173
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400174 @attr(type=['negative', 'gate'])
Attila Fazekas46a1d922013-01-11 10:19:42 +0100175 def test_delete_image_that_is_not_yet_active(self):
176 # Return an error while trying to delete an image what is creating
177
178 snapshot_name = rand_name('test-snap-')
Attila Fazekas4629a232013-10-16 17:20:45 +0200179 resp, body = self.client.create_image(self.server_id, snapshot_name)
Attila Fazekas46a1d922013-01-11 10:19:42 +0100180 self.assertEqual(202, resp.status)
181 image_id = parse_image_id(resp['location'])
182 self.image_ids.append(image_id)
183
184 # Do not wait, attempt to delete the image, ensure it's successful
185 resp, body = self.client.delete_image(image_id)
186 self.assertEqual('204', resp['status'])
187 self.image_ids.remove(image_id)
188
189 self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
190
191
Attila Fazekas19044d52013-02-16 07:35:06 +0100192class ImagesOneServerTestXML(ImagesOneServerTestJSON):
193 _interface = 'xml'