blob: 80825a4896a4f6c61bfa626aef25bbbc4676eb8f [file] [log] [blame]
Andrea Frittoli3be57482017-08-25 22:41:26 +01001# Copyright 2017 IBM Corp
2# 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
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +010016import os
Jon Schlueter1ff77482022-01-24 17:38:48 -050017import unittest
Sean McGinniseed80742020-04-18 12:01:03 -050018from unittest import mock
Andrea Frittoli3be57482017-08-25 22:41:26 +010019
Balazs Gibizerdfb30432021-12-14 17:25:16 +010020from oslo_concurrency import lockutils
Andrea Frittoli3be57482017-08-25 22:41:26 +010021from oslo_config import cfg
22import testtools
23
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010024from tempest import clients
Andrea Frittoli3be57482017-08-25 22:41:26 +010025from tempest import config
Andrea Frittoli0477acc2017-08-09 21:14:53 +010026from tempest.lib.common import validation_resources as vr
Balazs Gibizerdfb30432021-12-14 17:25:16 +010027from tempest.lib import decorators
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010028from tempest.lib import exceptions as lib_exc
Ghanshyam Mann18b45d72021-12-07 12:37:29 -060029from tempest.lib.services.compute import base_compute_client
30from tempest.lib.services.placement import base_placement_client
31from tempest.lib.services.volume import base_client as base_volume_client
Andrea Frittoli3be57482017-08-25 22:41:26 +010032from tempest import test
33from tempest.tests import base
34from tempest.tests import fake_config
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010035from tempest.tests.lib import fake_credentials
36from tempest.tests.lib.services import registry_fixture
Andrea Frittoli3be57482017-08-25 22:41:26 +010037
Balazs Gibizerdfb30432021-12-14 17:25:16 +010038CONF = config.CONF
39
Andrea Frittoli3be57482017-08-25 22:41:26 +010040
Andrea Frittoli3be57482017-08-25 22:41:26 +010041class LoggingTestResult(testtools.TestResult):
42
43 def __init__(self, log, *args, **kwargs):
44 super(LoggingTestResult, self).__init__(*args, **kwargs)
45 self.log = log
46
47 def addError(self, test, err=None, details=None):
48 self.log.append((test, err, details))
49
50
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010051class TestValidationResources(base.TestCase):
52
Andrea Frittoli0477acc2017-08-09 21:14:53 +010053 validation_resources_module = 'tempest.lib.common.validation_resources'
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010054
55 def setUp(self):
56 super(TestValidationResources, self).setUp()
57 self.useFixture(fake_config.ConfigFixture())
58 self.useFixture(registry_fixture.RegistryFixture())
59 self.patchobject(config, 'TempestConfigPrivate',
60 fake_config.FakePrivate)
61
62 class TestTestClass(test.BaseTestCase):
63 pass
64
65 self.test_test_class = TestTestClass
66
67 def test_validation_resources_no_validation(self):
68 cfg.CONF.set_default('run_validation', False, 'validation')
69 creds = fake_credentials.FakeKeystoneV3Credentials()
70 osclients = clients.Manager(creds)
71 vr = self.test_test_class.get_class_validation_resources(osclients)
Dan Smith8f9c77b2023-05-01 14:02:46 -070072 self.assertEqual({}, vr)
Andrea Frittoli9f416dd2017-08-10 15:38:00 +010073
74 def test_validation_resources_exists(self):
75 cfg.CONF.set_default('run_validation', True, 'validation')
76 creds = fake_credentials.FakeKeystoneV3Credentials()
77 osclients = clients.Manager(creds)
78 expected_vr = 'expected_validation_resources'
79 self.test_test_class._validation_resources[osclients] = expected_vr
80 obtained_vr = self.test_test_class.get_class_validation_resources(
81 osclients)
82 self.assertEqual(expected_vr, obtained_vr)
83
84 @mock.patch(validation_resources_module + '.create_validation_resources',
85 autospec=True)
86 def test_validation_resources_new(self, mock_create_vr):
87 cfg.CONF.set_default('run_validation', True, 'validation')
88 cfg.CONF.set_default('neutron', True, 'service_available')
89 creds = fake_credentials.FakeKeystoneV3Credentials()
90 osclients = clients.Manager(creds)
91 expected_vr = {'expected_validation_resources': None}
92 mock_create_vr.return_value = expected_vr
93 with mock.patch.object(
94 self.test_test_class,
95 'addClassResourceCleanup') as mock_add_class_cleanup:
96 obtained_vr = self.test_test_class.get_class_validation_resources(
97 osclients)
98 self.assertEqual(1, mock_add_class_cleanup.call_count)
99 self.assertEqual(mock.call(vr.clear_validation_resources,
100 osclients,
101 use_neutron=True,
102 **expected_vr),
103 mock_add_class_cleanup.call_args)
104 self.assertEqual(mock_create_vr.call_count, 1)
105 self.assertIn(osclients, mock_create_vr.call_args_list[0][0])
106 self.assertEqual(expected_vr, obtained_vr)
107 self.assertIn(osclients, self.test_test_class._validation_resources)
108 self.assertEqual(expected_vr,
109 self.test_test_class._validation_resources[osclients])
110
111 def test_validation_resources_invalid_config(self):
112 invalid_version = 999
113 cfg.CONF.set_default('run_validation', True, 'validation')
114 cfg.CONF.set_default('ip_version_for_ssh', invalid_version,
115 'validation')
116 cfg.CONF.set_default('neutron', True, 'service_available')
117 creds = fake_credentials.FakeKeystoneV3Credentials()
118 osclients = clients.Manager(creds)
119 with testtools.ExpectedException(
120 lib_exc.InvalidConfiguration,
121 value_re='^.*\n.*' + str(invalid_version)):
122 self.test_test_class.get_class_validation_resources(osclients)
123
124 @mock.patch(validation_resources_module + '.create_validation_resources',
125 autospec=True)
126 def test_validation_resources_invalid_config_nova_net(self,
127 mock_create_vr):
128 invalid_version = 999
129 cfg.CONF.set_default('run_validation', True, 'validation')
130 cfg.CONF.set_default('ip_version_for_ssh', invalid_version,
131 'validation')
132 cfg.CONF.set_default('neutron', False, 'service_available')
133 creds = fake_credentials.FakeKeystoneV3Credentials()
134 osclients = clients.Manager(creds)
135 expected_vr = {'expected_validation_resources': None}
136 mock_create_vr.return_value = expected_vr
137 obtained_vr = self.test_test_class.get_class_validation_resources(
138 osclients)
139 self.assertEqual(mock_create_vr.call_count, 1)
140 self.assertIn(osclients, mock_create_vr.call_args_list[0][0])
141 self.assertEqual(expected_vr, obtained_vr)
142 self.assertIn(osclients, self.test_test_class._validation_resources)
143 self.assertEqual(expected_vr,
144 self.test_test_class._validation_resources[osclients])
145
146 @mock.patch(validation_resources_module + '.create_validation_resources',
147 autospec=True)
148 @mock.patch(validation_resources_module + '.clear_validation_resources',
149 autospec=True)
150 def test_validation_resources_fixture(self, mock_clean_vr, mock_create_vr):
151
152 class TestWithRun(self.test_test_class):
153
154 def runTest(self):
155 pass
156
157 cfg.CONF.set_default('run_validation', True, 'validation')
158 test_case = TestWithRun()
159 creds = fake_credentials.FakeKeystoneV3Credentials()
160 osclients = clients.Manager(creds)
161 test_case.get_test_validation_resources(osclients)
162 self.assertEqual(1, mock_create_vr.call_count)
163 self.assertEqual(0, mock_clean_vr.call_count)
164
165
Andrea Frittolibcbf1af12017-08-14 11:53:35 +0100166class TestSetNetworkResources(base.TestCase):
167
168 def setUp(self):
169 super(TestSetNetworkResources, self).setUp()
170
171 class ParentTest(test.BaseTestCase):
172
173 @classmethod
174 def setup_credentials(cls):
175 cls.set_network_resources(dhcp=True)
176 super(ParentTest, cls).setup_credentials()
177
178 def runTest(self):
179 pass
180
181 self.parent_class = ParentTest
182
183 def test_set_network_resources_child_only(self):
184
185 class ChildTest(self.parent_class):
186
187 @classmethod
188 def setup_credentials(cls):
189 cls.set_network_resources(router=True)
190 super(ChildTest, cls).setup_credentials()
191
192 child_test = ChildTest()
193 child_test.setUpClass()
194 # Assert that the parents network resources are not set
195 self.assertFalse(child_test._network_resources['dhcp'])
196 # Assert that the child network resources are set
197 self.assertTrue(child_test._network_resources['router'])
198
199 def test_set_network_resources_right_order(self):
200
201 class ChildTest(self.parent_class):
202
203 @classmethod
204 def setup_credentials(cls):
205 super(ChildTest, cls).setup_credentials()
206 cls.set_network_resources(router=True)
207
208 child_test = ChildTest()
209 with testtools.ExpectedException(RuntimeError,
210 value_re='set_network_resources'):
211 child_test.setUpClass()
212
213 def test_set_network_resources_children(self):
214
215 class ChildTest(self.parent_class):
216
217 @classmethod
218 def setup_credentials(cls):
219 cls.set_network_resources(router=True)
220 super(ChildTest, cls).setup_credentials()
221
222 class GrandChildTest(ChildTest):
223 pass
224
225 # Invoke setupClass on both and check that the setup_credentials
226 # call check mechanism does not report any false negative.
227 child_test = ChildTest()
228 child_test.setUpClass()
229 grandchild_test = GrandChildTest()
230 grandchild_test.setUpClass()
231
232
Andrea Frittoli3be57482017-08-25 22:41:26 +0100233class TestTempestBaseTestClass(base.TestCase):
234
235 def setUp(self):
236 super(TestTempestBaseTestClass, self).setUp()
237 self.useFixture(fake_config.ConfigFixture())
238 self.patchobject(config, 'TempestConfigPrivate',
239 fake_config.FakePrivate)
240
241 class ParentTest(test.BaseTestCase):
242
243 def runTest(self):
244 pass
245
246 self.parent_test = ParentTest
247
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100248 def test_resource_cleanup(self):
Andrea Frittoli3be57482017-08-25 22:41:26 +0100249 cfg.CONF.set_default('neutron', False, 'service_available')
250 exp_args = (1, 2,)
251 exp_kwargs = {'a': 1, 'b': 2}
Andrea Frittoli3be57482017-08-25 22:41:26 +0100252 mock1 = mock.Mock()
253 mock2 = mock.Mock()
254 exp_functions = [mock1, mock2]
255
256 class TestWithCleanups(self.parent_test):
257
Andrea Frittoli3be57482017-08-25 22:41:26 +0100258 @classmethod
259 def resource_setup(cls):
260 for fn in exp_functions:
261 cls.addClassResourceCleanup(fn, *exp_args,
262 **exp_kwargs)
263
264 test_cleanups = TestWithCleanups()
265 suite = unittest.TestSuite((test_cleanups,))
266 log = []
267 result = LoggingTestResult(log)
268 suite.run(result)
269 # No exception raised - error log is empty
270 self.assertFalse(log)
271 # All stacked resource cleanups invoked
272 mock1.assert_called_once_with(*exp_args, **exp_kwargs)
273 mock2.assert_called_once_with(*exp_args, **exp_kwargs)
Andrea Frittoli3be57482017-08-25 22:41:26 +0100274 # Cleanup stack is empty
275 self.assertEqual(0, len(test_cleanups._class_cleanups))
Andrea Frittoli3be57482017-08-25 22:41:26 +0100276
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100277 def test_resource_cleanup_failures(self):
Andrea Frittoli3be57482017-08-25 22:41:26 +0100278 cfg.CONF.set_default('neutron', False, 'service_available')
279 exp_args = (1, 2,)
280 exp_kwargs = {'a': 1, 'b': 2}
Andrea Frittoli3be57482017-08-25 22:41:26 +0100281 mock1 = mock.Mock()
282 mock1.side_effect = Exception('mock1 resource cleanup failure')
283 mock2 = mock.Mock()
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100284 mock3 = mock.Mock()
285 mock3.side_effect = Exception('mock3 resource cleanup failure')
286 exp_functions = [mock1, mock2, mock3]
Andrea Frittoli3be57482017-08-25 22:41:26 +0100287
288 class TestWithFailingCleanups(self.parent_test):
289
Andrea Frittoli3be57482017-08-25 22:41:26 +0100290 @classmethod
291 def resource_setup(cls):
292 for fn in exp_functions:
293 cls.addClassResourceCleanup(fn, *exp_args,
294 **exp_kwargs)
295
296 test_cleanups = TestWithFailingCleanups()
297 suite = unittest.TestSuite((test_cleanups,))
298 log = []
299 result = LoggingTestResult(log)
300 suite.run(result)
301 # One multiple exception captured
302 self.assertEqual(1, len(log))
303 # [0]: test, err, details [1] -> exc_info
304 # Type, Exception, traceback [1] -> MultipleException
305 found_exc = log[0][1][1]
306 self.assertTrue(isinstance(found_exc, testtools.MultipleExceptions))
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100307 self.assertEqual(2, len(found_exc.args))
Andrea Frittoli3be57482017-08-25 22:41:26 +0100308 # Each arg is exc_info - match messages and order
Andrea Frittoli9f416dd2017-08-10 15:38:00 +0100309 self.assertIn('mock3 resource', str(found_exc.args[0][1]))
310 self.assertIn('mock1 resource', str(found_exc.args[1][1]))
Andrea Frittoli3be57482017-08-25 22:41:26 +0100311 # All stacked resource cleanups invoked
312 mock1.assert_called_once_with(*exp_args, **exp_kwargs)
313 mock2.assert_called_once_with(*exp_args, **exp_kwargs)
Andrea Frittoli3be57482017-08-25 22:41:26 +0100314 # Cleanup stack is empty
315 self.assertEqual(0, len(test_cleanups._class_cleanups))
Andrea Frittoli3be57482017-08-25 22:41:26 +0100316
317 def test_super_resource_cleanup_not_invoked(self):
318
319 class BadResourceCleanup(self.parent_test):
320
321 @classmethod
322 def resource_cleanup(cls):
323 pass
324
325 bad_class = BadResourceCleanup()
326 suite = unittest.TestSuite((bad_class,))
327 log = []
328 result = LoggingTestResult(log)
329 suite.run(result)
330 # One multiple exception captured
331 self.assertEqual(1, len(log))
332 # [0]: test, err, details [1] -> exc_info
333 # Type, Exception, traceback [1] -> RuntimeError
334 found_exc = log[0][1][1]
335 self.assertTrue(isinstance(found_exc, RuntimeError))
336 self.assertIn(BadResourceCleanup.__name__, str(found_exc))
Andrea Frittoli421dc3c2017-08-15 12:17:42 +0100337
338 def test_super_skip_checks_not_invoked(self):
339
340 class BadSkipChecks(self.parent_test):
341
342 @classmethod
343 def skip_checks(cls):
344 pass
345
346 bad_class = BadSkipChecks()
347 with testtools.ExpectedException(
348 RuntimeError,
349 value_re='^.* ' + BadSkipChecks.__name__):
350 bad_class.setUpClass()
351
352 def test_super_setup_credentials_not_invoked(self):
353
354 class BadSetupCredentials(self.parent_test):
355
356 @classmethod
357 def skip_checks(cls):
358 pass
359
360 bad_class = BadSetupCredentials()
361 with testtools.ExpectedException(
362 RuntimeError,
363 value_re='^.* ' + BadSetupCredentials.__name__):
364 bad_class.setUpClass()
365
366 def test_grandparent_skip_checks_not_invoked(self):
367
368 class BadSkipChecks(self.parent_test):
369
370 @classmethod
371 def skip_checks(cls):
372 pass
373
374 class SonOfBadSkipChecks(BadSkipChecks):
375 pass
376
377 bad_class = SonOfBadSkipChecks()
378 with testtools.ExpectedException(
379 RuntimeError,
380 value_re='^.* ' + SonOfBadSkipChecks.__name__):
381 bad_class.setUpClass()
Andrea Frittolia5440c82017-08-23 18:11:21 +0100382
383 @mock.patch('tempest.common.credentials_factory.is_admin_available',
384 autospec=True, return_value=True)
385 def test_skip_checks_admin(self, mock_iaa):
386 identity_version = 'identity_version'
387
388 class NeedAdmin(self.parent_test):
389 credentials = ['admin']
390
391 @classmethod
392 def get_identity_version(cls):
393 return identity_version
394
395 NeedAdmin().skip_checks()
396 mock_iaa.assert_called_once_with('identity_version')
397
398 @mock.patch('tempest.common.credentials_factory.is_admin_available',
399 autospec=True, return_value=False)
400 def test_skip_checks_admin_not_available(self, mock_iaa):
401 identity_version = 'identity_version'
402
403 class NeedAdmin(self.parent_test):
404 credentials = ['admin']
405
406 @classmethod
407 def get_identity_version(cls):
408 return identity_version
409
410 with testtools.ExpectedException(testtools.testcase.TestSkipped):
411 NeedAdmin().skip_checks()
412 mock_iaa.assert_called_once_with('identity_version')
413
414 def test_skip_checks_identity_v2_not_available(self):
415 cfg.CONF.set_default('api_v2', False, 'identity-feature-enabled')
416
417 class NeedV2(self.parent_test):
418 identity_version = 'v2'
419
420 with testtools.ExpectedException(testtools.testcase.TestSkipped):
421 NeedV2().skip_checks()
422
423 def test_skip_checks_identity_v3_not_available(self):
424 cfg.CONF.set_default('api_v3', False, 'identity-feature-enabled')
425
426 class NeedV3(self.parent_test):
427 identity_version = 'v3'
428
429 with testtools.ExpectedException(testtools.testcase.TestSkipped):
430 NeedV3().skip_checks()
Andrea Frittolia6c885a2017-08-23 19:37:50 +0100431
432 def test_setup_credentials_all(self):
433 expected_creds = ['string', ['list', 'role1', 'role2']]
434
435 class AllCredentials(self.parent_test):
436 credentials = expected_creds
437
438 expected_clients = 'clients'
439 with mock.patch.object(
440 AllCredentials,
441 'get_client_manager') as mock_get_client_manager:
442 mock_get_client_manager.return_value = expected_clients
443 all_creds = AllCredentials()
444 all_creds.setup_credentials()
445 self.assertTrue(hasattr(all_creds, 'os_string'))
446 self.assertEqual(expected_clients, all_creds.os_string)
447 self.assertTrue(hasattr(all_creds, 'os_roles_list'))
448 self.assertEqual(expected_clients, all_creds.os_roles_list)
449 self.assertEqual(2, mock_get_client_manager.call_count)
450 self.assertEqual(
451 expected_creds[0],
452 mock_get_client_manager.mock_calls[0][2]['credential_type'])
453 self.assertEqual(
454 expected_creds[1][1:],
455 mock_get_client_manager.mock_calls[1][2]['roles'])
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100456
Ghanshyam Mann2d0da042021-03-05 09:09:30 -0600457 def test_setup_credentials_with_role_and_system_scope(self):
458 expected_creds = [['system_my_role', 'role1', 'role2']]
459
460 class SystemRoleCredentials(self.parent_test):
461 credentials = expected_creds
462
463 expected_clients = 'clients'
464 with mock.patch.object(
465 SystemRoleCredentials,
466 'get_client_manager') as mock_get_client_manager:
467 mock_get_client_manager.return_value = expected_clients
468 sys_creds = SystemRoleCredentials()
469 sys_creds.setup_credentials()
470 self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
471 self.assertEqual(expected_clients, sys_creds.os_system_my_role)
472 self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
473 self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
474 self.assertEqual(1, mock_get_client_manager.call_count)
475 self.assertEqual(
476 expected_creds[0][1:],
477 mock_get_client_manager.mock_calls[0][2]['roles'])
478 self.assertEqual(
479 'system',
480 mock_get_client_manager.mock_calls[0][2]['scope'])
481
482 def test_setup_credentials_with_multiple_role_and_system_scope(self):
483 expected_creds = [['system_my_role', 'role1', 'role2'],
484 ['system_my_role2', 'role1', 'role2'],
485 ['system_my_role3', 'role3']]
486
487 class SystemRoleCredentials(self.parent_test):
488 credentials = expected_creds
489
490 expected_clients = 'clients'
491 with mock.patch.object(
492 SystemRoleCredentials,
493 'get_client_manager') as mock_get_client_manager:
494 mock_get_client_manager.return_value = expected_clients
495 sys_creds = SystemRoleCredentials()
496 sys_creds.setup_credentials()
497 self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
498 self.assertEqual(expected_clients, sys_creds.os_system_my_role)
499 self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
500 self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
501 self.assertTrue(hasattr(sys_creds, 'os_system_my_role2'))
502 self.assertEqual(expected_clients, sys_creds.os_system_my_role2)
503 self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role2'))
504 self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role2)
505 self.assertTrue(hasattr(sys_creds, 'os_system_my_role3'))
506 self.assertEqual(expected_clients, sys_creds.os_system_my_role3)
507 self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role3'))
508 self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role3)
509 self.assertEqual(3, mock_get_client_manager.call_count)
510 self.assertEqual(
511 expected_creds[0][1:],
512 mock_get_client_manager.mock_calls[0][2]['roles'])
513 self.assertEqual(
514 'system', mock_get_client_manager.mock_calls[0][2]['scope'])
515 self.assertEqual(
516 expected_creds[1][1:],
517 mock_get_client_manager.mock_calls[1][2]['roles'])
518 self.assertEqual(
519 'system', mock_get_client_manager.mock_calls[1][2]['scope'])
520 self.assertEqual(
521 expected_creds[2][1:],
522 mock_get_client_manager.mock_calls[2][2]['roles'])
523 self.assertEqual(
524 'system', mock_get_client_manager.mock_calls[2][2]['scope'])
525
526 def test_setup_credentials_with_role_and_multiple_scope(self):
527 expected_creds = [['my_role', 'role1', 'role2'],
528 ['project_my_role', 'role1', 'role2'],
529 ['domain_my_role', 'role1', 'role2'],
530 ['system_my_role', 'role1', 'role2']]
531
532 class SystemRoleCredentials(self.parent_test):
533 credentials = expected_creds
534
535 expected_clients = 'clients'
536 with mock.patch.object(
537 SystemRoleCredentials,
538 'get_client_manager') as mock_get_client_manager:
539 mock_get_client_manager.return_value = expected_clients
540 sys_creds = SystemRoleCredentials()
541 sys_creds.setup_credentials()
542 self.assertTrue(hasattr(sys_creds, 'os_my_role'))
543 self.assertEqual(expected_clients, sys_creds.os_my_role)
544 self.assertTrue(hasattr(sys_creds, 'os_roles_my_role'))
545 self.assertEqual(expected_clients, sys_creds.os_roles_my_role)
546 self.assertTrue(hasattr(sys_creds, 'os_project_my_role'))
547 self.assertEqual(expected_clients, sys_creds.os_project_my_role)
548 self.assertTrue(hasattr(sys_creds, 'os_roles_project_my_role'))
549 self.assertEqual(expected_clients, sys_creds.os_roles_project_my_role)
550 self.assertTrue(hasattr(sys_creds, 'os_domain_my_role'))
551 self.assertEqual(expected_clients, sys_creds.os_domain_my_role)
552 self.assertTrue(hasattr(sys_creds, 'os_roles_domain_my_role'))
553 self.assertEqual(expected_clients, sys_creds.os_roles_domain_my_role)
554 self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
555 self.assertEqual(expected_clients, sys_creds.os_system_my_role)
556 self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
557 self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
558
559 self.assertEqual(4, mock_get_client_manager.call_count)
560 self.assertEqual(
561 expected_creds[0][1:],
562 mock_get_client_manager.mock_calls[0][2]['roles'])
563 self.assertEqual(
564 'project', mock_get_client_manager.mock_calls[0][2]['scope'])
565 self.assertEqual(
566 expected_creds[1][1:],
567 mock_get_client_manager.mock_calls[1][2]['roles'])
568 self.assertEqual(
569 'project', mock_get_client_manager.mock_calls[1][2]['scope'])
570 self.assertEqual(
571 expected_creds[2][1:],
572 mock_get_client_manager.mock_calls[2][2]['roles'])
573 self.assertEqual(
574 'domain', mock_get_client_manager.mock_calls[2][2]['scope'])
575 self.assertEqual(
576 expected_creds[3][1:],
577 mock_get_client_manager.mock_calls[3][2]['roles'])
578 self.assertEqual(
579 'system', mock_get_client_manager.mock_calls[3][2]['scope'])
580
Andrea Frittoliba712ac2017-09-13 16:54:47 -0600581 def test_setup_class_overwritten(self):
582
583 class OverridesSetup(self.parent_test):
584
585 @classmethod
586 def setUpClass(cls): # noqa
587 pass
588
589 overrides_setup = OverridesSetup()
590 suite = unittest.TestSuite((overrides_setup,))
591 log = []
592 result = LoggingTestResult(log)
593 suite.run(result)
594 # Record 0, test (error holder). The error generates during test run.
595 self.assertIn('runTest', str(log[0][0]))
596 # Record 0, traceback
597 self.assertRegex(
598 str(log[0][2]['traceback']).replace('\n', ' '),
599 RuntimeError.__name__ + ': .* ' + OverridesSetup.__name__)
600
Balazs Gibizerdfb30432021-12-14 17:25:16 +0100601 @mock.patch.object(test.process_lock, 'InterProcessReaderWriterLock')
602 def test_serial_execution_if_requested(self, mock_lock):
603
604 @decorators.serial
605 class SerialTests(self.parent_test):
606 pass
607
608 class ParallelTests(self.parent_test):
609 pass
610
611 @decorators.serial
612 class SerialTests2(self.parent_test):
613 pass
614
615 suite = unittest.TestSuite(
616 (SerialTests(), ParallelTests(), SerialTests2()))
617 log = []
618 result = LoggingTestResult(log)
619 suite.run(result)
620
621 expected_lock_path = os.path.join(
622 lockutils.get_lock_path(CONF), 'tempest-serial-rw-lock')
623
624 # We except that each test class has a lock with the _same_ external
625 # path so that if they would run by different processes they would
626 # still use the same lock
627 # Also we expect that each serial class takes and releases the
628 # write-lock while each non-serial class takes and releases the
629 # read-lock.
630 self.assertEqual(
631 [
632 mock.call(expected_lock_path),
633 mock.call().acquire_write_lock(),
634 mock.call().release_write_lock(),
635
636 mock.call(expected_lock_path),
637 mock.call().acquire_read_lock(),
638 mock.call().release_read_lock(),
639
640 mock.call(expected_lock_path),
641 mock.call().acquire_write_lock(),
642 mock.call().release_write_lock(),
643 ],
644 mock_lock.mock_calls
645 )
646
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100647
648class TestTempestBaseTestClassFixtures(base.TestCase):
649
650 SETUP_FIXTURES = [test.BaseTestCase.setUpClass.__name__,
651 test.BaseTestCase.skip_checks.__name__,
652 test.BaseTestCase.setup_credentials.__name__,
653 test.BaseTestCase.setup_clients.__name__,
654 test.BaseTestCase.resource_setup.__name__]
655 TEARDOWN_FIXTURES = [test.BaseTestCase.tearDownClass.__name__,
656 test.BaseTestCase.resource_cleanup.__name__,
657 test.BaseTestCase.clear_credentials.__name__]
658
659 def setUp(self):
660 super(TestTempestBaseTestClassFixtures, self).setUp()
661 self.mocks = {}
662 for fix in self.SETUP_FIXTURES + self.TEARDOWN_FIXTURES:
663 self.mocks[fix] = mock.Mock()
664
665 def tracker_builder(name):
666
667 def tracker(cls):
668 # Track that the fixture was invoked
669 cls.fixtures_invoked.append(name)
670 # Run the fixture
671 getattr(super(TestWithClassFixtures, cls), name)()
672 # Run a mock we can use for side effects
673 self.mocks[name]()
674
675 return tracker
676
677 class TestWithClassFixtures(test.BaseTestCase):
678
679 credentials = []
680 fixtures_invoked = []
681
682 def runTest(_self):
683 pass
684
685 # Decorate all test class fixtures with tracker_builder
686 for method_name in self.SETUP_FIXTURES + self.TEARDOWN_FIXTURES:
687 setattr(TestWithClassFixtures, method_name,
688 classmethod(tracker_builder(method_name)))
689
690 self.test = TestWithClassFixtures()
691
692 def test_no_error_flow(self):
693 # If all setup fixtures are executed, all cleanup fixtures are
694 # executed too
695 suite = unittest.TestSuite((self.test,))
696 log = []
697 result = LoggingTestResult(log)
698 suite.run(result)
699 self.assertEqual(self.SETUP_FIXTURES + self.TEARDOWN_FIXTURES,
700 self.test.fixtures_invoked)
701
702 def test_skip_only(self):
703 # If a skip condition is hit in the test, no credentials or resource
704 # is provisioned / cleaned-up
Ghanshyam Manne64c78d2019-10-10 22:26:43 +0000705 self.mocks['skip_checks'].side_effect = (
706 testtools.TestCase.skipException())
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100707 suite = unittest.TestSuite((self.test,))
708 log = []
709 result = LoggingTestResult(log)
710 suite.run(result)
711 # If we trigger a skip condition, teardown is not invoked at all
Douglas Viroel7155fdf2019-10-01 13:34:52 -0300712 self.assertEqual((self.SETUP_FIXTURES[:2] +
713 [self.TEARDOWN_FIXTURES[0]]),
Andrea Frittoli (andreaf)08e42d42017-09-07 17:09:13 +0100714 self.test.fixtures_invoked)
715
716 def test_skip_credentials_fails(self):
717 expected_exc = 'sc exploded'
718 self.mocks['setup_credentials'].side_effect = Exception(expected_exc)
719 suite = unittest.TestSuite((self.test,))
720 log = []
721 result = LoggingTestResult(log)
722 suite.run(result)
723 # If setup_credentials explodes, we invoked teardown class and
724 # clear credentials, and re-raise
725 self.assertEqual((self.SETUP_FIXTURES[:3] +
726 [self.TEARDOWN_FIXTURES[i] for i in (0, 2)]),
727 self.test.fixtures_invoked)
728 found_exc = log[0][1][1]
729 self.assertIn(expected_exc, str(found_exc))
730
731 def test_skip_credentials_fails_clear_fails(self):
732 # If cleanup fails on failure, we log the exception and do not
733 # re-raise it. Note that since the exception happens outside of
734 # the Tempest test setUp, logging is not captured on the Tempest
735 # test side, it will be captured by the unit test instead.
736 expected_exc = 'sc exploded'
737 clear_exc = 'clear exploded'
738 self.mocks['setup_credentials'].side_effect = Exception(expected_exc)
739 self.mocks['clear_credentials'].side_effect = Exception(clear_exc)
740 suite = unittest.TestSuite((self.test,))
741 log = []
742 result = LoggingTestResult(log)
743 suite.run(result)
744 # If setup_credentials explodes, we invoked teardown class and
745 # clear credentials, and re-raise
746 self.assertEqual((self.SETUP_FIXTURES[:3] +
747 [self.TEARDOWN_FIXTURES[i] for i in (0, 2)]),
748 self.test.fixtures_invoked)
749 found_exc = log[0][1][1]
750 self.assertIn(expected_exc, str(found_exc))
751 # Since log capture depends on OS_LOG_CAPTURE, we can only assert if
752 # logging was captured
753 if os.environ.get('OS_LOG_CAPTURE'):
754 self.assertIn(clear_exc, self.log_fixture.logger.output)
755
756 def test_skip_credentials_clients_resources_credentials_clear_fails(self):
757 # If cleanup fails with no previous failure, we re-raise the exception.
758 expected_exc = 'clear exploded'
759 self.mocks['clear_credentials'].side_effect = Exception(expected_exc)
760 suite = unittest.TestSuite((self.test,))
761 log = []
762 result = LoggingTestResult(log)
763 suite.run(result)
764 # If setup_credentials explodes, we invoked teardown class and
765 # clear credentials, and re-raise
766 self.assertEqual(self.SETUP_FIXTURES + self.TEARDOWN_FIXTURES,
767 self.test.fixtures_invoked)
768 found_exc = log[0][1][1]
769 self.assertIn(expected_exc, str(found_exc))
770
771 def test_skip_credentials_clients_fails(self):
772 expected_exc = 'clients exploded'
773 self.mocks['setup_clients'].side_effect = Exception(expected_exc)
774 suite = unittest.TestSuite((self.test,))
775 log = []
776 result = LoggingTestResult(log)
777 suite.run(result)
778 # If setup_clients explodes, we invoked teardown class and
779 # clear credentials, and re-raise
780 self.assertEqual((self.SETUP_FIXTURES[:4] +
781 [self.TEARDOWN_FIXTURES[i] for i in (0, 2)]),
782 self.test.fixtures_invoked)
783 found_exc = log[0][1][1]
784 self.assertIn(expected_exc, str(found_exc))
785
786 def test_skip_credentials_clients_resources_fails(self):
787 expected_exc = 'resource setup exploded'
788 self.mocks['resource_setup'].side_effect = Exception(expected_exc)
789 suite = unittest.TestSuite((self.test,))
790 log = []
791 result = LoggingTestResult(log)
792 suite.run(result)
793 # If resource_setup explodes, we invoked teardown class and
794 # clear credentials and resource cleanup, and re-raise
795 self.assertEqual(self.SETUP_FIXTURES + self.TEARDOWN_FIXTURES,
796 self.test.fixtures_invoked)
797 found_exc = log[0][1][1]
798 self.assertIn(expected_exc, str(found_exc))
Ghanshyam Mann18b45d72021-12-07 12:37:29 -0600799
800
801class TestAPIMicroversionTest1(test.BaseTestCase):
802
Balazs Gibizerdfb30432021-12-14 17:25:16 +0100803 def __init__(self, *args, **kwargs):
804 super().__init__(*args, **kwargs)
805 self.useFixture(fake_config.ConfigFixture())
806 config.TempestConfigPrivate = fake_config.FakePrivate
807
Ghanshyam Mann18b45d72021-12-07 12:37:29 -0600808 @classmethod
809 def resource_setup(cls):
810 super(TestAPIMicroversionTest1, cls).resource_setup()
811 # Setting microvesions and checks that every tests
812 # of this class will have those microversion set
813 # on service clients requesting service APIs.
814 cls.setup_api_microversion_fixture(
815 compute_microversion='2.30',
816 volume_microversion='3.10',
817 placement_microversion='3.1')
818 # Check microvesion is set during resource_setup()
819 if base_compute_client.COMPUTE_MICROVERSION != '2.30':
820 raise testtools.TestCase.failureException(
821 "Microversion is not set in resource_setup method")
822 if base_volume_client.VOLUME_MICROVERSION != '3.10':
823 raise testtools.TestCase.failureException(
824 "Microversion is not set in resource_setup method")
825 if base_placement_client.PLACEMENT_MICROVERSION != '3.1':
826 raise testtools.TestCase.failureException(
827 "Microversion is not set in resource_setup method")
828
829 @classmethod
830 def resource_cleanup(cls):
831 super(TestAPIMicroversionTest1, cls).resource_cleanup()
832 # Check microversion is reset back to None in resource_cleanup()
833 if base_compute_client.COMPUTE_MICROVERSION is not None:
834 raise testtools.TestCase.failureException(
835 "Microversion is not reset to None in resource_cleanup method")
836 if base_volume_client.VOLUME_MICROVERSION is not None:
837 raise testtools.TestCase.failureException(
838 "Microversion is not reset to None in resource_cleanup method")
839 if base_placement_client.PLACEMENT_MICROVERSION is not None:
840 raise testtools.TestCase.failureException(
841 "Microversion is not reset to None in resource_cleanup method")
842
843 def setUp(self):
844 super(TestAPIMicroversionTest1, self).setUp()
845 # Check microversion is set in setUp method also.
846 self.assertEqual('2.30', base_compute_client.COMPUTE_MICROVERSION)
847 self.assertEqual('3.10', base_volume_client.VOLUME_MICROVERSION)
848 self.assertEqual('3.1', base_placement_client.PLACEMENT_MICROVERSION)
849
850 def tearDown(self):
851 super(TestAPIMicroversionTest1, self).tearDown()
852 # Check microversion is set in tearDown method also.
853 self.assertEqual('2.30', base_compute_client.COMPUTE_MICROVERSION)
854 self.assertEqual('3.10', base_volume_client.VOLUME_MICROVERSION)
855 self.assertEqual('3.1', base_placement_client.PLACEMENT_MICROVERSION)
856
857 def test_1(self):
858 self.assertEqual('2.30', base_compute_client.COMPUTE_MICROVERSION)
859 self.assertEqual('3.10', base_volume_client.VOLUME_MICROVERSION)
860 self.assertEqual('3.1', base_placement_client.PLACEMENT_MICROVERSION)
861
862 def test_2(self):
863 self.assertEqual('2.30', base_compute_client.COMPUTE_MICROVERSION)
864 self.assertEqual('3.10', base_volume_client.VOLUME_MICROVERSION)
865 self.assertEqual('3.1', base_placement_client.PLACEMENT_MICROVERSION)
866
867
868class TestAPIMicroversionTest2(test.BaseTestCase):
869
Balazs Gibizerdfb30432021-12-14 17:25:16 +0100870 def __init__(self, *args, **kwargs):
871 super().__init__(*args, **kwargs)
872 self.useFixture(fake_config.ConfigFixture())
873 config.TempestConfigPrivate = fake_config.FakePrivate
874
Ghanshyam Mann18b45d72021-12-07 12:37:29 -0600875 @classmethod
876 def resource_setup(cls):
877 super(TestAPIMicroversionTest2, cls).resource_setup()
878 # Setting microvesions different from what set in
879 # MicroversionTest1 and checks that every tests
880 # of this class will have the new microversion set
881 # on service clients requesting service APIs.
882 cls.setup_api_microversion_fixture(
883 compute_microversion='2.80',
884 volume_microversion='3.80',
885 placement_microversion='3.8')
886 # Check microvesion is set during resource_setup()
887 if base_compute_client.COMPUTE_MICROVERSION != '2.80':
888 raise testtools.TestCase.failureException(
889 "Microversion is not set in resource_setup method")
890 if base_volume_client.VOLUME_MICROVERSION != '3.80':
891 raise testtools.TestCase.failureException(
892 "Microversion is not set in resource_setup method")
893 if base_placement_client.PLACEMENT_MICROVERSION != '3.8':
894 raise testtools.TestCase.failureException(
895 "Microversion is not set in resource_setup method")
896
897 @classmethod
898 def resource_cleanup(cls):
899 super(TestAPIMicroversionTest2, cls).resource_cleanup()
900 # Check microversion is reset back to None in resource_cleanup()
901 if base_compute_client.COMPUTE_MICROVERSION is not None:
902 raise testtools.TestCase.failureException(
903 "Microversion is not reset to None in resource_cleanup method")
904 if base_volume_client.VOLUME_MICROVERSION is not None:
905 raise testtools.TestCase.failureException(
906 "Microversion is not reset to None in resource_cleanup method")
907 if base_placement_client.PLACEMENT_MICROVERSION is not None:
908 raise testtools.TestCase.failureException(
909 "Microversion is not reset to None in resource_cleanup method")
910
911 def setUp(self):
912 super(TestAPIMicroversionTest2, self).setUp()
913 # Check microversion is set in setUp method also.
914 self.assertEqual('2.80', base_compute_client.COMPUTE_MICROVERSION)
915 self.assertEqual('3.80', base_volume_client.VOLUME_MICROVERSION)
916 self.assertEqual('3.8', base_placement_client.PLACEMENT_MICROVERSION)
917
918 def tearDown(self):
919 super(TestAPIMicroversionTest2, self).tearDown()
920 # Check microversion is set in tearDown method also.
921 self.assertEqual('2.80', base_compute_client.COMPUTE_MICROVERSION)
922 self.assertEqual('3.80', base_volume_client.VOLUME_MICROVERSION)
923 self.assertEqual('3.8', base_placement_client.PLACEMENT_MICROVERSION)
924
925 def test_1(self):
926 self.assertEqual('2.80', base_compute_client.COMPUTE_MICROVERSION)
927 self.assertEqual('3.80', base_volume_client.VOLUME_MICROVERSION)
928 self.assertEqual('3.8', base_placement_client.PLACEMENT_MICROVERSION)
929
930 def test_2(self):
931 self.assertEqual('2.80', base_compute_client.COMPUTE_MICROVERSION)
932 self.assertEqual('3.80', base_volume_client.VOLUME_MICROVERSION)
933 self.assertEqual('3.8', base_placement_client.PLACEMENT_MICROVERSION)
934
935
936class TestAPIMicroversionTest3(test.BaseTestCase):
937
938 @classmethod
939 def resource_setup(cls):
940 super(TestAPIMicroversionTest3, cls).resource_setup()
941 # Not setting microversion for this test class so
942 # there should not be any micorversion set on service
943 # clients requesting services APIs.
944 # Check microvesion is not set during resource_setup()
945 if base_compute_client.COMPUTE_MICROVERSION is not None:
946 raise testtools.TestCase.failureException(
947 "Microversion is not set in resource_setup method")
948 if base_volume_client.VOLUME_MICROVERSION is not None:
949 raise testtools.TestCase.failureException(
950 "Microversion is not set in resource_setup method")
951 if base_placement_client.PLACEMENT_MICROVERSION is not None:
952 raise testtools.TestCase.failureException(
953 "Microversion is not set in resource_setup method")
954
955 @classmethod
956 def resource_cleanup(cls):
957 super(TestAPIMicroversionTest3, cls).resource_cleanup()
958 # Check microversion is set to None in resource_cleanup()
959 if base_compute_client.COMPUTE_MICROVERSION is not None:
960 raise testtools.TestCase.failureException(
961 "Microversion is not reset to None in resource_cleanup method")
962 if base_volume_client.VOLUME_MICROVERSION is not None:
963 raise testtools.TestCase.failureException(
964 "Microversion is not reset to None in resource_cleanup method")
965 if base_placement_client.PLACEMENT_MICROVERSION is not None:
966 raise testtools.TestCase.failureException(
967 "Microversion is not reset to None in resource_cleanup method")
968
969 def setUp(self):
970 super(TestAPIMicroversionTest3, self).setUp()
971 # Check microversion is None in setUp method also.
972 self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
973 self.assertIsNone(base_volume_client.VOLUME_MICROVERSION)
974 self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
975
976 def tearDown(self):
977 super(TestAPIMicroversionTest3, self).tearDown()
978 # Check microversion is None in tearDown method also.
979 self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
980 self.assertIsNone(base_volume_client.VOLUME_MICROVERSION)
981 self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
982
983 def test_1(self):
984 self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
985 self.assertIsNone(base_volume_client.VOLUME_MICROVERSION)
986 self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
987
988 def test_2(self):
989 self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
990 self.assertIsNone(base_volume_client.VOLUME_MICROVERSION)
991 self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)