blob: b2effc2fd5e78fe9051fcab0d77a937d552b6add [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
Ken'ichi Ohmichi685cd172015-07-13 01:29:57 +000067 cls.security_group_rules_client = cls.os.security_group_rules_client
Emily Hugenbruche7991d92014-12-12 16:53:36 +000068 cls.security_groups_client = cls.os.security_groups_client
69 cls.quotas_client = cls.os.quotas_client
70 # NOTE(mriedem): os-quota-class-sets is v2 API only
71 cls.quota_classes_client = cls.os.quota_classes_client
72 # NOTE(mriedem): os-networks is v2 API only
73 cls.networks_client = cls.os.networks_client
74 cls.limits_client = cls.os.limits_client
75 cls.volumes_extensions_client = cls.os.volumes_extensions_client
76 cls.volumes_client = cls.os.volumes_client
77 cls.interfaces_client = cls.os.interfaces_client
78 cls.fixed_ips_client = cls.os.fixed_ips_client
79 cls.availability_zone_client = cls.os.availability_zone_client
80 cls.agents_client = cls.os.agents_client
81 cls.aggregates_client = cls.os.aggregates_client
82 cls.services_client = cls.os.services_client
83 cls.instance_usages_audit_log_client = (
84 cls.os.instance_usages_audit_log_client)
85 cls.hypervisor_client = cls.os.hypervisor_client
86 cls.certificates_client = cls.os.certificates_client
87 cls.migrations_client = cls.os.migrations_client
88 cls.security_group_default_rules_client = (
89 cls.os.security_group_default_rules_client)
90
91 @classmethod
92 def resource_setup(cls):
93 super(BaseComputeTest, cls).resource_setup()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000094 cls.build_interval = CONF.compute.build_interval
95 cls.build_timeout = CONF.compute.build_timeout
96 cls.ssh_user = CONF.compute.ssh_user
97 cls.image_ref = CONF.compute.image_ref
98 cls.image_ref_alt = CONF.compute.image_ref_alt
99 cls.flavor_ref = CONF.compute.flavor_ref
100 cls.flavor_ref_alt = CONF.compute.flavor_ref_alt
101 cls.image_ssh_user = CONF.compute.image_ssh_user
102 cls.image_ssh_password = CONF.compute.image_ssh_password
Jay Pipesf38eaac2012-06-21 13:37:35 -0400103 cls.servers = []
Sean Dagued62bf1c2013-06-05 14:36:25 -0400104 cls.images = []
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800105 cls.security_groups = []
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530106 cls.server_groups = []
Matthew Treinishf7fca6a2013-12-09 16:27:23 +0000107
Emily Hugenbruche7991d92014-12-12 16:53:36 +0000108 @classmethod
109 def resource_cleanup(cls):
110 cls.clear_images()
111 cls.clear_servers()
112 cls.clear_security_groups()
113 cls.clear_server_groups()
114 super(BaseComputeTest, cls).resource_cleanup()
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900115
Matthew Treinishf7fca6a2013-12-09 16:27:23 +0000116 @classmethod
Jay Pipes444c3e62012-10-04 19:26:35 -0400117 def clear_servers(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200118 LOG.debug('Clearing servers: %s', ','.join(
119 server['id'] for server in cls.servers))
Jay Pipes444c3e62012-10-04 19:26:35 -0400120 for server in cls.servers:
Dan Smith74e7bcb2012-08-21 09:18:26 -0700121 try:
122 cls.servers_client.delete_server(server['id'])
Masayuki Igawabfa07602015-01-20 18:47:17 +0900123 except lib_exc.NotFound:
Joe Gordon0c335792014-09-23 12:36:11 -0700124 # Something else already cleaned up the server, nothing to be
125 # worried about
Dan Smith74e7bcb2012-08-21 09:18:26 -0700126 pass
Joe Gordon0c335792014-09-23 12:36:11 -0700127 except Exception:
128 LOG.exception('Deleting server %s failed' % server['id'])
Dan Smith74e7bcb2012-08-21 09:18:26 -0700129
Jay Pipes444c3e62012-10-04 19:26:35 -0400130 for server in cls.servers:
Dan Smith74e7bcb2012-08-21 09:18:26 -0700131 try:
132 cls.servers_client.wait_for_server_termination(server['id'])
133 except Exception:
Joe Gordon0c335792014-09-23 12:36:11 -0700134 LOG.exception('Waiting for deletion of server %s failed'
135 % server['id'])
Dan Smith74e7bcb2012-08-21 09:18:26 -0700136
137 @classmethod
Attila Fazekas305e65b2013-10-29 13:23:07 +0100138 def server_check_teardown(cls):
139 """Checks is the shared server clean enough for subsequent test.
140 Method will delete the server when it's dirty.
141 The setUp method is responsible for creating a new server.
142 Exceptions raised in tearDown class are fails the test case,
143 This method supposed to use only by tierDown methods, when
144 the shared server_id is stored in the server_id of the class.
145 """
146 if getattr(cls, 'server_id', None) is not None:
147 try:
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000148 waiters.wait_for_server_status(cls.servers_client,
149 cls.server_id, 'ACTIVE')
Attila Fazekas305e65b2013-10-29 13:23:07 +0100150 except Exception as exc:
151 LOG.exception(exc)
152 cls.servers_client.delete_server(cls.server_id)
153 cls.servers_client.wait_for_server_termination(cls.server_id)
154 cls.server_id = None
155 raise
156
157 @classmethod
Sean Dagued62bf1c2013-06-05 14:36:25 -0400158 def clear_images(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200159 LOG.debug('Clearing images: %s', ','.join(cls.images))
Sean Dagued62bf1c2013-06-05 14:36:25 -0400160 for image_id in cls.images:
161 try:
162 cls.images_client.delete_image(image_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900163 except lib_exc.NotFound:
David Kranz33138312013-09-24 17:09:32 -0400164 # The image may have already been deleted which is OK.
165 pass
Yair Frieda039f872014-01-02 12:11:10 +0200166 except Exception:
167 LOG.exception('Exception raised deleting image %s' % image_id)
Sean Dagued62bf1c2013-06-05 14:36:25 -0400168
169 @classmethod
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800170 def clear_security_groups(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200171 LOG.debug('Clearing security groups: %s', ','.join(
172 str(sg['id']) for sg in cls.security_groups))
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800173 for sg in cls.security_groups:
174 try:
David Kranz9964b4e2015-02-06 15:45:29 -0500175 cls.security_groups_client.delete_security_group(sg['id'])
Masayuki Igawabfa07602015-01-20 18:47:17 +0900176 except lib_exc.NotFound:
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800177 # The security group may have already been deleted which is OK.
178 pass
179 except Exception as exc:
180 LOG.info('Exception raised deleting security group %s',
181 sg['id'])
182 LOG.exception(exc)
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800183
184 @classmethod
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530185 def clear_server_groups(cls):
Salvatore1422a9a2014-10-08 15:53:25 +0200186 LOG.debug('Clearing server groups: %s', ','.join(cls.server_groups))
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530187 for server_group_id in cls.server_groups:
188 try:
Ken'ichi Ohmichi7ca54b82015-07-07 01:10:26 +0000189 cls.server_groups_client.delete_server_group(server_group_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900190 except lib_exc.NotFound:
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530191 # The server-group may have already been deleted which is OK.
192 pass
193 except Exception:
194 LOG.exception('Exception raised deleting server-group %s',
195 server_group_id)
196
197 @classmethod
Joseph Lanouxb3e1f872015-01-30 11:13:07 +0000198 def create_test_server(cls, validatable=False, **kwargs):
199 """Wrapper utility that returns a test server.
Rohit Karajgidc300b22012-05-04 08:11:00 -0700200
Joseph Lanouxb3e1f872015-01-30 11:13:07 +0000201 This wrapper utility calls the common create test server and
202 returns a test server. The purpose of this wrapper is to minimize
203 the impact on the code of the tests already using this
204 function.
205 """
206 tenant_network = cls.get_tenant_network()
207 body, servers = compute.create_test_server(
208 cls.os,
209 validatable,
210 validation_resources=cls.validation_resources,
211 tenant_network=tenant_network,
212 **kwargs)
Ken'ichi Ohmichi51c8c262013-12-21 03:30:37 +0900213
214 cls.servers.extend(servers)
Sean Dague9b669e32012-12-13 18:40:08 -0500215
David Kranz0fb14292015-02-11 15:55:20 -0500216 return body
Sean Dague9b669e32012-12-13 18:40:08 -0500217
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800218 @classmethod
219 def create_security_group(cls, name=None, description=None):
220 if name is None:
221 name = data_utils.rand_name(cls.__name__ + "-securitygroup")
222 if description is None:
Ken'ichi Ohmichi4937f562015-03-23 00:15:01 +0000223 description = data_utils.rand_name('description')
David Kranz9964b4e2015-02-06 15:45:29 -0500224 body = \
Ken'ichi Ohmichi34563cc2015-07-21 00:53:17 +0000225 cls.security_groups_client.create_security_group(
226 name=name, description=description)
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800227 cls.security_groups.append(body)
228
David Kranz9964b4e2015-02-06 15:45:29 -0500229 return body
Zhi Kun Liu02e7a7b2014-01-08 16:08:32 +0800230
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530231 @classmethod
Ghanshyam2a180b82014-06-16 13:54:22 +0900232 def create_test_server_group(cls, name="", policy=None):
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530233 if not name:
234 name = data_utils.rand_name(cls.__name__ + "-Server-Group")
Ghanshyam2a180b82014-06-16 13:54:22 +0900235 if policy is None:
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530236 policy = ['affinity']
Ken'ichi Ohmichi7ca54b82015-07-07 01:10:26 +0000237 body = cls.server_groups_client.create_server_group(name, policy)
David Kranzda5d4ec2014-06-24 16:04:57 -0400238 cls.server_groups.append(body['id'])
David Kranzae99b9a2015-02-16 13:37:01 -0500239 return body
Abhijeet.Jain87dd4452014-04-23 15:51:23 +0530240
David Kranzcf0040c2012-06-26 09:46:56 -0400241 def wait_for(self, condition):
Sean Daguef237ccb2013-01-04 15:19:14 -0500242 """Repeatedly calls condition() until a timeout."""
David Kranzcf0040c2012-06-26 09:46:56 -0400243 start_time = int(time.time())
244 while True:
245 try:
246 condition()
Matthew Treinish05d9fb92012-12-07 16:14:05 -0500247 except Exception:
David Kranzcf0040c2012-06-26 09:46:56 -0400248 pass
249 else:
250 return
251 if int(time.time()) - start_time >= self.build_timeout:
252 condition()
253 return
254 time.sleep(self.build_interval)
Jay Pipesf38eaac2012-06-21 13:37:35 -0400255
Matt Riedemann807d0562014-01-27 12:03:10 -0800256 @staticmethod
257 def _delete_volume(volumes_client, volume_id):
258 """Deletes the given volume and waits for it to be gone."""
259 try:
Joseph Lanoux6809bab2014-12-18 14:57:18 +0000260 volumes_client.delete_volume(volume_id)
Matt Riedemann807d0562014-01-27 12:03:10 -0800261 # TODO(mriedem): We should move the wait_for_resource_deletion
262 # into the delete_volume method as a convenience to the caller.
263 volumes_client.wait_for_resource_deletion(volume_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900264 except lib_exc.NotFound:
Matt Riedemann807d0562014-01-27 12:03:10 -0800265 LOG.warn("Unable to delete volume '%s' since it was not found. "
266 "Maybe it was already deleted?" % volume_id)
267
Attila Fazekas423834d2014-03-14 17:33:13 +0100268 @classmethod
269 def prepare_instance_network(cls):
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000270 if (CONF.validation.auth_method != 'disabled' and
271 CONF.validation.connect_method == 'floating'):
Attila Fazekas423834d2014-03-14 17:33:13 +0100272 cls.set_network_resources(network=True, subnet=True, router=True,
273 dhcp=True)
274
ivan-zhu8f992be2013-07-31 14:56:58 +0800275 @classmethod
276 def create_image_from_server(cls, server_id, **kwargs):
277 """Wrapper utility that returns an image created from the server."""
Masayuki Igawa259c1132013-10-31 17:48:44 +0900278 name = data_utils.rand_name(cls.__name__ + "-image")
ivan-zhu8f992be2013-07-31 14:56:58 +0800279 if 'name' in kwargs:
280 name = kwargs.pop('name')
281
Ken'ichi Ohmichi28f18672015-07-17 10:00:38 +0000282 image = cls.images_client.create_image(server_id, name=name)
David Kranza5299eb2015-01-15 17:24:05 -0500283 image_id = data_utils.parse_image_id(image.response['location'])
ivan-zhu8f992be2013-07-31 14:56:58 +0800284 cls.images.append(image_id)
285
286 if 'wait_until' in kwargs:
Ken'ichi Ohmichi8b9c7802015-07-08 05:57:37 +0000287 waiters.wait_for_image_status(cls.images_client,
288 image_id, kwargs['wait_until'])
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000289 image = cls.images_client.show_image(image_id)
ivan-zhu8f992be2013-07-31 14:56:58 +0800290
Bob Ball621e4602013-12-06 19:53:43 +0000291 if kwargs['wait_until'] == 'ACTIVE':
292 if kwargs.get('wait_for_server', True):
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000293 waiters.wait_for_server_status(cls.servers_client,
294 server_id, 'ACTIVE')
David Kranza5299eb2015-01-15 17:24:05 -0500295 return image
ivan-zhu8f992be2013-07-31 14:56:58 +0800296
297 @classmethod
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000298 def rebuild_server(cls, server_id, validatable=False, **kwargs):
ivan-zhu8f992be2013-07-31 14:56:58 +0800299 # Destroy an existing server and creates a new one
Matthew Treinish2cd19a42013-12-02 21:54:42 +0000300 if server_id:
301 try:
302 cls.servers_client.delete_server(server_id)
303 cls.servers_client.wait_for_server_termination(server_id)
Yair Frieda039f872014-01-02 12:11:10 +0200304 except Exception:
305 LOG.exception('Failed to delete server %s' % server_id)
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000306
307 server = cls.create_test_server(
308 validatable,
309 wait_until='ACTIVE',
310 **kwargs)
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000311 cls.password = server['adminPass']
Matthew Treinish2cd19a42013-12-02 21:54:42 +0000312 return server['id']
ivan-zhu8f992be2013-07-31 14:56:58 +0800313
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800314 @classmethod
Jesse Keating613b4982015-05-04 15:05:19 -0700315 def delete_server(cls, server_id):
316 """Deletes an existing server and waits for it to be gone."""
317 try:
318 cls.servers_client.delete_server(server_id)
319 cls.servers_client.wait_for_server_termination(server_id)
320 except Exception:
321 LOG.exception('Failed to delete server %s' % server_id)
322
323 @classmethod
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800324 def delete_volume(cls, volume_id):
325 """Deletes the given volume and waits for it to be gone."""
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000326 cls._delete_volume(cls.volumes_extensions_client, volume_id)
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900327
Joseph Lanouxffe09dd2015-03-18 16:45:33 +0000328 @classmethod
329 def get_server_ip(cls, server):
330 """Get the server fixed or floating IP.
331
332 For the floating IP, the address created by the validation resources
333 is returned.
334 For the fixed IP, the server is returned and the current mechanism of
335 address extraction in the remote_client is followed.
336 """
337 if CONF.validation.connect_method == 'floating':
338 ip_or_server = cls.validation_resources['floating_ip']['ip']
339 elif CONF.validation.connect_method == 'fixed':
340 ip_or_server = server
341 return ip_or_server
342
Ken'ichi Ohmichi543a5d42014-05-02 08:44:15 +0900343
344class BaseV2ComputeTest(BaseComputeTest):
345 _api_version = 2
Matt Riedemann5dc594c2014-01-27 11:40:28 -0800346
ivan-zhuf2b00502013-10-18 10:06:52 +0800347
Ken'ichi Ohmichibcefa3d2014-05-09 08:14:05 +0900348class BaseComputeAdminTest(BaseComputeTest):
349 """Base test case class for Compute Admin API tests."""
ivan-zhuf2b00502013-10-18 10:06:52 +0800350
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000351 credentials = ['primary', 'admin']
Emily Hugenbruche7991d92014-12-12 16:53:36 +0000352
353 @classmethod
354 def setup_clients(cls):
355 super(BaseComputeAdminTest, cls).setup_clients()
Ken'ichi Ohmichi9f5adf82014-12-12 04:01:32 +0000356 cls.availability_zone_admin_client = (
357 cls.os_adm.availability_zone_client)
ivan-zhu8f992be2013-07-31 14:56:58 +0800358
Ken'ichi Ohmichibcefa3d2014-05-09 08:14:05 +0900359
360class BaseV2ComputeAdminTest(BaseComputeAdminTest):
361 """Base test case class for Compute Admin V2 API tests."""
362 _api_version = 2