From 49a7e57f112d855b0609721b6082b15a94417380 Mon Sep 17 00:00:00 2001 From: Cédric Ollivier Date: Tue, 23 May 2017 20:58:42 +0200 Subject: Define create_snapshot() and clean() in TestCase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They replace the former calls in run_tests which are not suitable for all test cases. Now any test case can define how to clean its resources. If the snapshot cannot be created, the test case is considered as failed. Only a message is printed if any failure during cleaning. It also defines a new class called OSGCTestCase useful for test cases which don't clean their OpenStack resources. All test cases located in opnfv_tests/openstack inherit from it to keep the global behavior unchanged. It also deletes exit instructions in openstack_clean and openstack_snapshot, removes clean flags in testcases.yaml and updates the related utils. All Docs are modified as well. JIRA: FUNCTEST-438 Change-Id: I8938e6255708012380389763a24059ace4ce45d8 Signed-off-by: Cédric Ollivier --- functest/ci/run_tests.py | 50 ++++++++++------------ functest/ci/testcases.yaml | 33 -------------- functest/ci/tier_builder.py | 1 - functest/ci/tier_handler.py | 5 --- functest/core/testcase.py | 50 ++++++++++++++++++++++ functest/opnfv_tests/openstack/rally/rally.py | 2 +- .../openstack/refstack_client/refstack_client.py | 2 +- functest/opnfv_tests/openstack/tempest/tempest.py | 2 +- functest/opnfv_tests/openstack/vping/vping_base.py | 10 ++--- functest/tests/unit/ci/test_run_tests.py | 27 +++++------- functest/tests/unit/ci/test_tier_builder.py | 1 - functest/tests/unit/ci/test_tier_handler.py | 1 - functest/tests/unit/core/test_testcase.py | 49 +++++++++++++++++++++ functest/utils/openstack_clean.py | 10 ++--- functest/utils/openstack_snapshot.py | 5 ++- 15 files changed, 148 insertions(+), 100 deletions(-) (limited to 'functest') diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py index 8317df541..9e64196ed 100755 --- a/functest/ci/run_tests.py +++ b/functest/ci/run_tests.py @@ -22,8 +22,6 @@ import prettytable import functest.ci.tier_builder as tb import functest.core.testcase as testcase import functest.utils.functest_utils as ft_utils -import functest.utils.openstack_clean as os_clean -import functest.utils.openstack_snapshot as os_snapshot import functest.utils.openstack_utils as os_utils from functest.utils.constants import CONST @@ -97,14 +95,6 @@ class Runner(object): elif key == 'OS_PASSWORD': CONST.__setattr__('OS_PASSWORD', value) - @staticmethod - def generate_os_snapshot(): - os_snapshot.main() - - @staticmethod - def cleanup(): - os_clean.main() - @staticmethod def get_run_dict(testname): try: @@ -124,14 +114,11 @@ class Runner(object): "The test case {} is not enabled".format(test.get_name())) logger.info("\n") # blank line self.print_separator("=") - logger.info("Running test case '%s'..." % test.get_name()) + logger.info("Running test case '%s'...", test.get_name()) self.print_separator("=") logger.debug("\n%s" % test) self.source_rc_file() - if test.needs_clean() and self.clean_flag: - self.generate_os_snapshot() - flags = " -t %s" % test.get_name() if self.report_flag: flags += " -r" @@ -145,6 +132,9 @@ class Runner(object): test_dict = ft_utils.get_dict_by_test(test.get_name()) test_case = cls(**test_dict) self.executed_test_cases.append(test_case) + if self.clean_flag: + if test_case.create_snapshot() != test_case.EX_OK: + return result try: kwargs = run_dict['args'] result = test_case.run(**kwargs) @@ -155,6 +145,8 @@ class Runner(object): test_case.push_to_db() result = test_case.is_successful() logger.info("Test result:\n\n%s\n", test_case) + if self.clean_flag: + test_case.clean() except ImportError: logger.exception("Cannot import module {}".format( run_dict['module'])) @@ -164,15 +156,7 @@ class Runner(object): else: raise Exception("Cannot import the class for the test case.") - if test.needs_clean() and self.clean_flag: - self.cleanup() - if result != testcase.TestCase.EX_OK: - logger.error("The test case '%s' failed. " % test.get_name()) - self.overall_result = Result.EX_ERROR - if test.is_blocking(): - raise BlockingTestFailed( - "The test case {} failed and is blocking".format( - test.get_name())) + return result def run_tier(self, tier): tier_name = tier.get_name() @@ -187,7 +171,14 @@ class Runner(object): self.print_separator("#") logger.debug("\n%s" % tier) for test in tests: - self.run_test(test, tier_name) + result = self.run_test(test, tier_name) + if result != testcase.TestCase.EX_OK: + logger.error("The test case '%s' failed.", test.get_name()) + self.overall_result = Result.EX_ERROR + if test.is_blocking(): + raise BlockingTestFailed( + "The test case {} failed and is blocking".format( + test.get_name())) def run_all(self, tiers): summary = "" @@ -225,9 +216,14 @@ class Runner(object): if _tiers.get_tier(kwargs['test']): self.run_tier(_tiers.get_tier(kwargs['test'])) elif _tiers.get_test(kwargs['test']): - self.run_test(_tiers.get_test(kwargs['test']), - _tiers.get_tier_name(kwargs['test']), - kwargs['test']) + result = self.run_test( + _tiers.get_test(kwargs['test']), + _tiers.get_tier_name(kwargs['test']), + kwargs['test']) + if result != testcase.TestCase.EX_OK: + logger.error("The test case '%s' failed.", + kwargs['test']) + self.overall_result = Result.EX_ERROR elif kwargs['test'] == "all": self.run_all(_tiers) else: diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index 8222df102..7d518324e 100644 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -12,7 +12,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: false description: >- This test case verifies the retrieval of OpenStack clients: Keystone, Glance, Neutron and Nova and may perform some @@ -31,7 +30,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: false description: >- This test case verifies the retrieval of OpenStack clients: Keystone, Glance, Neutron and Nova and may perform some @@ -50,7 +48,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: false description: >- This test case creates executes the SimpleHealthCheck Python test class which creates an, image, flavor, network, @@ -75,7 +72,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: true description: >- This test case verifies: 1) SSH to an instance using floating IPs over the public network. 2) Connectivity between 2 instances @@ -92,7 +88,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: true description: >- This test case verifies: 1) Boot a VM with given userdata. 2) Connectivity between 2 instances over a private network. @@ -108,7 +103,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- This test case runs the smoke subset of the OpenStack Tempest suite. The list of test cases is generated by @@ -126,7 +120,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: false description: >- This test case runs a sub group of tests of the OpenStack Rally suite in smoke mode. @@ -142,7 +135,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- This test case runs a sub group of tests of the OpenStack Defcore testcases by using refstack client. @@ -158,7 +150,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: false description: >- Test Suite for the OpenDaylight SDN Controller. It integrates some test suites from upstream using @@ -179,7 +170,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: false description: >- Test Suite for the OpenDaylight SDN Controller when the NetVirt features are installed. It integrates @@ -202,7 +192,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: false description: >- Test Suite for the OpenDaylight SDN Controller when GBP features are installed. It integrates some test suites from upstream using @@ -222,7 +211,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: true description: >- Test Suite for the ONOS SDN Controller. It integrates some test suites from upstream using TestON as the test @@ -239,7 +227,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: false description: >- This test case contains tests that setup and destroy environments with VMs with and without Floating IPs @@ -269,7 +256,6 @@ tiers: project_name: promise criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Promise project. dependencies: @@ -287,7 +273,6 @@ tiers: project_name: doctor criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Doctor project. dependencies: @@ -304,7 +289,6 @@ tiers: project_name: sdnvpn criteria: 100 blocking: false - clean_flag: true description: >- Test suite from SDNVPN project. dependencies: @@ -322,7 +306,6 @@ tiers: project_name: securityscanning criteria: 100 blocking: false - clean_flag: true description: >- Simple Security Scan dependencies: @@ -340,7 +323,6 @@ tiers: project_name: copper criteria: 100 blocking: false - clean_flag: true description: >- Test suite for policy management based on OpenStack Congress dependencies: @@ -358,7 +340,6 @@ tiers: project_name: multisite criteria: 100 blocking: false - clean_flag: false description: >- Test suite from kingbird dependencies: @@ -374,7 +355,6 @@ tiers: project_name: sfc criteria: 100 blocking: false - clean_flag: true description: >- Test suite for odl-sfc to test two chains and two SFs dependencies: @@ -392,7 +372,6 @@ tiers: project_name: functest criteria: 100 blocking: true - clean_flag: true description: >- Test Suite for onos-sfc to test sfc function. dependencies: @@ -408,7 +387,6 @@ tiers: project_name: parser criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Parser project. dependencies: @@ -426,7 +404,6 @@ tiers: project_name: domino criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Domino project. dependencies: @@ -444,7 +421,6 @@ tiers: project_name: netready criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Netready project. dependencies: @@ -462,7 +438,6 @@ tiers: project_name: barometer criteria: 100 blocking: false - clean_flag: true description: >- Test suite for the Barometer project. Separate tests verify the proper configuration and functionality of the following @@ -487,7 +462,6 @@ tiers: project_name: functest criteria: 80 blocking: false - clean_flag: true description: >- The list of test cases is generated by Tempest automatically and depends on the parameters of @@ -504,7 +478,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- The test case allows running a customized list of tempest test cases defined in a file under @@ -523,7 +496,6 @@ tiers: project_name: functest criteria: 90 blocking: false - clean_flag: false description: >- This test case runs the full suite of scenarios of the OpenStack Rally suite using several threads and iterations. @@ -546,7 +518,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- This test case deploys an OpenSource vIMS solution from Clearwater using the Cloudify orchestrator. It also runs some signaling traffic. @@ -563,7 +534,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- Test suite from Parser project. dependencies: @@ -579,7 +549,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- VNF deployment with OpenBaton (Orchestra) dependencies: @@ -595,7 +564,6 @@ tiers: project_name: opera criteria: 100 blocking: false - clean_flag: true description: >- VNF deployment with OPEN-O dependencies: @@ -611,7 +579,6 @@ tiers: project_name: functest criteria: 100 blocking: false - clean_flag: true description: >- This test case is vRouter testing. dependencies: diff --git a/functest/ci/tier_builder.py b/functest/ci/tier_builder.py index d03cd9032..f8038468f 100644 --- a/functest/ci/tier_builder.py +++ b/functest/ci/tier_builder.py @@ -52,7 +52,6 @@ class TierBuilder(object): dependency=dep, criteria=dic_testcase['criteria'], blocking=dic_testcase['blocking'], - clean_flag=dic_testcase['clean_flag'], description=dic_testcase['description']) if (testcase.is_compatible(self.ci_installer, self.ci_scenario) and diff --git a/functest/ci/tier_handler.py b/functest/ci/tier_handler.py index 36ce245e7..4f2f14ecd 100644 --- a/functest/ci/tier_handler.py +++ b/functest/ci/tier_handler.py @@ -109,14 +109,12 @@ class TestCase(object): dependency, criteria, blocking, - clean_flag, description=""): self.name = name self.enabled = enabled self.dependency = dependency self.criteria = criteria self.blocking = blocking - self.clean_flag = clean_flag self.description = description @staticmethod @@ -149,9 +147,6 @@ class TestCase(object): def is_blocking(self): return self.blocking - def needs_clean(self): - return self.clean_flag - def __str__(self): lines = split_text(self.description, LINE_LENGTH - 6) diff --git a/functest/core/testcase.py b/functest/core/testcase.py index 431615250..50ca2ce44 100644 --- a/functest/core/testcase.py +++ b/functest/core/testcase.py @@ -15,6 +15,8 @@ import os import prettytable import functest.utils.functest_utils as ft_utils +import functest.utils.openstack_clean as os_clean +import functest.utils.openstack_snapshot as os_snapshot __author__ = "Cedric Ollivier " @@ -176,3 +178,51 @@ class TestCase(object): except Exception: # pylint: disable=broad-except self.__logger.exception("The results cannot be pushed to DB") return TestCase.EX_PUSH_TO_DB_ERROR + + def create_snapshot(self): # pylint: disable=no-self-use + """Save the testing environement before running test. + + It can be overriden if resources must be listed running the + test case. + + Returns: + TestCase.EX_OK + """ + return TestCase.EX_OK + + def clean(self): + """Clean the resources. + + It can be overriden if resources must be deleted after + running the test case. + """ + + +class OSGCTestCase(TestCase): + """Model for single test case which requires an OpenStack Garbage + Collector.""" + + __logger = logging.getLogger(__name__) + + def create_snapshot(self): + """Create a snapshot listing the OpenStack resources. + + Returns: + TestCase.EX_OK if os_snapshot.main() returns 0. + TestCase.EX_RUN_ERROR otherwise. + """ + try: + assert os_snapshot.main() == 0 + self.__logger.info("OpenStack resources snapshot created") + return TestCase.EX_OK + except Exception: # pylint: disable=broad-except + self.__logger.exception("Cannot create the snapshot") + return TestCase.EX_RUN_ERROR + + def clean(self): + """Clean the OpenStack resources.""" + try: + assert os_clean.main() == 0 + self.__logger.info("OpenStack resources cleaned") + except Exception: # pylint: disable=broad-except + self.__logger.exception("Cannot clean the OpenStack resources") diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index 86ec35584..97e2444a7 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -27,7 +27,7 @@ import functest.utils.openstack_utils as os_utils logger = logging.getLogger(__name__) -class RallyBase(testcase.TestCase): +class RallyBase(testcase.OSGCTestCase): TESTS = ['authenticate', 'glance', 'cinder', 'heat', 'keystone', 'neutron', 'nova', 'quotas', 'requests', 'vm', 'all'] GLANCE_IMAGE_NAME = CONST.__getattribute__('openstack_image_name') diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py index 5f1f3a1dd..b2a215337 100755 --- a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py +++ b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py @@ -27,7 +27,7 @@ from tempest_conf import TempestConf logger = logging.getLogger(__name__) -class RefstackClient(testcase.TestCase): +class RefstackClient(testcase.OSGCTestCase): def __init__(self, **kwargs): if "case_name" not in kwargs: diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index f5f194e67..99425af54 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -28,7 +28,7 @@ import functest.utils.functest_utils as ft_utils logger = logging.getLogger(__name__) -class TempestCommon(testcase.TestCase): +class TempestCommon(testcase.OSGCTestCase): def __init__(self, **kwargs): super(TempestCommon, self).__init__(**kwargs) diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py index 8e71bf82c..099f26b7a 100644 --- a/functest/opnfv_tests/openstack/vping/vping_base.py +++ b/functest/opnfv_tests/openstack/vping/vping_base.py @@ -13,7 +13,7 @@ import os import time import uuid -from functest.core.testcase import TestCase +from functest.core import testcase from functest.utils import functest_utils from functest.utils.constants import CONST @@ -24,7 +24,7 @@ from snaps.openstack.tests import openstack_tests from snaps.openstack.utils import deploy_utils, nova_utils -class VPingBase(TestCase): +class VPingBase(testcase.OSGCTestCase): """ Base class for vPing tests that check connectivity between two VMs shared @@ -152,12 +152,12 @@ class VPingBase(TestCase): else: raise Exception('VMs never became active') - if result == TestCase.EX_RUN_ERROR: - return TestCase.EX_RUN_ERROR + if result == testcase.TestCase.EX_RUN_ERROR: + return testcase.TestCase.EX_RUN_ERROR self.stop_time = time.time() self.result = 100 - return TestCase.EX_OK + return testcase.TestCase.EX_OK def _cleanup(self): """ diff --git a/functest/tests/unit/ci/test_run_tests.py b/functest/tests/unit/ci/test_run_tests.py index 88e5d2b86..fb8cb3915 100644 --- a/functest/tests/unit/ci/test_run_tests.py +++ b/functest/tests/unit/ci/test_run_tests.py @@ -38,8 +38,12 @@ class RunTestsTesting(unittest.TestCase): 'OS_PASSWORD': 'test_password'} self.test = {'test_name': 'test_name'} self.tier = mock.Mock() + test1 = mock.Mock() + test1.get_name.return_value = 'test1' + test2 = mock.Mock() + test2.get_name.return_value = 'test2' attrs = {'get_name.return_value': 'test_tier', - 'get_tests.return_value': ['test1', 'test2'], + 'get_tests.return_value': [test1, test2], 'get_ci_loop.return_value': 'test_ci_loop', 'get_test_names.return_value': ['test1', 'test2']} self.tier.configure_mock(**attrs) @@ -70,16 +74,6 @@ class RunTestsTesting(unittest.TestCase): return_value=self.creds): self.runner.source_rc_file() - @mock.patch('functest.ci.run_tests.os_snapshot.main') - def test_generate_os_snapshot(self, mock_os_snap): - self.runner.generate_os_snapshot() - self.assertTrue(mock_os_snap.called) - - @mock.patch('functest.ci.run_tests.os_clean.main') - def test_cleanup(self, mock_os_clean): - self.runner.cleanup() - self.assertTrue(mock_os_clean.called) - def test_get_run_dict_if_defined_default(self): mock_obj = mock.Mock() with mock.patch('functest.ci.run_tests.' @@ -137,8 +131,6 @@ class RunTestsTesting(unittest.TestCase): @mock.patch('functest.ci.run_tests.Runner.print_separator') @mock.patch('functest.ci.run_tests.Runner.source_rc_file') - @mock.patch('functest.ci.run_tests.Runner.generate_os_snapshot') - @mock.patch('functest.ci.run_tests.Runner.cleanup') @mock.patch('importlib.import_module', name="module", return_value=mock.Mock(test_class=mock.Mock( side_effect=FakeModule))) @@ -161,10 +153,10 @@ class RunTestsTesting(unittest.TestCase): def test_run_tier_default(self, mock_logger_info): with mock.patch('functest.ci.run_tests.Runner.print_separator'), \ mock.patch( - 'functest.ci.run_tests.Runner.run_test') as mock_method: + 'functest.ci.run_tests.Runner.run_test', + return_value=TestCase.EX_OK) as mock_method: self.runner.run_tier(self.tier) - mock_method.assert_any_call('test1', 'test_tier') - mock_method.assert_any_call('test2', 'test_tier') + mock_method.assert_any_call(mock.ANY, 'test_tier') self.assertTrue(mock_logger_info.called) @mock.patch('functest.ci.run_tests.logger.info') @@ -237,7 +229,8 @@ class RunTestsTesting(unittest.TestCase): with mock.patch('functest.ci.run_tests.tb.TierBuilder', return_value=mock_obj), \ mock.patch('functest.ci.run_tests.Runner.source_rc_file'), \ - mock.patch('functest.ci.run_tests.Runner.run_test') as m: + mock.patch('functest.ci.run_tests.Runner.run_test', + return_value=TestCase.EX_OK) as m: self.assertEqual(self.runner.main(**kwargs), run_tests.Result.EX_OK) self.assertTrue(m.called) diff --git a/functest/tests/unit/ci/test_tier_builder.py b/functest/tests/unit/ci/test_tier_builder.py index 989c0870f..ab75e15b9 100644 --- a/functest/tests/unit/ci/test_tier_builder.py +++ b/functest/tests/unit/ci/test_tier_builder.py @@ -24,7 +24,6 @@ class TierBuilderTesting(unittest.TestCase): 'case_name': 'test_name', 'criteria': 'test_criteria', 'blocking': 'test_blocking', - 'clean_flag': 'test_clean_flag', 'description': 'test_desc'} self.dic_tier = {'name': 'test_tier', diff --git a/functest/tests/unit/ci/test_tier_handler.py b/functest/tests/unit/ci/test_tier_handler.py index c93fffd36..1909ac222 100644 --- a/functest/tests/unit/ci/test_tier_handler.py +++ b/functest/tests/unit/ci/test_tier_handler.py @@ -34,7 +34,6 @@ class TierHandlerTesting(unittest.TestCase): self.mock_depend, 'test_criteria', 'test_blocking', - 'test_clean_flag', description='test_desc') self.dependency = tier_handler.Dependency('test_installer', diff --git a/functest/tests/unit/core/test_testcase.py b/functest/tests/unit/core/test_testcase.py index ef0983cc0..0a6f0c9f4 100644 --- a/functest/tests/unit/core/test_testcase.py +++ b/functest/tests/unit/core/test_testcase.py @@ -221,6 +221,55 @@ class TestCaseTesting(unittest.TestCase): self.assertIn(duration, message) self.assertIn('FAIL', message) + def test_create_snapshot(self): + self.assertEqual(self.test.create_snapshot(), + testcase.TestCase.EX_OK) + + def test_clean(self): + self.assertEqual(self.test.clean(), None) + + +class OSGCTestCaseTesting(unittest.TestCase): + """The class testing OSGCTestCase.""" + # pylint: disable=missing-docstring + + def setUp(self): + self.test = testcase.OSGCTestCase() + + @mock.patch('functest.utils.openstack_snapshot.main', + side_effect=Exception) + def test_create_snapshot_exc(self, mock_method=None): + self.assertEqual(self.test.create_snapshot(), + testcase.TestCase.EX_RUN_ERROR) + mock_method.assert_called_once_with() + + @mock.patch('functest.utils.openstack_snapshot.main', return_value=-1) + def test_create_snapshot_ko(self, mock_method=None): + self.assertEqual(self.test.create_snapshot(), + testcase.TestCase.EX_RUN_ERROR) + mock_method.assert_called_once_with() + + @mock.patch('functest.utils.openstack_snapshot.main', return_value=0) + def test_create_snapshot_env(self, mock_method=None): + self.assertEqual(self.test.create_snapshot(), + testcase.TestCase.EX_OK) + mock_method.assert_called_once_with() + + @mock.patch('functest.utils.openstack_clean.main', side_effect=Exception) + def test_clean_exc(self, mock_method=None): + self.assertEqual(self.test.clean(), None) + mock_method.assert_called_once_with() + + @mock.patch('functest.utils.openstack_clean.main', return_value=-1) + def test_clean_ko(self, mock_method=None): + self.assertEqual(self.test.clean(), None) + mock_method.assert_called_once_with() + + @mock.patch('functest.utils.openstack_clean.main', return_value=0) + def test_clean(self, mock_method=None): + self.assertEqual(self.test.clean(), None) + mock_method.assert_called_once_with() + if __name__ == "__main__": logging.disable(logging.CRITICAL) diff --git a/functest/utils/openstack_clean.py b/functest/utils/openstack_clean.py index 29106d9ed..cdd918521 100755 --- a/functest/utils/openstack_clean.py +++ b/functest/utils/openstack_clean.py @@ -22,9 +22,9 @@ # http://www.apache.org/licenses/LICENSE-2.0 # -import time - import logging +import sys +import time import yaml import functest.utils.openstack_utils as os_utils @@ -392,7 +392,7 @@ def main(): except Exception: logger.info("The file %s does not exist. The OpenStack snapshot must" " be created first. Aborting cleanup." % OS_SNAPSHOT_FILE) - exit(0) + return 0 default_images = snapshot_yaml.get('images') default_instances = snapshot_yaml.get('instances') @@ -407,7 +407,7 @@ def main(): if not os_utils.check_credentials(): logger.error("Please source the openrc credentials and run " "the script again.") - exit(-1) + return -1 remove_instances(nova_client, default_instances) separator() @@ -429,4 +429,4 @@ def main(): if __name__ == '__main__': logging.basicConfig() - main() + sys.exit(main()) diff --git a/functest/utils/openstack_snapshot.py b/functest/utils/openstack_snapshot.py index 952fb7bbb..8f1d3b9b2 100755 --- a/functest/utils/openstack_snapshot.py +++ b/functest/utils/openstack_snapshot.py @@ -22,6 +22,7 @@ import logging import yaml +import sys import functest.utils.openstack_utils as os_utils from functest.utils.constants import CONST @@ -139,7 +140,7 @@ def main(): if not os_utils.check_credentials(): logger.error("Please source the openrc credentials and run the" + "script again.") - exit(-1) + return -1 snapshot = {} snapshot.update(get_instances(nova_client)) @@ -163,4 +164,4 @@ def main(): if __name__ == '__main__': logging.basicConfig() - main() + sys.exit(main()) -- cgit 1.2.3-korg