blob: 50756f642fe65c653548512ee506e164f3c29bd1 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipes13b479b2012-06-11 14:52:27 -04002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
David Kranzcf0040c2012-06-26 09:46:56 -040016import time
Jay Pipesf38eaac2012-06-21 13:37:35 -040017
Doug Hellmann583ce2c2015-03-11 14:55:46 +000018from oslo_log import log as logging
Matthew Treinish01472ff2015-02-20 17:26:52 -050019from tempest_lib import exceptions as lib_exc
20
Joseph Lanouxb3e1f872015-01-30 11:13:07 +000021from tempest.common import compute
Fei Long Wangd39431f2015-05-14 11:30:48 +120022from tempest.common.utils import data_utils
Ken'ichi Ohmichi8b9c7802015-07-08 05:57:37 +000023from tempest.common import waiters
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000024from tempest import config
David Kranz33138312013-09-24 17:09:32 -040025from tempest import exceptions
Attila Fazekasdc216422013-01-29 15:12:14 +010026import tempest.test
Jay Pipesf38eaac2012-06-21 13:37:35 -040027
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000028CONF = config.CONF
Tiago Melloeda03b52012-08-22 23:47:29 -030029
Jay Pipesf38eaac2012-06-21 13:37:35 -040030LOG = logging.getLogger(__name__)
Daryl Walleckc7251962012-03-12 17:26:54 -050031
32
Attila Fazekasdc216422013-01-29 15:12:14 +010033class BaseComputeTest(tempest.test.BaseTestCase):
Sean Daguef237ccb2013-01-04 15:19:14 -050034 """Base test case class for all Compute API tests."""
Daryl Walleckc7251962012-03-12 17:26:54 -050035
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +000036 _api_version = 2
Attila Fazekas430dae32013-10-17 15:19:32 +020037 force_tenant_isolation = False
Chris Yeoh8a79b9d2013-01-18 19:32:47 +103038
Andrea Frittolib21de6c2015-02-06 20:12:38 +000039 # TODO(andreaf) We should care also for the alt_manager here
40 # but only once client lazy load in the manager is done
41 credentials = ['primary']
42
Jay Pipesf38eaac2012-06-21 13:37:35 -040043 @classmethod
Emily Hugenbruche7991d92014-12-12 16:53:36 +000044 def skip_checks(cls):
45 super(BaseComputeTest, cls).skip_checks()
46 if cls._api_version != 2:
47 msg = ("Unexpected API version is specified (%s)" %
48 cls._api_version)
49 raise exceptions.InvalidConfiguration(message=msg)
Jay Pipesf38eaac2012-06-21 13:37:35 -040050
Emily Hugenbruche7991d92014-12-12 16:53:36 +000051 @classmethod
52 def setup_credentials(cls):
53 cls.set_network_resources()
54 super(BaseComputeTest, cls).setup_credentials()
Daryl Walleckc7251962012-03-12 17:26:54 -050055
Emily Hugenbruche7991d92014-12-12 16:53:36 +000056 @classmethod
57 def setup_clients(cls):
58 super(BaseComputeTest, cls).setup_clients()
59 cls.servers_client = cls.os.servers_client
Ken'ichi Ohmichi7ca54b82015-07-07 01:10:26 +000060 cls.server_groups_client = cls.os.server_groups_client
Emily Hugenbruche7991d92014-12-12 16:53:36 +000061 cls.flavors_client = cls.os.flavors_client
62 cls.images_client = cls.os.images_client
63 cls.extensions_client = cls.os.extensions_client
Ken'ichi Ohmichi03af1c52015-07-13 00:28:05 +000064 cls.floating_ip_pools_client = cls.os.floating_ip_pools_client
Emily Hugenbruche7991d92014-12-12 16:53:36 +000065 cls.floating_ips_client = cls.os.floating_ips_client
66 cls.keypairs_client = cls.os.keypairs_client
67 cls.security_groups_client = cls.os.security_groups_client
68 cls.quotas_client = cls.os.quotas_client
69 # NOTE(mriedem): os-quota-class-sets is v2 API only
70 cls.quota_classes_client = cls.os.quota_classes_client
71 # NOTE(mriedem): os-networks is v2 API only
72 cls.networks_client = cls.os.networks_client
73 cls.limits_client = cls.os.limits_client
74 cls.volumes_extensions_client = cls.os.volumes_extensions_client
75 cls.volumes_client = cls.os.volumes_client
76 cls.interfaces_client = cls.os.interfaces_client
77 cls.fixed_ips_client = cls.os.fixed_ips_client
78 cls.availability_zone_client = cls.os.availability_zone_client
79 cls.agents_client = cls.os.agents_client
80 cls.aggregates_client = cls.os.aggregates_client
81 cls.services_client = cls.os.services_client
82 cls.instance_usages_audit_log_client = (
83 cls.os.instance_usages_audit_log_client)
84 cls.hypervisor_client = cls.os.hypervisor_client
85 cls.certificates_client = cls.os.certificates_client
86 cls.migrations_client = cls.os.migrations_client
87 cls.security_group_default_rules_client = (
88 cls.os.security_group_default_rules_client)
89
90 @classmethod
91 def resource_setup(cls):
92 super(BaseComputeTest, cls).resource_setup()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000093 cls.build_interval = CONF.compute.build_interval
94 cls.build_timeout = CONF.compute.build_timeout
95 cls.ssh_user = CONF.compute.ssh_user
96 cls.image_ref = CONF.compute.image_ref
97 cls.image_ref_alt = CONF.compute.image_ref_alt
98 cls.flavor_ref = CONF.compute.flavor_ref
99 cls.flavor_ref_alt = CONF.compute.flavor_ref_alt
100 cls.image_ssh_user = CONF.compute.image_ssh_user
101 cls.image_ssh_password = CONF.compute.image_ssh_password
Jay Pipesf38eaac2012-06-21 13:37:35 -0400102 cls.servers = []
Sean Dagued62bf1c2013-06-05 14:36:25 -0400103 cls.images = []
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800104 cls.security_groups = []
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530105 cls.server_groups = []
Matthew Treinishf7fca6a2013-12-09 16:27:23 +0000106
Emily Hugenbruche7991d92014-12-12 16:53:36 +0000107 @classmethod
108 def resource_cleanup(cls):
109 cls.clear_images()
110 cls.clear_servers()
111 cls.clear_security_groups()
112 cls.clear_server_groups()
113 super(BaseComputeTest, cls).resource_cleanup()
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900114
Matthew Treinishf7fca6a2013-12-09 16:27:23 +0000115 @classmethod
Jay Pipes444c3e62012-10-04 19:26:35 -0400116 def clear_servers(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200117 LOG.debug('Clearing servers: %s', ','.join(
118 server['id'] for server in cls.servers))
Jay Pipes444c3e62012-10-04 19:26:35 -0400119 for server in cls.servers:
Dan Smith74e7bcb2012-08-21 09:18:26 -0700120 try:
121 cls.servers_client.delete_server(server['id'])
Masayuki Igawabfa07602015-01-20 18:47:17 +0900122 except lib_exc.NotFound:
Joe Gordon0c335792014-09-23 12:36:11 -0700123 # Something else already cleaned up the server, nothing to be
124 # worried about
Dan Smith74e7bcb2012-08-21 09:18:26 -0700125 pass
Joe Gordon0c335792014-09-23 12:36:11 -0700126 except Exception:
127 LOG.exception('Deleting server %s failed' % server['id'])
Dan Smith74e7bcb2012-08-21 09:18:26 -0700128
Jay Pipes444c3e62012-10-04 19:26:35 -0400129 for server in cls.servers:
Dan Smith74e7bcb2012-08-21 09:18:26 -0700130 try:
131 cls.servers_client.wait_for_server_termination(server['id'])
132 except Exception:
Joe Gordon0c335792014-09-23 12:36:11 -0700133 LOG.exception('Waiting for deletion of server %s failed'
134 % server['id'])
Dan Smith74e7bcb2012-08-21 09:18:26 -0700135
136 @classmethod
Attila Fazekas305e65b2013-10-29 13:23:07 +0100137 def server_check_teardown(cls):
138 """Checks is the shared server clean enough for subsequent test.
139 Method will delete the server when it's dirty.
140 The setUp method is responsible for creating a new server.
141 Exceptions raised in tearDown class are fails the test case,
142 This method supposed to use only by tierDown methods, when
143 the shared server_id is stored in the server_id of the class.
144 """
145 if getattr(cls, 'server_id', None) is not None:
146 try:
147 cls.servers_client.wait_for_server_status(cls.server_id,
148 'ACTIVE')
149 except Exception as exc:
150 LOG.exception(exc)
151 cls.servers_client.delete_server(cls.server_id)
152 cls.servers_client.wait_for_server_termination(cls.server_id)
153 cls.server_id = None
154 raise
155
156 @classmethod
Sean Dagued62bf1c2013-06-05 14:36:25 -0400157 def clear_images(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200158 LOG.debug('Clearing images: %s', ','.join(cls.images))
Sean Dagued62bf1c2013-06-05 14:36:25 -0400159 for image_id in cls.images:
160 try:
161 cls.images_client.delete_image(image_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900162 except lib_exc.NotFound:
David Kranz33138312013-09-24 17:09:32 -0400163 # The image may have already been deleted which is OK.
164 pass
Yair Frieda039f872014-01-02 12:11:10 +0200165 except Exception:
166 LOG.exception('Exception raised deleting image %s' % image_id)
Sean Dagued62bf1c2013-06-05 14:36:25 -0400167
168 @classmethod
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800169 def clear_security_groups(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200170 LOG.debug('Clearing security groups: %s', ','.join(
171 str(sg['id']) for sg in cls.security_groups))
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800172 for sg in cls.security_groups:
173 try:
David Kranz9964b4e2015-02-06 15:45:29 -0500174 cls.security_groups_client.delete_security_group(sg['id'])
Masayuki Igawabfa07602015-01-20 18:47:17 +0900175 except lib_exc.NotFound:
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800176 # The security group may have already been deleted which is OK.
177 pass
178 except Exception as exc:
179 LOG.info('Exception raised deleting security group %s',
180 sg['id'])
181 LOG.exception(exc)
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800182
183 @classmethod
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530184 def clear_server_groups(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200185 LOG.debug('Clearing server groups: %s', ','.join(cls.server_groups))
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530186 for server_group_id in cls.server_groups:
187 try:
Ken'ichi Ohmichi7ca54b82015-07-07 01:10:26 +0000188 cls.server_groups_client.delete_server_group(server_group_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900189 except lib_exc.NotFound:
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530190 # The server-group may have already been deleted which is OK.
191 pass
192 except Exception:
193 LOG.exception('Exception raised deleting server-group %s',
194 server_group_id)
195
196 @classmethod
Joseph Lanouxb3e1f872015-01-30 11:13:07 +0000197 def create_test_server(cls, validatable=False, **kwargs):
198 """Wrapper utility that returns a test server.
Rohit Karajgidc300b22012-05-04 08:11:00 -0700199
Joseph Lanouxb3e1f872015-01-30 11:13:07 +0000200 This wrapper utility calls the common create test server and
201 returns a test server. The purpose of this wrapper is to minimize
202 the impact on the code of the tests already using this
203 function.
204 """
205 tenant_network = cls.get_tenant_network()
206 body, servers = compute.create_test_server(
207 cls.os,
208 validatable,
209 validation_resources=cls.validation_resources,
210 tenant_network=tenant_network,
211 **kwargs)
Ken'ichi Ohmichi51c8c262013-12-21 03:30:37 +0900212
213 cls.servers.extend(servers)
Sean Dague9b669e32012-12-13 18:40:08 -0500214
David Kranz0fb14292015-02-11 15:55:20 -0500215 return body
Sean Dague9b669e32012-12-13 18:40:08 -0500216
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800217 @classmethod
218 def create_security_group(cls, name=None, description=None):
219 if name is None:
220 name = data_utils.rand_name(cls.__name__ + "-securitygroup")
221 if description is None:
Ken'ichi Ohmichi4937f562015-03-23 00:15:01 +0000222 description = data_utils.rand_name('description')
David Kranz9964b4e2015-02-06 15:45:29 -0500223 body = \
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800224 cls.security_groups_client.create_security_group(name,
225 description)
226 cls.security_groups.append(body)
227
David Kranz9964b4e2015-02-06 15:45:29 -0500228 return body
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800229
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530230 @classmethod
Ghanshyam2a180b82014-06-16 13:54:22 +0900231 def create_test_server_group(cls, name="", policy=None):
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530232 if not name:
233 name = data_utils.rand_name(cls.__name__ + "-Server-Group")
Ghanshyam2a180b82014-06-16 13:54:22 +0900234 if policy is None:
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530235 policy = ['affinity']
Ken'ichi Ohmichi7ca54b82015-07-07 01:10:26 +0000236 body = cls.server_groups_client.create_server_group(name, policy)
David Kranzda5d4ec2014-06-24 16:04:57 -0400237 cls.server_groups.append(body['id'])
David Kranzae99b9a2015-02-16 13:37:01 -0500238 return body
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530239
David Kranzcf0040c2012-06-26 09:46:56 -0400240 def wait_for(self, condition):
Sean Daguef237ccb2013-01-04 15:19:14 -0500241 """Repeatedly calls condition() until a timeout."""
David Kranzcf0040c2012-06-26 09:46:56 -0400242 start_time = int(time.time())
243 while True:
244 try:
245 condition()
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500246 except Exception:
David Kranzcf0040c2012-06-26 09:46:56 -0400247 pass
248 else:
249 return
250 if int(time.time()) - start_time >= self.build_timeout:
251 condition()
252 return
253 time.sleep(self.build_interval)
Jay Pipesf38eaac2012-06-21 13:37:35 -0400254
Matt Riedemann807d0562014-01-27 12:03:10 -0800255 @staticmethod
256 def _delete_volume(volumes_client, volume_id):
257 """Deletes the given volume and waits for it to be gone."""
258 try:
Joseph Lanoux6809bab2014-12-18 14:57:18 +0000259 volumes_client.delete_volume(volume_id)
Matt Riedemann807d0562014-01-27 12:03:10 -0800260 # TODO(mriedem): We should move the wait_for_resource_deletion
261 # into the delete_volume method as a convenience to the caller.
262 volumes_client.wait_for_resource_deletion(volume_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900263 except lib_exc.NotFound:
Matt Riedemann807d0562014-01-27 12:03:10 -0800264 LOG.warn("Unable to delete volume '%s' since it was not found. "
265 "Maybe it was already deleted?" % volume_id)
266
Attila Fazekas423834d2014-03-14 17:33:13 +0100267 @classmethod
268 def prepare_instance_network(cls):
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000269 if (CONF.validation.auth_method != 'disabled' and
270 CONF.validation.connect_method == 'floating'):
Attila Fazekas423834d2014-03-14 17:33:13 +0100271 cls.set_network_resources(network=True, subnet=True, router=True,
272 dhcp=True)
273
ivan-zhu8f992be2013-07-31 14:56:58 +0800274 @classmethod
275 def create_image_from_server(cls, server_id, **kwargs):
276 """Wrapper utility that returns an image created from the server."""
Masayuki Igawa259c1132013-10-31 17:48:44 +0900277 name = data_utils.rand_name(cls.__name__ + "-image")
ivan-zhu8f992be2013-07-31 14:56:58 +0800278 if 'name' in kwargs:
279 name = kwargs.pop('name')
280
David Kranza5299eb2015-01-15 17:24:05 -0500281 image = cls.images_client.create_image(server_id, name)
282 image_id = data_utils.parse_image_id(image.response['location'])
ivan-zhu8f992be2013-07-31 14:56:58 +0800283 cls.images.append(image_id)
284
285 if 'wait_until' in kwargs:
Ken'ichi Ohmichi8b9c7802015-07-08 05:57:37 +0000286 waiters.wait_for_image_status(cls.images_client,
287 image_id, kwargs['wait_until'])
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000288 image = cls.images_client.show_image(image_id)
ivan-zhu8f992be2013-07-31 14:56:58 +0800289
Bob Ball621e4602013-12-06 19:53:43 +0000290 if kwargs['wait_until'] == 'ACTIVE':
291 if kwargs.get('wait_for_server', True):
292 cls.servers_client.wait_for_server_status(server_id,
293 'ACTIVE')
David Kranza5299eb2015-01-15 17:24:05 -0500294 return image
ivan-zhu8f992be2013-07-31 14:56:58 +0800295
296 @classmethod
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000297 def rebuild_server(cls, server_id, validatable=False, **kwargs):
ivan-zhu8f992be2013-07-31 14:56:58 +0800298 # Destroy an existing server and creates a new one
Matthew Treinish2cd19a42013-12-02 21:54:42 +0000299 if server_id:
300 try:
301 cls.servers_client.delete_server(server_id)
302 cls.servers_client.wait_for_server_termination(server_id)
Yair Frieda039f872014-01-02 12:11:10 +0200303 except Exception:
304 LOG.exception('Failed to delete server %s' % server_id)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000305
306 server = cls.create_test_server(
307 validatable,
308 wait_until='ACTIVE',
309 **kwargs)
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000310 cls.password = server['adminPass']
Matthew Treinish2cd19a42013-12-02 21:54:42 +0000311 return server['id']
ivan-zhu8f992be2013-07-31 14:56:58 +0800312
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800313 @classmethod
Jesse Keating613b4982015-05-04 15:05:19 -0700314 def delete_server(cls, server_id):
315 """Deletes an existing server and waits for it to be gone."""
316 try:
317 cls.servers_client.delete_server(server_id)
318 cls.servers_client.wait_for_server_termination(server_id)
319 except Exception:
320 LOG.exception('Failed to delete server %s' % server_id)
321
322 @classmethod
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800323 def delete_volume(cls, volume_id):
324 """Deletes the given volume and waits for it to be gone."""
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000325 cls._delete_volume(cls.volumes_extensions_client, volume_id)
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900326
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000327 @classmethod
328 def get_server_ip(cls, server):
329 """Get the server fixed or floating IP.
330
331 For the floating IP, the address created by the validation resources
332 is returned.
333 For the fixed IP, the server is returned and the current mechanism of
334 address extraction in the remote_client is followed.
335 """
336 if CONF.validation.connect_method == 'floating':
337 ip_or_server = cls.validation_resources['floating_ip']['ip']
338 elif CONF.validation.connect_method == 'fixed':
339 ip_or_server = server
340 return ip_or_server
341
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900342
343class BaseV2ComputeTest(BaseComputeTest):
344 _api_version = 2
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800345
ivan-zhuf2b00502013-10-18 10:06:52 +0800346
Ken'ichi Ohmichibcefa3d2014-05-09 08:14:05 +0900347class BaseComputeAdminTest(BaseComputeTest):
348 """Base test case class for Compute Admin API tests."""
ivan-zhuf2b00502013-10-18 10:06:52 +0800349
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000350 credentials = ['primary', 'admin']
Emily Hugenbruche7991d92014-12-12 16:53:36 +0000351
352 @classmethod
353 def setup_clients(cls):
354 super(BaseComputeAdminTest, cls).setup_clients()
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000355 cls.availability_zone_admin_client = (
356 cls.os_adm.availability_zone_client)
ivan-zhu8f992be2013-07-31 14:56:58 +0800357
Ken'ichi Ohmichibcefa3d2014-05-09 08:14:05 +0900358
359class BaseV2ComputeAdminTest(BaseComputeAdminTest):
360 """Base test case class for Compute Admin V2 API tests."""
361 _api_version = 2