run() returns the expected status code (see following JIRA tickets).
repo, pre() and post() are removed as they were quite useless.
A dedicated class is proposed for bash programs.
Unit tests have been added to fully cover this module.
All features have been modified to conform with these modifications.
It also removes the decorators which skipped several unit tests.
JIRA: FUNCTEST-778
JIRA: FUNCTEST-779
JIRA: FUNCTEST-780
JIRA: FUNCTEST-781
Change-Id: Ifb1e4c4f68260a4e20d895f67f07f369ca959374
Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
import time
-import testcase as base
+import functest.core.testcase as base
import functest.utils.functest_utils as ft_utils
import functest.utils.functest_logger as ft_logger
from functest.utils.constants import CONST
def __init__(self, **kwargs):
super(Feature, self).__init__(**kwargs)
self.cmd = kwargs.get('cmd', '')
- repo = kwargs.get('repo', '')
- self.repo = CONST.__getattribute__(repo)
- self.result_file = self.get_result_file()
+ self.result_file = "{}/{}.log".format(
+ CONST.__getattribute__('dir_results'), self.project_name)
self.logger = ft_logger.Logger(self.project_name).getLogger()
+ def execute(self, **kwargs):
+ return -1
+
def run(self, **kwargs):
- self.prepare()
self.start_time = time.time()
- ret = self.execute()
+ exit_code = base.TestCase.EX_RUN_ERROR
+ self.criteria = "FAIL"
+ try:
+ if self.execute() == 0:
+ exit_code = base.TestCase.EX_OK
+ self.criteria = 'PASS'
+ ft_utils.logger_test_results(
+ self.project_name, self.case_name,
+ self.criteria, self.details)
+ self.logger.info("%s %s", self.project_name, self.criteria)
+ except Exception: # pylint: disable=broad-except
+ self.logger.exception("%s FAILED", self.project_name)
+ self.logger.info("Test result is stored in '%s'", self.result_file)
self.stop_time = time.time()
- self.post()
- self.parse_results(ret)
- self.log_results()
- self.logger.info("Test result is stored in '%s'" % self.result_file)
- return base.TestCase.EX_OK
-
- def execute(self):
- '''
- Executer method that can be overwritten
- By default it executes a shell command.
- '''
- return ft_utils.execute_command(self.cmd, output_file=self.result_file)
-
- def prepare(self, **kwargs):
- pass
-
- def post(self, **kwargs):
- pass
-
- def parse_results(self, ret):
- exit_code = base.TestCase.EX_OK
- if ret == 0:
- self.logger.info("{} OK".format(self.project_name))
- self.criteria = 'PASS'
- else:
- self.logger.info("{} FAILED".format(self.project_name))
- exit_code = base.TestCase.EX_RUN_ERROR
- self.criteria = "FAIL"
-
return exit_code
- def get_result_file(self):
- return "{}/{}.log".format(CONST.dir_results, self.project_name)
- def log_results(self):
- ft_utils.logger_test_results(self.project_name,
- self.case_name,
- self.criteria,
- self.details)
+class BashFeature(Feature):
+
+ def execute(self, **kwargs):
+ return ft_utils.execute_command(
+ self.cmd, output_file=self.result_file)
'''
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_barometer'
super(BarometerCollectd, self).__init__(**kwargs)
def execute(self):
# limitations under the License.
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class Copper(base.Feature):
+class Copper(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_copper'
+ repo = CONST.__getattribute__('dir_repo_copper')
+ kwargs["cmd"] = 'cd %s/tests && bash run.sh && cd -' % repo
super(Copper, self).__init__(**kwargs)
- self.cmd = 'cd %s/tests && bash run.sh && cd -' % self.repo
#
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class Doctor(base.Feature):
+class Doctor(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_doctor'
+ repo = CONST.__getattribute__('dir_repo_doctor')
+ kwargs["cmd"] = 'cd %s/tests && ./run.sh' % repo
super(Doctor, self).__init__(**kwargs)
- self.cmd = 'cd %s/tests && ./run.sh' % self.repo
# 0.4: refactoring to match Test abstraction class
import functest.core.feature as base
+from functest.utils.constants import CONST
-class Domino(base.Feature):
+class Domino(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_domino'
+ repo = CONST.__getattribute__('dir_repo_domino')
+ kwargs["cmd"] = 'cd %s && ./tests/run_multinode.sh' % repo
super(Domino, self).__init__(**kwargs)
- self.cmd = 'cd %s && ./tests/run_multinode.sh' % self.repo
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class GluonVping(base.Feature):
+class GluonVping(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_netready'
+ repo = CONST.__getattribute__('dir_repo_netready')
+ dir_netready_functest = '{}/test/functest'.format(repo)
+ kwargs["cmd"] = ('cd %s && python ./gluon-test-suite.py' %
+ dir_netready_functest)
super(GluonVping, self).__init__(**kwargs)
- dir_netready_functest = '{}/test/functest'.format(self.repo)
- self.cmd = ('cd %s && python ./gluon-test-suite.py' %
- dir_netready_functest)
# http://www.apache.org/licenses/LICENSE-2.0
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class OpenDaylightSFC(base.Feature):
+class OpenDaylightSFC(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_sfc'
+ repo = CONST.__getattribute__('dir_repo_sfc')
+ dir_sfc_functest = '{}/sfc/tests/functest'.format(repo)
+ kwargs["cmd"] = 'cd %s && python ./run_tests.py' % dir_sfc_functest
super(OpenDaylightSFC, self).__init__(**kwargs)
- dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo)
- self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
# limitations under the License.
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class Promise(base.Feature):
+class Promise(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_promise'
+ repo = CONST.__getattribute__('dir_repo_promise')
+ dir_promise_functest = '{}/promise/test/functest'.format(repo)
+ kwargs["cmd"] = 'cd %s && python ./run_tests.py' % dir_promise_functest
super(Promise, self).__init__(**kwargs)
- dir_promise_functest = '{}/promise/test/functest'.format(self.repo)
- self.cmd = 'cd %s && python ./run_tests.py' % dir_promise_functest
# http://www.apache.org/licenses/LICENSE-2.0
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class SdnVpnTests(base.Feature):
+class SdnVpnTests(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_sdnvpn'
+ repo = CONST.__getattribute__('dir_repo_sdnvpn')
+ dir_sfc_functest = '{}/sdnvpn/test/functest'.format(repo)
+ kwargs["cmd"] = 'cd %s && python ./run_tests.py' % dir_sfc_functest
super(SdnVpnTests, self).__init__(**kwargs)
- dir_sfc_functest = '{}/sdnvpn/test/functest'.format(self.repo)
- self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
from functest.utils.constants import CONST
-class SecurityScan(base.Feature):
+class SecurityScan(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_securityscan'
+ repo = CONST.__getattribute__('dir_repo_securityscan')
+ conf = CONST.__getattribute__('dir_functest_conf')
+ kwargs["cmd"] = ('. {0}/stackrc && '
+ 'cd {1} && '
+ 'python security_scan.py --config config.ini && '
+ 'cd -'.format(conf, repo))
super(SecurityScan, self).__init__(**kwargs)
- self.cmd = ('. {0}/stackrc && '
- 'cd {1} && '
- 'python security_scan.py --config config.ini && '
- 'cd -'.format(CONST.dir_functest_conf,
- self.repo))
#
import functest.core.feature as base
+from functest.utils.constants import CONST
-class Parser(base.Feature):
+class Parser(base.BashFeature):
def __init__(self, **kwargs):
- kwargs["repo"] = 'dir_repo_parser'
+ repo = CONST.__getattribute__('dir_repo_parser')
+ kwargs["cmd"] = 'cd %s/tests && ./functest_run.sh' % repo
super(Parser, self).__init__(**kwargs)
- self.cmd = 'cd %s/tests && ./functest_run.sh' % self.repo
from functest.core import feature
from functest.core import testcase
-from functest.utils import constants
+logging.disable(logging.CRITICAL)
-class FeatureInitTesting(unittest.TestCase):
- logging.disable(logging.CRITICAL)
+class FeatureTestingBase(unittest.TestCase):
- @unittest.skip("JIRA: FUNCTEST-780")
- def test_init_with_wrong_repo(self):
- with self.assertRaises(ValueError):
- feature.Feature(repo='foo')
+ _case_name = "foo"
+ _project_name = "bar"
+ _repo = "dir_repo_copper"
+ _cmd = "cd /home/opnfv/repos/foo/tests && bash run.sh && cd -"
+ _output_file = '/home/opnfv/functest/results/bar.log'
- def test_init(self):
- barometer = feature.Feature(repo='dir_repo_barometer')
- self.assertEqual(barometer.project_name, "functest")
- self.assertEqual(barometer.case_name, "")
- self.assertEqual(
- barometer.repo,
- constants.CONST.__getattribute__('dir_repo_barometer'))
+ @mock.patch('time.time', side_effect=[1, 2])
+ def _test_run(self, status, mock_method=None):
+ self.assertEqual(self.feature.run(), status)
+ if status == testcase.TestCase.EX_OK:
+ self.assertEqual(self.feature.criteria, 'PASS')
+ else:
+ self.assertEqual(self.feature.criteria, 'FAIL')
+ mock_method.assert_has_calls([mock.call(), mock.call()])
+ self.assertEqual(self.feature.start_time, 1)
+ self.assertEqual(self.feature.stop_time, 2)
-class FeatureTesting(unittest.TestCase):
-
- logging.disable(logging.CRITICAL)
+class FeatureTesting(FeatureTestingBase):
def setUp(self):
- self.feature = feature.Feature(repo='dir_repo_barometer')
-
- @unittest.skip("JIRA: FUNCTEST-781")
- def test_prepare_ko(self):
- # pylint: disable=bad-continuation
- with mock.patch.object(
- self.feature, 'prepare',
- return_value=testcase.TestCase.EX_RUN_ERROR) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
-
- @unittest.skip("JIRA: FUNCTEST-781")
- def test_prepare_exc(self):
- with mock.patch.object(self.feature, 'prepare',
- side_effect=Exception) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
-
- @unittest.skip("JIRA: FUNCTEST-781")
- def test_post_ko(self):
- # pylint: disable=bad-continuation
- with mock.patch.object(
- self.feature, 'post',
- return_value=testcase.TestCase.EX_RUN_ERROR) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
-
- @unittest.skip("JIRA: FUNCTEST-781")
- def test_post_exc(self):
- with mock.patch.object(self.feature, 'post',
- side_effect=Exception) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
-
- @unittest.skip("JIRA: FUNCTEST-778")
- def test_execute_ko(self):
- with mock.patch.object(self.feature, 'execute',
- return_value=1) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
-
- @unittest.skip("JIRA: FUNCTEST-778")
- def test_execute_exc(self):
- with mock.patch.object(self.feature, 'execute',
- side_effect=Exception) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_RUN_ERROR)
- mock_object.assert_called_once_with()
+ self.feature = feature.Feature(
+ project_name=self._project_name, case_name=self._case_name,
+ cmd=self._cmd)
def test_run(self):
- with mock.patch.object(self.feature, 'execute',
- return_value=0) as mock_object:
- self.assertEqual(self.feature.run(),
- testcase.TestCase.EX_OK)
- mock_object.assert_called_once_with()
+ self._test_run(testcase.TestCase.EX_RUN_ERROR)
+
+
+class BashFeatureTesting(FeatureTestingBase):
+
+ def setUp(self):
+ self.feature = feature.BashFeature(
+ project_name=self._project_name, case_name=self._case_name,
+ cmd=self._cmd)
+
+ @mock.patch("functest.utils.functest_utils.execute_command",
+ return_value=1)
+ def test_run_ko(self, mock_method=None):
+ self._test_run(testcase.TestCase.EX_RUN_ERROR)
+ mock_method.assert_called_once_with(
+ self._cmd, output_file=self._output_file)
+
+ @mock.patch("functest.utils.functest_utils.execute_command",
+ side_effect=Exception)
+ def test_run_exc(self, mock_method=None):
+ self._test_run(testcase.TestCase.EX_RUN_ERROR)
+ mock_method.assert_called_once_with(
+ self._cmd, output_file=self._output_file)
+
+ @mock.patch("functest.utils.functest_utils.execute_command",
+ return_value=0)
+ def test_run(self, mock_method):
+ self._test_run(testcase.TestCase.EX_OK)
+ mock_method.assert_called_once_with(
+ self._cmd, output_file=self._output_file)
if __name__ == "__main__":
sys.modules['baro_tests'] = mock.Mock() # noqa
# pylint: disable=wrong-import-position
from functest.opnfv_tests.features import barometer
-from functest.utils import constants
class BarometerTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.barometer.project_name, self._project_name)
self.assertEqual(self.barometer.case_name, self._case_name)
- self.assertEqual(
- self.barometer.repo,
- constants.CONST.__getattribute__('dir_repo_barometer'))
- @unittest.skip("JIRA: FUNCTEST-777")
- def test_execute_ko(self):
- # It must be skipped to allow merging
+ def test_run_ko(self):
sys.modules['baro_tests'].collectd.main = mock.Mock(return_value=1)
- self.assertEqual(self.barometer.execute(),
+ self.assertEqual(self.barometer.run(),
testcase.TestCase.EX_RUN_ERROR)
- @unittest.skip("JIRA: FUNCTEST-777")
- def test_execute(self):
- # It must be skipped to allow merging
+ def test_run(self):
sys.modules['baro_tests'].collectd.main = mock.Mock(return_value=0)
- self.assertEqual(self.barometer.execute(), testcase.TestCase.EX_OK)
+ self.assertEqual(self.barometer.run(), testcase.TestCase.EX_OK)
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import copper
-from functest.utils import constants
+from functest.utils.constants import CONST
class CopperTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.copper.project_name, self._project_name)
- self.assertEqual(self.copper.case_name, self._case_name)
- self.assertEqual(
- self.copper.repo,
- constants.CONST.__getattribute__("dir_repo_copper"))
+ repo = CONST.__getattribute__('dir_repo_copper')
self.assertEqual(
self.copper.cmd,
- "cd {}/tests && bash run.sh && cd -".format(self.copper.repo))
+ "cd {}/tests && bash run.sh && cd -".format(repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import doctor
-from functest.utils import constants
+from functest.utils.constants import CONST
class DoctorTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.doctor.project_name, self._project_name)
self.assertEqual(self.doctor.case_name, self._case_name)
- self.assertEqual(
- self.doctor.repo,
- constants.CONST.__getattribute__("dir_repo_doctor"))
+ repo = CONST.__getattribute__('dir_repo_doctor')
self.assertEqual(
self.doctor.cmd,
- 'cd {}/tests && ./run.sh'.format(self.doctor.repo))
+ 'cd {}/tests && ./run.sh'.format(repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import domino
-from functest.utils import constants
+from functest.utils.constants import CONST
class DominoTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.domino.project_name, self._project_name)
self.assertEqual(self.domino.case_name, self._case_name)
- self.assertEqual(
- self.domino.repo,
- constants.CONST.__getattribute__("dir_repo_domino"))
+ repo = CONST.__getattribute__('dir_repo_domino')
self.assertEqual(
self.domino.cmd,
- 'cd {} && ./tests/run_multinode.sh'.format(self.domino.repo))
+ 'cd {} && ./tests/run_multinode.sh'.format(repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import netready
-from functest.utils import constants
+from functest.utils.constants import CONST
class NetreadyTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.netready.project_name, self._project_name)
self.assertEqual(self.netready.case_name, self._case_name)
- self.assertEqual(
- self.netready.repo,
- constants.CONST.__getattribute__("dir_repo_netready"))
+ repo = CONST.__getattribute__('dir_repo_netready')
self.assertEqual(
self.netready.cmd,
- 'cd {}/test/functest && python ./gluon-test-suite.py'.format(
- self.netready.repo))
+ 'cd {}/test/functest && python ./gluon-test-suite.py'.format(repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import odl_sfc
-from functest.utils import constants
+from functest.utils.constants import CONST
class OpenDaylightSFCTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.odl_sfc.project_name, "sfc")
self.assertEqual(self.odl_sfc.case_name, "functest-odl-sfc")
- self.assertEqual(
- self.odl_sfc.repo,
- constants.CONST.__getattribute__("dir_repo_sfc"))
- dir_sfc_functest = '{}/sfc/tests/functest'.format(self.odl_sfc.repo)
+ repo = CONST.__getattribute__('dir_repo_sfc')
+ dir_sfc_functest = '{}/sfc/tests/functest'.format(repo)
self.assertEqual(
self.odl_sfc.cmd,
'cd {} && python ./run_tests.py'.format(dir_sfc_functest))
import unittest
from functest.opnfv_tests.features import promise
-from functest.utils import constants
+from functest.utils.constants import CONST
class PromiseTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.promise.project_name, self._project_name)
self.assertEqual(self.promise.case_name, self._case_name)
- self.assertEqual(
- self.promise.repo,
- constants.CONST.__getattribute__("dir_repo_promise"))
+ repo = CONST.__getattribute__('dir_repo_promise')
self.assertEqual(
self.promise.cmd,
'cd {}/promise/test/functest && python ./run_tests.py'.format(
- self.promise.repo))
+ repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import sdnvpn
-from functest.utils import constants
+from functest.utils.constants import CONST
class SdnVpnTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.sdnvpn.project_name, self._project_name)
self.assertEqual(self.sdnvpn.case_name, self._case_name)
- self.assertEqual(
- self.sdnvpn.repo,
- constants.CONST.__getattribute__("dir_repo_sdnvpn"))
+ repo = CONST.__getattribute__('dir_repo_sdnvpn')
self.assertEqual(
self.sdnvpn.cmd,
- 'cd {}/sdnvpn/test/functest && python ./run_tests.py'.format(
- self.sdnvpn.repo))
+ 'cd {}/sdnvpn/test/functest && python ./run_tests.py'.format(repo))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.features import security_scan
-from functest.utils import constants
+from functest.utils.constants import CONST
class SecurityScanTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.sscan.project_name, self._project_name)
self.assertEqual(self.sscan.case_name, self._case_name)
- self.assertEqual(
- self.sscan.repo,
- constants.CONST.__getattribute__("dir_repo_securityscan"))
+ repo = CONST.__getattribute__('dir_repo_securityscan')
self.assertEqual(
self.sscan.cmd, (
'. {0}/stackrc && cd {1} && '
'python security_scan.py --config config.ini && '
'cd -'.format(
- constants.CONST.__getattribute__("dir_functest_conf"),
- self.sscan.repo)))
+ CONST.__getattribute__("dir_functest_conf"),
+ repo)))
if __name__ == "__main__":
import unittest
from functest.opnfv_tests.vnf.rnc import parser
-from functest.utils import constants
+from functest.utils.constants import CONST
class ParserTesting(unittest.TestCase):
def test_init(self):
self.assertEqual(self.parser.project_name, self._project_name)
self.assertEqual(self.parser.case_name, self._case_name)
- self.assertEqual(
- self.parser.repo,
- constants.CONST.__getattribute__("dir_repo_parser"))
+ repo = CONST.__getattribute__('dir_repo_parser')
self.assertEqual(
self.parser.cmd,
- 'cd {}/tests && ./functest_run.sh'.format(self.parser.repo))
+ 'cd {}/tests && ./functest_run.sh'.format(repo))
if __name__ == "__main__":