blob: 9da85d5fc43aaac82bc9f595f1f7bbb7d9eb60db [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipes051075a2012-04-28 17:39:37 -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
Attila Fazekasf86fa312013-07-30 19:56:39 +020016import atexit
Ian Wienand98c35f32013-07-23 20:34:23 +100017import os
Attila Fazekas53943322014-02-10 16:07:34 +010018import sys
Jay Pipes051075a2012-04-28 17:39:37 -040019
Jordan Pittier35a63752016-08-30 13:09:12 +020020import debtcollector.moves
Matthew Treinish78561ad2013-07-26 11:41:56 -040021import fixtures
Doug Hellmann583ce2c2015-03-11 14:55:46 +000022from oslo_log import log as logging
Chris Hoge296558c2015-02-19 00:29:49 -060023import six
ivan-zhu1feeb382013-01-24 10:14:39 +080024import testtools
Jay Pipes051075a2012-04-28 17:39:37 -040025
Matthew Treinish3e046852013-07-23 16:00:24 -040026from tempest import clients
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010027from tempest.common import credentials_factory as credentials
Andrea Frittolicd368412017-08-14 21:37:56 +010028from tempest.common import utils
Attila Fazekasdc216422013-01-29 15:12:14 +010029from tempest import config
Matthew Treinishb19c55d2017-07-17 12:38:35 -040030from tempest.lib.common import fixed_network
Andrea Frittoli0477acc2017-08-09 21:14:53 +010031from tempest.lib.common import validation_resources as vr
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050032from tempest.lib import decorators
Andrea Frittoli (andreaf)af4f7cf2016-06-13 15:12:26 +010033from tempest.lib import exceptions as lib_exc
Jay Pipes051075a2012-04-28 17:39:37 -040034
35LOG = logging.getLogger(__name__)
36
Sean Dague86bd8422013-12-20 09:56:44 -050037CONF = config.CONF
38
Ken'ichi Ohmichi44f01272017-01-27 18:44:14 -080039# TODO(oomichi): This test.idempotent_id should be removed after all projects
40# switch to use decorators.idempotent_id.
41idempotent_id = debtcollector.moves.moved_function(
42 decorators.idempotent_id, 'idempotent_id', __name__,
43 version='Mitaka', removal_version='?')
Matthew Treinishc1802bc2015-12-03 18:48:11 -050044
Jay Pipes051075a2012-04-28 17:39:37 -040045
Jordan Pittier3b46d272017-04-12 16:17:28 +020046attr = debtcollector.moves.moved_function(
47 decorators.attr, 'attr', __name__,
48 version='Pike', removal_version='?')
Chris Yeoh55530bb2013-02-08 16:04:27 +103049
50
Andrea Frittolicd368412017-08-14 21:37:56 +010051services = debtcollector.moves.moved_function(
52 utils.services, 'services', __name__,
53 version='Pike', removal_version='?')
Andrea Frittoli07acf262017-04-09 19:36:37 +020054
55
Andrea Frittolicd368412017-08-14 21:37:56 +010056requires_ext = debtcollector.moves.moved_function(
57 utils.requires_ext, 'requires_ext', __name__,
58 version='Pike', removal_version='?')
Matthew Treinish16c43792013-09-09 19:55:23 +000059
Matthew Treinish3d8c7322014-08-03 23:53:28 -040060
Andrea Frittolicd368412017-08-14 21:37:56 +010061is_extension_enabled = debtcollector.moves.moved_function(
62 utils.is_extension_enabled, 'is_extension_enabled', __name__,
63 version='Pike', removal_version='?')
Ian Wienand98c35f32013-07-23 20:34:23 +100064
Attila Fazekasf86fa312013-07-30 19:56:39 +020065at_exit_set = set()
66
67
68def validate_tearDownClass():
69 if at_exit_set:
Sean Dagueeb1523b2014-03-10 10:17:44 -040070 LOG.error(
71 "tearDownClass does not call the super's "
72 "tearDownClass in these classes: \n"
73 + str(at_exit_set))
74
Attila Fazekasf86fa312013-07-30 19:56:39 +020075
76atexit.register(validate_tearDownClass)
77
Attila Fazekas53943322014-02-10 16:07:34 +010078
Matthew Treinish2474f412014-11-17 18:11:56 -050079class BaseTestCase(testtools.testcase.WithAttributes,
80 testtools.TestCase):
Andrea Frittolia5ddd552014-08-19 18:30:00 +010081 """The test base class defines Tempest framework for class level fixtures.
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +000082
Andrea Frittolia5ddd552014-08-19 18:30:00 +010083 `setUpClass` and `tearDownClass` are defined here and cannot be overwritten
84 by subclasses (enforced via hacking rule T105).
85
86 Set-up is split in a series of steps (setup stages), which can be
87 overwritten by test classes. Set-up stages are:
88 - skip_checks
89 - setup_credentials
90 - setup_clients
91 - resource_setup
92
93 Tear-down is also split in a series of steps (teardown stages), which are
94 stacked for execution only if the corresponding setup stage had been
95 reached during the setup phase. Tear-down stages are:
Andrea Frittoli (andreaf)17209bb2015-05-22 10:16:57 -070096 - clear_credentials (defined in the base test class)
Andrea Frittolia5ddd552014-08-19 18:30:00 +010097 - resource_cleanup
98 """
Attila Fazekasc43fec82013-04-09 23:17:52 +020099
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000100 # NOTE(andreaf) credentials holds a list of the credentials to be allocated
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100101 # at class setup time. Credential types can be 'primary', 'alt', 'admin' or
102 # a list of roles - the first element of the list being a label, and the
103 # rest the actual roles
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000104 credentials = []
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100105
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600106 # Track if setUpClass was invoked
107 __setupclass_called = False
108
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100109 # Network resources to be provisioned for the requested test credentials.
110 # Only used with the dynamic credentials provider.
111 _network_resources = {}
Matthew Treinish9f756a02014-01-15 10:26:07 -0500112
Andrea Frittoli3be57482017-08-25 22:41:26 +0100113 # Stack of resource cleanups
114 _class_cleanups = []
115
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100116 # Resources required to validate a server using ssh
117 _validation_resources = {}
118
Sean Dague2ef32ac2014-06-09 11:32:23 -0400119 # NOTE(sdague): log_format is defined inline here instead of using the oslo
120 # default because going through the config path recouples config to the
121 # stress tests too early, and depending on testr order will fail unit tests
122 log_format = ('%(asctime)s %(process)d %(levelname)-8s '
123 '[%(name)s] %(message)s')
124
Ryota MIBU60687e52015-12-09 18:37:39 +0900125 # Client manager class to use in this test case.
126 client_manager = clients.Manager
127
Sean Dague02620fd2016-03-02 15:52:51 -0500128 # A way to adjust slow test classes
129 TIMEOUT_SCALING_FACTOR = 1
130
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200131 @classmethod
Andrea Frittoli3be57482017-08-25 22:41:26 +0100132 def _reset_class(cls):
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100133 cls.__setup_credentials_called = False
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100134 cls.__resource_cleanup_called = False
Andrea Frittoli421dc3c2017-08-15 12:17:42 +0100135 cls.__skip_checks_called = False
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600136 # Stack of callable to be invoked in reverse order
Andrea Frittoli3be57482017-08-25 22:41:26 +0100137 cls._class_cleanups = []
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600138 # Stack of (name, callable) to be invoked in reverse order at teardown
139 cls._teardowns = []
Andrea Frittoli3be57482017-08-25 22:41:26 +0100140
141 @classmethod
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200142 def setUpClass(cls):
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600143 cls.__setupclass_called = True
Andrea Frittoli3be57482017-08-25 22:41:26 +0100144 # Reset state
145 cls._reset_class()
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100146 # It should never be overridden by descendants
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200147 if hasattr(super(BaseTestCase, cls), 'setUpClass'):
148 super(BaseTestCase, cls).setUpClass()
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100149 # All the configuration checks that may generate a skip
150 cls.skip_checks()
Andrea Frittoli421dc3c2017-08-15 12:17:42 +0100151 if not cls.__skip_checks_called:
152 raise RuntimeError("skip_checks for %s did not call the super's "
153 "skip_checks" % cls.__name__)
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100154 try:
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100155 # Allocation of all required credentials and client managers
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100156 cls._teardowns.append(('credentials', cls.clear_credentials))
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100157 cls.setup_credentials()
Andrea Frittoli421dc3c2017-08-15 12:17:42 +0100158 if not cls.__setup_credentials_called:
159 raise RuntimeError("setup_credentials for %s did not call the "
160 "super's setup_credentials" % cls.__name__)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100161 # Shortcuts to clients
162 cls.setup_clients()
163 # Additional class-wide test resources
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100164 cls._teardowns.append(('resources', cls.resource_cleanup))
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100165 cls.resource_setup()
166 except Exception:
167 etype, value, trace = sys.exc_info()
Jordan Pittier525ec712016-12-07 17:51:26 +0100168 LOG.info("%s raised in %s.setUpClass. Invoking tearDownClass.",
169 etype, cls.__name__)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100170 cls.tearDownClass()
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100171 try:
Matthew Treinish843227d2015-04-23 10:17:17 -0400172 six.reraise(etype, value, trace)
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100173 finally:
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100174 del trace # to avoid circular refs
Pavel Sedlák1053bd32013-04-16 16:47:40 +0200175
Attila Fazekasf86fa312013-07-30 19:56:39 +0200176 @classmethod
177 def tearDownClass(cls):
Martin Kopecae155b72017-06-26 09:41:21 +0000178 # insert pdb breakpoint when pause_teardown is enabled
179 if CONF.pause_teardown:
180 cls.insert_pdb_breakpoint()
Attila Fazekas5d275302013-08-29 12:35:12 +0200181 at_exit_set.discard(cls)
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100182 # It should never be overridden by descendants
Attila Fazekasf86fa312013-07-30 19:56:39 +0200183 if hasattr(super(BaseTestCase, cls), 'tearDownClass'):
184 super(BaseTestCase, cls).tearDownClass()
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100185 # Save any existing exception, we always want to re-raise the original
186 # exception only
187 etype, value, trace = sys.exc_info()
188 # If there was no exception during setup we shall re-raise the first
189 # exception in teardown
190 re_raise = (etype is None)
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100191 while cls._teardowns:
192 name, teardown = cls._teardowns.pop()
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100193 # Catch any exception in tearDown so we can re-raise the original
194 # exception at the end
195 try:
196 teardown()
Andrea Frittoli3be57482017-08-25 22:41:26 +0100197 if name == 'resources':
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100198 if not cls.__resource_cleanup_called:
Andrea Frittoli3be57482017-08-25 22:41:26 +0100199 raise RuntimeError(
200 "resource_cleanup for %s did not call the "
201 "super's resource_cleanup" % cls.__name__)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100202 except Exception as te:
203 sys_exec_info = sys.exc_info()
204 tetype = sys_exec_info[0]
Andrea Frittoli3be57482017-08-25 22:41:26 +0100205 # TODO(andreaf): Resource cleanup is often implemented by
206 # storing an array of resources at class level, and cleaning
207 # them up during `resource_cleanup`.
208 # In case of failure during setup, some resource arrays might
209 # not be defined at all, in which case the cleanup code might
210 # trigger an AttributeError. In such cases we log
211 # AttributeError as info instead of exception. Once all
212 # cleanups are migrated to addClassResourceCleanup we can
213 # remove this.
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100214 if tetype is AttributeError and name == 'resources':
Jordan Pittier525ec712016-12-07 17:51:26 +0100215 LOG.info("tearDownClass of %s failed: %s", name, te)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100216 else:
Jordan Pittier525ec712016-12-07 17:51:26 +0100217 LOG.exception("teardown of %s failed: %s", name, te)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100218 if not etype:
219 etype, value, trace = sys_exec_info
Joshua Whitebd769602016-02-02 09:30:11 -0800220 # If exceptions were raised during teardown, and not before, re-raise
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100221 # the first one
222 if re_raise and etype is not None:
223 try:
Matthew Treinish843227d2015-04-23 10:17:17 -0400224 six.reraise(etype, value, trace)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100225 finally:
226 del trace # to avoid circular refs
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100227
Martin Kopecae155b72017-06-26 09:41:21 +0000228 def tearDown(self):
229 super(BaseTestCase, self).tearDown()
230 # insert pdb breakpoint when pause_teardown is enabled
231 if CONF.pause_teardown:
232 BaseTestCase.insert_pdb_breakpoint()
233
234 @classmethod
235 def insert_pdb_breakpoint(cls):
236 """Add pdb breakpoint.
237
238 This can help in debugging process, cleaning of resources is
239 paused, so they can be examined.
240 """
241 import pdb
242 pdb.set_trace()
243
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100244 @classmethod
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100245 def skip_checks(cls):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000246 """Class level skip checks.
247
248 Subclasses verify in here all conditions that might prevent the
Andrea Frittolia5440c82017-08-23 18:11:21 +0100249 execution of the entire test class. Skipping here prevents any other
250 class fixture from being executed i.e. no credentials or other
251 resource allocation will happen.
252
253 Tests defined in the test class will no longer appear in test results.
254 The `setUpClass` for the entire test class will be marked as SKIPPED
255 instead.
256
257 At this stage no test credentials are available, so skip checks
258 should rely on configuration alone. This is deliberate since skips
259 based on the result of an API call are discouraged.
260
261 The following checks are implemented in `test.py` already:
262 - check that alt credentials are available when requested by the test
263 - check that admin credentials are available when requested by the test
264 - check that the identity version specified by the test is marked as
265 enabled in the configuration
266
267 Overriders of skip_checks must always invoke skip_check on `super`
268 first.
269
270 Example::
271
272 @classmethod
273 def skip_checks(cls):
274 super(Example, cls).skip_checks()
275 if not CONF.service_available.my_service:
276 skip_msg = ("%s skipped as my_service is not available")
277 raise cls.skipException(skip_msg % cls.__name__)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100278 """
Andrea Frittoli421dc3c2017-08-15 12:17:42 +0100279 cls.__skip_checks_called = True
Andrea Frittoli (andreaf)32d0de12015-10-09 14:43:53 +0100280 identity_version = cls.get_identity_version()
zhufl75498ba2017-08-25 10:49:35 +0800281 # setting force_tenant_isolation to True also needs admin credentials.
282 if ('admin' in cls.credentials or
283 getattr(cls, 'force_tenant_isolation', False)):
284 if not credentials.is_admin_available(
285 identity_version=identity_version):
286 raise cls.skipException(
287 "Missing Identity Admin API credentials in configuration.")
Andrea Frittoli (andreaf)32d0de12015-10-09 14:43:53 +0100288 if 'alt' in cls.credentials and not credentials.is_alt_available(
289 identity_version=identity_version):
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000290 msg = "Missing a 2nd set of API credentials in configuration."
291 raise cls.skipException(msg)
Andrea Frittoli (andreaf)41601412015-05-12 16:39:03 +0100292 if hasattr(cls, 'identity_version'):
293 if cls.identity_version == 'v2':
294 if not CONF.identity_feature_enabled.api_v2:
295 raise cls.skipException("Identity api v2 is not enabled")
296 elif cls.identity_version == 'v3':
297 if not CONF.identity_feature_enabled.api_v3:
298 raise cls.skipException("Identity api v3 is not enabled")
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100299
300 @classmethod
301 def setup_credentials(cls):
edannon6cc6fbc2016-05-03 11:56:12 +0300302 """Allocate credentials and create the client managers from them.
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000303
Andrea Frittolia6c885a2017-08-23 19:37:50 +0100304 `setup_credentials` looks for the content of the `credentials`
305 attribute in the test class. If the value is a non-empty collection,
306 a credentials provider is setup, and credentials are provisioned or
307 allocated based on the content of the collection. Every set of
308 credentials is associated to an object of type `cls.client_manager`.
309 The client manager is accessible by tests via class attribute
310 `os_[type]`:
edannon6cc6fbc2016-05-03 11:56:12 +0300311
Andrea Frittolia6c885a2017-08-23 19:37:50 +0100312 Valid values in `credentials` are:
313 - 'primary':
314 A normal user is provisioned.
315 It can be used only once. Multiple entries will be ignored.
316 Clients are available at os_primary.
317 - 'alt':
318 A normal user other than 'primary' is provisioned.
319 It can be used only once. Multiple entries will be ignored.
320 Clients are available at os_alt.
321 - 'admin':
322 An admin user is provisioned.
323 It can be used only once. Multiple entries will be ignored.
324 Clients are available at os_admin.
325 - A list in the format ['any_label', 'role1', ... , 'roleN']:
326 A client with roles <list>[1:] is provisioned.
327 It can be used multiple times, with unique labels.
328 Clients are available at os_roles_<list>[0].
329
330 By default network resources are allocated (in case of dynamic
331 credentials). Tests that do not need network or that require a
332 custom network setup must specify which network resources shall
333 be provisioned using the `set_network_resources()` method (note
334 that it must be invoked before the `setup_credentials` is
335 invoked on super).
336
337 Example::
338
339 class TestWithCredentials(test.BaseTestCase):
340
341 credentials = ['primary', 'admin',
342 ['special', 'special_role1']]
343
344 @classmethod
345 def setup_credentials(cls):
346 # set_network_resources must be called first
347 cls.set_network_resources(network=True)
348 super(TestWithCredentials, cls).setup_credentials()
349
350 @classmethod
351 def setup_clients(cls):
352 cls.servers = cls.os_primary.compute.ServersClient()
353 cls.admin_servers = cls.os_admin.compute.ServersClient()
354 # certain API calls may require a user with a specific
355 # role assigned. In this example `special_role1` is
356 # assigned to the user in `cls.os_roles_special`.
357 cls.special_servers = (
358 cls.os_roles_special.compute.ServersClient())
359
360 def test_special_servers(self):
361 # Do something with servers
362 pass
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000363 """
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100364 cls.__setup_credentials_called = True
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000365 for credentials_type in cls.credentials:
366 # This may raise an exception in case credentials are not available
367 # In that case we want to let the exception through and the test
368 # fail accordingly
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100369 if isinstance(credentials_type, six.string_types):
370 manager = cls.get_client_manager(
371 credential_type=credentials_type)
372 setattr(cls, 'os_%s' % credentials_type, manager)
Jordan Pittier8160d312017-04-18 11:52:23 +0200373 # NOTE(jordanP): Tempest should use os_primary, os_admin
374 # and os_alt throughout its code base but we keep the aliases
375 # around for a while for Tempest plugins. Aliases should be
376 # removed eventually.
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100377 # Setup some common aliases
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100378 if credentials_type == 'primary':
Jordan Pittier8160d312017-04-18 11:52:23 +0200379 cls.os = debtcollector.moves.moved_read_only_property(
380 'os', 'os_primary', version='Pike',
Jakub Libosvar7835ca12017-05-04 16:44:23 +0200381 removal_version='Queens')
Jordan Pittier8160d312017-04-18 11:52:23 +0200382 cls.manager =\
383 debtcollector.moves.moved_read_only_property(
384 'manager', 'os_primary', version='Pike',
Jakub Libosvar7835ca12017-05-04 16:44:23 +0200385 removal_version='Queens')
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100386 if credentials_type == 'admin':
Jordan Pittier8160d312017-04-18 11:52:23 +0200387 cls.os_adm = debtcollector.moves.moved_read_only_property(
388 'os_adm', 'os_admin', version='Pike',
Jakub Libosvar7835ca12017-05-04 16:44:23 +0200389 removal_version='Queens')
Jordan Pittier8160d312017-04-18 11:52:23 +0200390 cls.admin_manager =\
391 debtcollector.moves.moved_read_only_property(
392 'admin_manager', 'os_admin', version='Pike',
Jakub Libosvar7835ca12017-05-04 16:44:23 +0200393 removal_version='Queens')
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100394 if credentials_type == 'alt':
Jordan Pittier8160d312017-04-18 11:52:23 +0200395 cls.alt_manager =\
396 debtcollector.moves.moved_read_only_property(
397 'alt_manager', 'os_alt', version='Pike',
Jakub Libosvar7835ca12017-05-04 16:44:23 +0200398 removal_version='Queens')
Andrea Frittoli (andreaf)825b2d32015-04-08 20:58:01 +0100399 elif isinstance(credentials_type, list):
400 manager = cls.get_client_manager(roles=credentials_type[1:],
401 force_new=True)
402 setattr(cls, 'os_roles_%s' % credentials_type[0], manager)
Andrea Frittolia5ddd552014-08-19 18:30:00 +0100403
404 @classmethod
405 def setup_clients(cls):
Andrea Frittoli99583672017-08-24 15:39:20 +0100406 """Create aliases to the clients in the client managers.
407
408 `setup_clients` is invoked after the credential provisioning step.
409 Client manager objects are available to tests already. The purpose
410 of this helper is to setup shortcuts to specific clients that are
411 useful for the tests implemented in the test class.
412
413 Its purpose is mostly for code readability, however it should be used
414 carefully to avoid doing exactly the opposite, i.e. making the code
415 unreadable and hard to debug. If aliases are defined in a super class
416 it won't be obvious what they refer to, so it's good practice to define
417 all aliases used in the class. Aliases are meant to be shortcuts to
418 be used in tests, not shortcuts to avoid helper method attributes.
419 If an helper method starts relying on a client alias and a subclass
420 overrides that alias, it will become rather difficult to understand
421 what the helper method actually does.
422
423 Example::
424
425 class TestDoneItRight(test.BaseTestCase):
426
427 credentials = ['primary', 'alt']
428
429 @classmethod
430 def setup_clients(cls):
431 super(TestDoneItRight, cls).setup_clients()
432 cls.servers = cls.os_primary.ServersClient()
433 cls.servers_alt = cls.os_alt.ServersClient()
434
435 def _a_good_helper(self, clients):
436 # Some complex logic we're going to use many times
437 servers = clients.ServersClient()
438 vm = servers.create_server(...)
439
440 def delete_server():
441 test_utils.call_and_ignore_notfound_exc(
442 servers.delete_server, vm['id'])
443
444 self.addCleanup(self.delete_server)
445 return vm
446
447 def test_with_servers(self):
448 vm = self._a_good_helper(os.primary)
449 vm_alt = self._a_good_helper(os.alt)
450 cls.servers.show_server(vm['id'])
451 cls.servers_alt.show_server(vm_alt['id'])
452 """
Andrea Frittoli73ee2472014-09-15 12:31:53 +0100453 pass
Attila Fazekasf86fa312013-07-30 19:56:39 +0200454
Emily Hugenbruch5bd4cbf2014-12-17 21:38:38 +0000455 @classmethod
456 def resource_setup(cls):
Andrea Frittoli3be57482017-08-25 22:41:26 +0100457 """Class level resource setup for test cases.
458
459 `resource_setup` is invoked once all credentials (and related network
460 resources have been provisioned and after client aliases - if any -
461 have been defined.
462
463 The use case for `resource_setup` is test optimization: provisioning
464 of project-specific "expensive" resources that are not dirtied by tests
465 and can thus safely be re-used by multiple tests.
466
467 System wide resources shared by all tests could instead be provisioned
468 only once, before the test run.
469
470 Resources provisioned here must be cleaned up during
471 `resource_cleanup`. This is best achieved by scheduling a cleanup via
472 `addClassResourceCleanup`.
473
474 Some test resources have an asynchronous delete process. It's best
475 practice for them to schedule a wait for delete via
476 `addClassResourceCleanup` to avoid having resources in process of
477 deletion when we reach the credentials cleanup step.
478
479 Example::
480
481 @classmethod
482 def resource_setup(cls):
483 super(MyTest, cls).resource_setup()
484 servers = cls.os_primary.compute.ServersClient()
485 # Schedule delete and wait so that we can first delete the
486 # two servers and then wait for both to delete
487 # Create server 1
488 cls.shared_server = servers.create_server()
489 # Create server 2. If something goes wrong we schedule cleanup
490 # of server 1 anyways.
491 try:
492 cls.shared_server2 = servers.create_server()
493 # Wait server 2
494 cls.addClassResourceCleanup(
495 waiters.wait_for_server_termination,
496 servers, cls.shared_server2['id'],
497 ignore_error=False)
498 finally:
499 # Wait server 1
500 cls.addClassResourceCleanup(
501 waiters.wait_for_server_termination,
502 servers, cls.shared_server['id'],
503 ignore_error=False)
504 # Delete server 1
505 cls.addClassResourceCleanup(
506 test_utils.call_and_ignore_notfound_exc,
507 servers.delete_server,
508 cls.shared_server['id'])
509 # Delete server 2 (if it was created)
510 if hasattr(cls, 'shared_server2'):
511 cls.addClassResourceCleanup(
512 test_utils.call_and_ignore_notfound_exc,
513 servers.delete_server,
514 cls.shared_server2['id'])
515 """
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100516 pass
Emily Hugenbruch5bd4cbf2014-12-17 21:38:38 +0000517
518 @classmethod
519 def resource_cleanup(cls):
520 """Class level resource cleanup for test cases.
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000521
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100522 Resource cleanup processes the stack of cleanups produced by
Andrea Frittoli3be57482017-08-25 22:41:26 +0100523 `addClassResourceCleanup` and then cleans up validation resources
524 if any were provisioned.
525
526 All cleanups are processed whatever the outcome. Exceptions are
527 accumulated and re-raised as a `MultipleExceptions` at the end.
528
529 In most cases test cases won't need to override `resource_cleanup`,
530 but if they do they must invoke `resource_cleanup` on super.
531
532 Example::
533
534 class TestWithReallyComplexCleanup(test.BaseTestCase):
535
536 @classmethod
537 def resource_setup(cls):
538 # provision resource A
539 cls.addClassResourceCleanup(delete_resource, A)
540 # provision resource B
541 cls.addClassResourceCleanup(delete_resource, B)
542
543 @classmethod
544 def resource_cleanup(cls):
545 # It's possible to override resource_cleanup but in most
546 # cases it shouldn't be required. Nothing that may fail
547 # should be executed before the call to super since it
548 # might cause resource leak in case of error.
549 super(TestWithReallyComplexCleanup, cls).resource_cleanup()
550 # At this point test credentials are still available but
551 # anything from the cleanup stack has been already deleted.
Emily Hugenbruch5bd4cbf2014-12-17 21:38:38 +0000552 """
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100553 cls.__resource_cleanup_called = True
Andrea Frittoli3be57482017-08-25 22:41:26 +0100554 cleanup_errors = []
555 while cls._class_cleanups:
556 try:
557 fn, args, kwargs = cls._class_cleanups.pop()
558 fn(*args, **kwargs)
559 except Exception:
560 cleanup_errors.append(sys.exc_info())
Andrea Frittoli3be57482017-08-25 22:41:26 +0100561 if cleanup_errors:
562 raise testtools.MultipleExceptions(*cleanup_errors)
563
564 @classmethod
565 def addClassResourceCleanup(cls, fn, *arguments, **keywordArguments):
566 """Add a cleanup function to be called during resource_cleanup.
567
568 Functions added with addClassResourceCleanup will be called in reverse
569 order of adding at the beginning of resource_cleanup, before any
570 credential, networking or validation resources cleanup is processed.
571
572 If a function added with addClassResourceCleanup raises an exception,
573 the error will be recorded as a test error, and the next cleanup will
574 then be run.
575
576 Cleanup functions are always called during the test class tearDown
577 fixture, even if an exception occured during setUp or tearDown.
578 """
579 cls._class_cleanups.append((fn, arguments, keywordArguments))
Emily Hugenbruch5bd4cbf2014-12-17 21:38:38 +0000580
Attila Fazekasf86fa312013-07-30 19:56:39 +0200581 def setUp(self):
582 super(BaseTestCase, self).setUp()
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600583 if not self.__setupclass_called:
Attila Fazekasf86fa312013-07-30 19:56:39 +0200584 raise RuntimeError("setUpClass does not calls the super's"
585 "setUpClass in the "
586 + self.__class__.__name__)
587 at_exit_set.add(self.__class__)
Matthew Treinish78561ad2013-07-26 11:41:56 -0400588 test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
589 try:
Sean Dague02620fd2016-03-02 15:52:51 -0500590 test_timeout = int(test_timeout) * self.TIMEOUT_SCALING_FACTOR
Matthew Treinish78561ad2013-07-26 11:41:56 -0400591 except ValueError:
592 test_timeout = 0
593 if test_timeout > 0:
Attila Fazekasf86fa312013-07-30 19:56:39 +0200594 self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
Matthew Treinish78561ad2013-07-26 11:41:56 -0400595
596 if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or
597 os.environ.get('OS_STDOUT_CAPTURE') == '1'):
Attila Fazekasf86fa312013-07-30 19:56:39 +0200598 stdout = self.useFixture(fixtures.StringStream('stdout')).stream
599 self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
Matthew Treinish78561ad2013-07-26 11:41:56 -0400600 if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or
601 os.environ.get('OS_STDERR_CAPTURE') == '1'):
Attila Fazekasf86fa312013-07-30 19:56:39 +0200602 stderr = self.useFixture(fixtures.StringStream('stderr')).stream
603 self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
Attila Fazekas31388072013-08-15 08:58:07 +0200604 if (os.environ.get('OS_LOG_CAPTURE') != 'False' and
605 os.environ.get('OS_LOG_CAPTURE') != '0'):
Attila Fazekas31388072013-08-15 08:58:07 +0200606 self.useFixture(fixtures.LoggerFixture(nuke_handlers=False,
Sean Dague2ef32ac2014-06-09 11:32:23 -0400607 format=self.log_format,
Attila Fazekas90445be2013-10-24 16:46:03 +0200608 level=None))
Matthew Treinish78561ad2013-07-26 11:41:56 -0400609
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100610 @property
611 def credentials_provider(self):
612 return self._get_credentials_provider()
613
614 @classmethod
Andrea Frittoli (andreaf)32d0de12015-10-09 14:43:53 +0100615 def get_identity_version(cls):
616 """Returns the identity version used by the test class"""
617 identity_version = getattr(cls, 'identity_version', None)
618 return identity_version or CONF.identity.auth_version
619
620 @classmethod
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100621 def _get_credentials_provider(cls):
622 """Returns a credentials provider
623
624 If no credential provider exists yet creates one.
Andrea Frittoli9e01dbb2017-04-20 15:28:30 +0100625 It always use the configuration value from identity.auth_version,
626 since we always want to provision accounts with the current version
627 of the identity API.
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100628 """
629 if (not hasattr(cls, '_creds_provider') or not cls._creds_provider or
630 not cls._creds_provider.name == cls.__name__):
631 force_tenant_isolation = getattr(cls, 'force_tenant_isolation',
632 False)
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100633
Andrea Frittoli (andreaf)17209bb2015-05-22 10:16:57 -0700634 cls._creds_provider = credentials.get_credentials_provider(
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100635 name=cls.__name__, network_resources=cls._network_resources,
Andrea Frittoli9e01dbb2017-04-20 15:28:30 +0100636 force_tenant_isolation=force_tenant_isolation)
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100637 return cls._creds_provider
638
Matthew Treinish3e046852013-07-23 16:00:24 -0400639 @classmethod
Andrea Frittoli (andreaf)41601412015-05-12 16:39:03 +0100640 def get_client_manager(cls, credential_type=None, roles=None,
641 force_new=None):
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100642 """Returns an OpenStack client manager
643
644 Returns an OpenStack client manager based on either credential_type
645 or a list of roles. If neither is specified, it defaults to
646 credential_type 'primary'
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100647 :param credential_type: string - primary, alt or admin
648 :param roles: list of roles
649
lei zhangdd552b22015-11-25 20:41:48 +0800650 :returns: the created client manager
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100651 :raises skipException: if the requested credentials are not available
Ryan Hsu6c4bb3d2013-10-21 21:22:50 -0700652 """
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100653 if all([roles, credential_type]):
654 msg = "Cannot get credentials by type and roles at the same time"
655 raise ValueError(msg)
656 if not any([roles, credential_type]):
657 credential_type = 'primary'
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100658 cred_provider = cls._get_credentials_provider()
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100659 if roles:
660 for role in roles:
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100661 if not cred_provider.is_role_available(role):
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100662 skip_msg = (
663 "%s skipped because the configured credential provider"
664 " is not able to provide credentials with the %s role "
665 "assigned." % (cls.__name__, role))
666 raise cls.skipException(skip_msg)
667 params = dict(roles=roles)
668 if force_new is not None:
669 params.update(force_new=force_new)
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100670 creds = cred_provider.get_creds_by_roles(**params)
Andrea Frittolib21de6c2015-02-06 20:12:38 +0000671 else:
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100672 credentials_method = 'get_%s_creds' % credential_type
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100673 if hasattr(cred_provider, credentials_method):
674 creds = getattr(cred_provider, credentials_method)()
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100675 else:
Andrea Frittoli (andreaf)af4f7cf2016-06-13 15:12:26 +0100676 raise lib_exc.InvalidCredentials(
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +0100677 "Invalid credentials type %s" % credential_type)
Jordan Pittiere4be9072017-01-04 19:17:35 +0100678 manager = cls.client_manager(credentials=creds.credentials)
Andrea Frittoli73224672016-12-09 21:08:19 +0000679 # NOTE(andreaf) Ensure credentials have user and project id fields.
680 # It may not be the case when using pre-provisioned credentials.
681 manager.auth_provider.set_auth()
682 return manager
Ryan Hsu6c4bb3d2013-10-21 21:22:50 -0700683
684 @classmethod
Andrea Frittoli (andreaf)17209bb2015-05-22 10:16:57 -0700685 def clear_credentials(cls):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000686 """Clears creds if set"""
Attila Fazekas5b0d9262015-05-20 10:17:39 +0200687 if hasattr(cls, '_creds_provider'):
Andrea Frittoli (andreaf)17209bb2015-05-22 10:16:57 -0700688 cls._creds_provider.clear_creds()
Ryan Hsu6c4bb3d2013-10-21 21:22:50 -0700689
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100690 @staticmethod
691 def _validation_resources_params_from_conf():
692 return dict(
693 keypair=(CONF.validation.auth_method.lower() == "keypair"),
694 floating_ip=(CONF.validation.connect_method.lower() == "floating"),
695 security_group=CONF.validation.security_group,
696 security_group_rules=CONF.validation.security_group_rules,
697 use_neutron=CONF.service_available.neutron,
698 ethertype='IPv' + str(CONF.validation.ip_version_for_ssh),
699 floating_network_id=CONF.network.public_network_id,
700 floating_network_name=CONF.network.floating_network_name)
701
Ryan Hsu6c4bb3d2013-10-21 21:22:50 -0700702 @classmethod
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100703 def get_class_validation_resources(cls, os_clients):
704 """Provision validation resources according to configuration
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +0000705
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100706 This is a wrapper around `create_validation_resources` from
707 `tempest.common.validation_resources` that passes parameters from
708 Tempest configuration. Only one instance of class level
709 validation resources is managed by the helper, so If resources
710 were already provisioned before, existing ones will be returned.
nithya-ganesan222efd72015-01-22 12:20:27 +0000711
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100712 Resources are returned as a dictionary. They are also scheduled for
713 automatic cleanup during class teardown using
714 `addClassResourcesCleanup`.
715
716 If `CONF.validation.run_validation` is False no resource will be
717 provisioned at all.
718
719 @param os_clients: Clients to be used to provision the resources.
nithya-ganesan222efd72015-01-22 12:20:27 +0000720 """
Matthew Treinishe5cca002015-05-11 15:36:50 -0400721 if not CONF.validation.run_validation:
722 return
Jordan Pittier79cd1822016-12-08 17:20:35 +0100723
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100724 if os_clients in cls._validation_resources:
725 return cls._validation_resources[os_clients]
Jordan Pittier79cd1822016-12-08 17:20:35 +0100726
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100727 if (CONF.validation.ip_version_for_ssh not in (4, 6) and
728 CONF.service_available.neutron):
729 msg = "Invalid IP version %s in ip_version_for_ssh. Use 4 or 6"
730 raise lib_exc.InvalidConfiguration(
731 msg % CONF.validation.ip_version_for_ssh)
Jordan Pittier79cd1822016-12-08 17:20:35 +0100732
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100733 resources = vr.create_validation_resources(
734 os_clients,
735 **cls._validation_resources_params_from_conf())
Jordan Pittier79cd1822016-12-08 17:20:35 +0100736
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100737 cls.addClassResourceCleanup(
738 vr.clear_validation_resources, os_clients,
739 use_neutron=CONF.service_available.neutron,
740 **resources)
741 cls._validation_resources[os_clients] = resources
742 return resources
Brandon Palmc6cc91d2015-08-19 13:20:21 -0500743
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100744 def get_test_validation_resources(self, os_clients):
745 """Returns a dict of validation resources according to configuration
746
747 Initialise a validation resources fixture based on configuration.
748 Start the fixture and returns the validation resources.
749
750 If `CONF.validation.run_validation` is False no resource will be
751 provisioned at all.
752
753 @param os_clients: Clients to be used to provision the resources.
754 """
755
756 params = {}
757 # Test will try to use the fixture, so for this to be useful
758 # we must return a fixture. If validation is disabled though
759 # we don't need to provision anything, which is the default
760 # behavior for the fixture.
761 if CONF.validation.run_validation:
762 params = self._validation_resources_params_from_conf()
763
764 validation = self.useFixture(
765 vr.ValidationResourcesFixture(os_clients, **params))
766 return validation.resources
nithya-ganesan222efd72015-01-22 12:20:27 +0000767
768 @classmethod
Andrea Frittoli7d5ed592015-02-10 01:10:23 +0000769 def set_network_resources(cls, network=False, router=False, subnet=False,
Matthew Treinish9f756a02014-01-15 10:26:07 -0500770 dhcp=False):
771 """Specify which network resources should be created
772
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100773 The dynamic credentials provider by default provisions network
774 resources for each user/project that is provisioned. This behavior
775 can be altered using this method, which allows tests to define which
776 specific network resources to be provisioned - none if no parameter
777 is specified.
778
Andrea Frittolia6c885a2017-08-23 19:37:50 +0100779 This method is designed so that only the network resources set on the
780 leaf class are honoured.
781
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100782 Credentials are provisioned as part of the class setup fixture,
783 during the `setup_credentials` step. For this to be effective this
784 helper must be invoked before super's `setup_credentials` is executed.
785
Matthew Treinish9f756a02014-01-15 10:26:07 -0500786 @param network
787 @param router
788 @param subnet
789 @param dhcp
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100790
791 Example::
792
793 @classmethod
794 def setup_credentials(cls):
795 # Do not setup network resources for this test
796 cls.set_network_resources()
797 super(MyTest, cls).setup_credentials()
Matthew Treinish9f756a02014-01-15 10:26:07 -0500798 """
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100799 # If this is invoked after the credentials are setup, it won't take
800 # any effect. To avoid this situation, fail the test in case this was
801 # invoked too late in the test lifecycle.
802 if cls.__setup_credentials_called:
803 raise RuntimeError(
804 "set_network_resources invoked after setup_credentials on the "
805 "super class has been already invoked. For "
806 "set_network_resources to have effect please invoke it before "
807 "the call to super().setup_credentials")
808
809 # Network resources should be set only once from callers
Salvatore Orlando5a337242014-01-15 22:49:22 +0000810 # in order to ensure that even if it's called multiple times in
811 # a chain of overloaded methods, the attribute is set only
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100812 # in the leaf class.
813 if not cls._network_resources:
814 cls._network_resources = {
Salvatore Orlando5a337242014-01-15 22:49:22 +0000815 'network': network,
816 'router': router,
817 'subnet': subnet,
818 'dhcp': dhcp}
Matthew Treinish9f756a02014-01-15 10:26:07 -0500819
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530820 @classmethod
Ryan Rossiter9228bf72016-02-25 03:06:12 +0000821 def get_tenant_network(cls, credentials_type='primary'):
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530822 """Get the network to be used in testing
823
Ryan Rossiter9228bf72016-02-25 03:06:12 +0000824 :param credentials_type: The type of credentials for which to get the
825 tenant network
826
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530827 :return: network dict including 'id' and 'name'
828 """
Ryan Rossiter9228bf72016-02-25 03:06:12 +0000829 # Get a manager for the given credentials_type, but at least
830 # always fall back on getting the manager for primary credentials
831 if isinstance(credentials_type, six.string_types):
832 manager = cls.get_client_manager(credential_type=credentials_type)
833 elif isinstance(credentials_type, list):
834 manager = cls.get_client_manager(roles=credentials_type[1:])
835 else:
836 manager = cls.get_client_manager()
837
Andrea Frittoli (andreaf)17209bb2015-05-22 10:16:57 -0700838 # Make sure cred_provider exists and get a network client
Ryan Rossiter9228bf72016-02-25 03:06:12 +0000839 networks_client = manager.compute_networks_client
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100840 cred_provider = cls._get_credentials_provider()
Andrea Frittoli700711e2015-04-02 11:39:38 +0100841 # In case of nova network, isolated tenants are not able to list the
Joshua Whitebd769602016-02-02 09:30:11 -0800842 # network configured in fixed_network_name, even if they can use it
Andrea Frittoli700711e2015-04-02 11:39:38 +0100843 # for their servers, so using an admin network client to validate
844 # the network name
845 if (not CONF.service_available.neutron and
Andrea Frittoli (andreaf)32d0de12015-10-09 14:43:53 +0100846 credentials.is_admin_available(
847 identity_version=cls.get_identity_version())):
Andrea Frittoli (andreaf)1f342412015-05-12 16:37:19 +0100848 admin_creds = cred_provider.get_admin_creds()
Andrea Frittoli (andreaf)848c4a12016-06-09 11:09:02 +0100849 admin_manager = clients.Manager(admin_creds.credentials)
John Warren9487a182015-09-14 18:12:56 -0400850 networks_client = admin_manager.compute_networks_client
Andrea Frittoli (andreaf)940f8c62015-10-30 16:39:24 +0900851 return fixed_network.get_tenant_network(
852 cred_provider, networks_client, CONF.compute.fixed_network_name)
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530853
Andrea Frittoli71c71e92017-04-07 17:45:21 +0100854 def assertEmpty(self, items, msg=None):
855 """Asserts whether a sequence or collection is empty
Mark Maglana5885eb32014-02-28 10:57:34 -0800856
Andrea Frittoli71c71e92017-04-07 17:45:21 +0100857 :param items: sequence or collection to be tested
858 :param msg: message to be passed to the AssertionError
859 :raises AssertionError: when items is not empty
860 """
zhufl92ade4b2017-03-03 15:20:10 +0800861 if msg is None:
Andrea Frittoli71c71e92017-04-07 17:45:21 +0100862 msg = "sequence or collection is not empty: %s" % items
Masayuki Igawa0c0f0142017-04-10 17:22:02 +0900863 self.assertFalse(items, msg)
Andrea Frittoli71c71e92017-04-07 17:45:21 +0100864
865 def assertNotEmpty(self, items, msg=None):
866 """Asserts whether a sequence or collection is not empty
867
868 :param items: sequence or collection to be tested
869 :param msg: message to be passed to the AssertionError
870 :raises AssertionError: when items is empty
871 """
872 if msg is None:
873 msg = "sequence or collection is empty."
Masayuki Igawa0c0f0142017-04-10 17:22:02 +0900874 self.assertTrue(items, msg)