aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xci/run_tests.py42
-rw-r--r--ci/testcases.yaml3
-rw-r--r--core/TestCasesBase.py46
-rwxr-xr-xcore/TestCasesBaseTesting.py80
-rw-r--r--core/__init__.py0
-rw-r--r--docker/Dockerfile1
-rwxr-xr-xtestcases/Controllers/ODL/OpenDaylightTesting.py158
-rwxr-xr-xtestcases/Controllers/ODL/OpenDaylightUnitTesting.py341
-rw-r--r--utils/functest_utils.py11
-rwxr-xr-xutils/openstack_utils.py12
10 files changed, 609 insertions, 85 deletions
diff --git a/ci/run_tests.py b/ci/run_tests.py
index 638a6edf3..f30062f75 100755
--- a/ci/run_tests.py
+++ b/ci/run_tests.py
@@ -9,6 +9,7 @@
#
import datetime
+import importlib
import os
import re
import sys
@@ -17,12 +18,13 @@ import argparse
import functest.ci.generate_report as generate_report
import functest.ci.tier_builder as tb
+import functest.core.TestCasesBase as TestCasesBase
import functest.utils.functest_logger as ft_logger
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.testcases.Controllers.ODL.OpenDaylightTesting import ODLTestCases
+
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--test", dest="test", action='store',
@@ -82,6 +84,19 @@ def update_test_info(test_name, result, duration):
"duration": duration})
+def get_run_dict_if_defined(testname):
+ try:
+ dict = ft_utils.get_dict_by_test(testname)
+ if not dict:
+ logger.error("Cannot get {}'s config options".format(testname))
+ elif 'run' in dict:
+ return dict['run']
+ return None
+ except Exception:
+ logger.exception("Cannot get {}'s config options".format(testname))
+ return None
+
+
def run_test(test, tier_name):
global OVERALL_RESULT, EXECUTED_TEST_CASES
result_str = "PASS"
@@ -100,14 +115,27 @@ def run_test(test, tier_name):
if REPORT_FLAG:
flags += " -r"
- if test_name == 'odl':
- result = ODLTestCases.functest_run()
- if result and REPORT_FLAG:
- result = ODLTestCases.push_to_db()
- result = not result
+ result = TestCasesBase.TestCasesBase.EX_RUN_ERROR
+ run_dict = get_run_dict_if_defined(test_name)
+ if run_dict:
+ try:
+ module = importlib.import_module(run_dict['module'])
+ cls = getattr(module, run_dict['class'])
+ test_case = cls()
+ result = test_case.run()
+ if result == TestCasesBase.TestCasesBase.EX_OK and REPORT_FLAG:
+ result = test_case.push_to_db()
+ except ImportError:
+ logger.exception("Cannot import module {}".format(
+ run_dict['module']))
+ except AttributeError:
+ logger.exception("Cannot get class {}".format(
+ run_dict['class']))
else:
cmd = ("%s%s" % (EXEC_SCRIPT, flags))
- logger.debug("Executing command '%s'" % cmd)
+ logger.info("Executing command {} because {} "
+ "doesn't implement the new framework".format(
+ cmd, test_name))
result = ft_utils.execute_command(cmd)
if CLEAN_FLAG:
diff --git a/ci/testcases.yaml b/ci/testcases.yaml
index 02b69ec8b..22509e611 100644
--- a/ci/testcases.yaml
+++ b/ci/testcases.yaml
@@ -92,6 +92,9 @@ tiers:
dependencies:
installer: ''
scenario: 'odl'
+ run:
+ module: 'functest.testcases.Controllers.ODL.OpenDaylightTesting'
+ class: 'ODLTestCases'
-
name: onos
diff --git a/core/TestCasesBase.py b/core/TestCasesBase.py
new file mode 100644
index 000000000..8e68fa68a
--- /dev/null
+++ b/core/TestCasesBase.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+import os
+
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+
+
+class TestCasesBase(object):
+
+ EX_OK = os.EX_OK
+ EX_RUN_ERROR = os.EX_SOFTWARE
+ EX_PUSH_TO_DB_ERROR = os.EX_SOFTWARE - 1
+
+ logger = ft_logger.Logger(__name__).getLogger()
+
+ project = "functest"
+
+ def __init__(self):
+ self.details = {}
+ self.case_name = ""
+ self.criteria = ""
+ self.start_time = ""
+ self.stop_time = ""
+
+ def run(self, **kwargs):
+ self.logger.error("Run must be implemented")
+ return TestCasesBase.EX_RUN_ERROR
+
+ def push_to_db(self):
+ try:
+ assert self.case_name
+ assert self.criteria
+ assert self.start_time
+ assert self.stop_time
+ if ft_utils.push_results_to_db(
+ TestCasesBase.project, self.case_name, self.start_time,
+ self.stop_time, self.criteria, self.details):
+ self.logger.info("The results were successfully pushed to DB")
+ return TestCasesBase.EX_OK
+ else:
+ self.logger.error("The results cannot be pushed to DB")
+ return TestCasesBase.EX_PUSH_TO_DB_ERROR
+ except Exception:
+ self.logger.exception("The results cannot be pushed to DB")
+ return TestCasesBase.EX_PUSH_TO_DB_ERROR
diff --git a/core/TestCasesBaseTesting.py b/core/TestCasesBaseTesting.py
new file mode 100755
index 000000000..9658e8dc4
--- /dev/null
+++ b/core/TestCasesBaseTesting.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+import logging
+import mock
+import unittest
+
+import TestCasesBase
+
+
+class TestCasesBaseTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.test = TestCasesBase.TestCasesBase()
+ self.test.project = "functest"
+ self.test.case_name = "base"
+ self.test.start_time = "1"
+ self.test.stop_time = "2"
+ self.test.criteria = "100"
+ self.test.details = {"Hello": "World"}
+
+ def test_run_unimplemented(self):
+ self.assertEqual(self.test.run(),
+ TestCasesBase.TestCasesBase.EX_RUN_ERROR)
+
+ @mock.patch('functest.utils.functest_utils.push_results_to_db',
+ return_value=False)
+ def _test_missing_attribute(self, mock_function):
+ self.assertEqual(self.test.push_to_db(),
+ TestCasesBase.TestCasesBase.EX_PUSH_TO_DB_ERROR)
+ mock_function.assert_not_called()
+
+ def test_missing_case_name(self):
+ self.test.case_name = None
+ self._test_missing_attribute()
+
+ def test_missing_criteria(self):
+ self.test.criteria = None
+ self._test_missing_attribute()
+
+ def test_missing_start_time(self):
+ self.test.start_time = None
+ self._test_missing_attribute()
+
+ def test_missing_stop_time(self):
+ self.test.stop_time = None
+ self._test_missing_attribute()
+
+ @mock.patch('functest.utils.functest_utils.push_results_to_db',
+ return_value=True)
+ def test_missing_details(self, mock_function):
+ self.test.details = None
+ self.assertEqual(self.test.push_to_db(),
+ TestCasesBase.TestCasesBase.EX_OK)
+ mock_function.assert_called_once_with(
+ self.test.project, self.test.case_name, self.test.start_time,
+ self.test.stop_time, self.test.criteria, self.test.details)
+
+ @mock.patch('functest.utils.functest_utils.push_results_to_db',
+ return_value=False)
+ def test_push_to_db_failed(self, mock_function):
+ self.assertEqual(self.test.push_to_db(),
+ TestCasesBase.TestCasesBase.EX_PUSH_TO_DB_ERROR)
+ mock_function.assert_called_once_with(
+ self.test.project, self.test.case_name, self.test.start_time,
+ self.test.stop_time, self.test.criteria, self.test.details)
+
+ @mock.patch('functest.utils.functest_utils.push_results_to_db',
+ return_value=True)
+ def test_push_to_db(self, mock_function):
+ self.assertEqual(self.test.push_to_db(),
+ TestCasesBase.TestCasesBase.EX_OK)
+ mock_function.assert_called_once_with(
+ self.test.project, self.test.case_name, self.test.start_time,
+ self.test.stop_time, self.test.criteria, self.test.details)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/core/__init__.py b/core/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/core/__init__.py
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 2d325eaaf..9ff0f4f62 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -53,6 +53,7 @@ git \
gcc \
wget \
python-dev \
+python-mockĀ \
python-pip \
bundler \
postgresql \
diff --git a/testcases/Controllers/ODL/OpenDaylightTesting.py b/testcases/Controllers/ODL/OpenDaylightTesting.py
index 35a2ee117..e302b569e 100755
--- a/testcases/Controllers/ODL/OpenDaylightTesting.py
+++ b/testcases/Controllers/ODL/OpenDaylightTesting.py
@@ -1,6 +1,7 @@
#!/usr/bin/python
import argparse
+import errno
import fileinput
import os
import re
@@ -8,13 +9,13 @@ import shutil
import sys
import urlparse
-from robot import run
from robot.api import ExecutionResult, ResultVisitor
from robot.errors import RobotError
+import robot.run
from robot.utils.robottime import timestamp_to_secs
+from functest.core import TestCasesBase
import functest.utils.functest_logger as ft_logger
-import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as op_utils
@@ -39,7 +40,7 @@ class ODLResultVisitor(ResultVisitor):
return self._data
-class ODLTestCases:
+class ODLTestCases(TestCasesBase.TestCasesBase):
repos = "/home/opnfv/repos/"
odl_test_repo = repos + "odl_test/"
@@ -48,13 +49,16 @@ class ODLTestCases:
res_dir = '/home/opnfv/functest/results/odl/'
logger = ft_logger.Logger("opendaylight").getLogger()
+ def __init__(self):
+ self.case_name = "odl"
+
@classmethod
def copy_opnf_testcases(cls):
opnfv_testcases_dir = (os.path.dirname(os.path.abspath(__file__)) +
"/custom_tests/neutron/")
- file = opnfv_testcases_dir + "001__reachability.robot"
+ f = opnfv_testcases_dir + "001__reachability.robot"
try:
- shutil.copy(file, cls.neutron_suite_dir)
+ shutil.copy(f, cls.neutron_suite_dir)
except IOError as e:
cls.logger.error(
"Cannot copy OPNFV's testcase to ODL directory: %s" % str(e))
@@ -76,9 +80,19 @@ class ODLTestCases:
cls.logger.error("Cannot set ODL creds: %s" % str(e))
return False
- @classmethod
- def run(cls, **kwargs):
- dirs = [cls.basic_suite_dir, cls.neutron_suite_dir]
+ def parse_results(self):
+ result = ExecutionResult(self.res_dir + 'output.xml')
+ visitor = ODLResultVisitor()
+ result.visit(visitor)
+ self.criteria = result.suite.status
+ self.start_time = timestamp_to_secs(result.suite.starttime)
+ self.stop_time = timestamp_to_secs(result.suite.endtime)
+ self.details = {}
+ self.details['description'] = result.suite.name
+ self.details['tests'] = visitor.get_data()
+
+ def main(self, **kwargs):
+ dirs = [self.basic_suite_dir, self.neutron_suite_dir]
try:
odlusername = kwargs['odlusername']
odlpassword = kwargs['odlpassword']
@@ -91,49 +105,60 @@ class ODLTestCases:
'PORT:' + kwargs['odlwebport'],
'RESTCONFPORT:' + kwargs['odlrestconfport']]
except KeyError as e:
- cls.logger.error("Cannot run ODL testcases. Please check "
- "%s" % str(e))
- return False
- if (cls.copy_opnf_testcases() and
- cls.set_robotframework_vars(odlusername, odlpassword)):
+ self.logger.error("Cannot run ODL testcases. Please check "
+ "%s" % str(e))
+ return self.EX_RUN_ERROR
+ if (self.copy_opnf_testcases() and
+ self.set_robotframework_vars(odlusername, odlpassword)):
try:
- os.makedirs(cls.res_dir)
- except OSError:
- pass
- stdout_file = cls.res_dir + 'stdout.txt'
+ os.makedirs(self.res_dir)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ self.logger.exception(
+ "Cannot create {}".format(self.res_dir))
+ return self.EX_RUN_ERROR
+ stdout_file = self.res_dir + 'stdout.txt'
with open(stdout_file, 'w+') as stdout:
- run(*dirs, variable=variables,
- output=cls.res_dir + 'output.xml',
- log='NONE',
- report='NONE',
- stdout=stdout)
+ robot.run(*dirs, variable=variables,
+ output=self.res_dir + 'output.xml',
+ log='NONE',
+ report='NONE',
+ stdout=stdout)
stdout.seek(0, 0)
- cls.logger.info("\n" + stdout.read())
- cls.logger.info("ODL results were successfully generated")
+ self.logger.info("\n" + stdout.read())
+ self.logger.info("ODL results were successfully generated")
+ try:
+ self.parse_results()
+ self.logger.info("ODL results were successfully parsed")
+ except RobotError as e:
+ self.logger.error("Run tests before publishing: %s" %
+ e.message)
+ return self.EX_RUN_ERROR
try:
os.remove(stdout_file)
except OSError:
- pass
- return True
+ self.logger.warning("Cannot remove {}".format(stdout_file))
+ return self.EX_OK
else:
- return False
+ return self.EX_RUN_ERROR
- @classmethod
- def functest_run(cls):
- kclient = op_utils.get_keystone_client()
- keystone_url = kclient.service_catalog.url_for(
- service_type='identity', endpoint_type='publicURL')
- neutron_url = kclient.service_catalog.url_for(
- service_type='network', endpoint_type='publicURL')
- kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname}
- kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname
- kwargs['odlip'] = kwargs['neutronip']
- kwargs['odlwebport'] = '8080'
- kwargs['odlrestconfport'] = '8181'
- kwargs['odlusername'] = 'admin'
- kwargs['odlpassword'] = 'admin'
+ def run(self):
try:
- installer_type = os.environ['INSTALLER_TYPE']
+ kclient = op_utils.get_keystone_client()
+ keystone_url = kclient.service_catalog.url_for(
+ service_type='identity', endpoint_type='publicURL')
+ neutron_url = kclient.service_catalog.url_for(
+ service_type='network', endpoint_type='publicURL')
+ kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname}
+ kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname
+ kwargs['odlip'] = kwargs['neutronip']
+ kwargs['odlwebport'] = '8080'
+ kwargs['odlrestconfport'] = '8181'
+ kwargs['odlusername'] = 'admin'
+ kwargs['odlpassword'] = 'admin'
+ installer_type = None
+ if 'INSTALLER_TYPE' in os.environ:
+ installer_type = os.environ['INSTALLER_TYPE']
kwargs['osusername'] = os.environ['OS_USERNAME']
kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
kwargs['ospassword'] = os.environ['OS_PASSWORD']
@@ -149,34 +174,15 @@ class ODLTestCases:
else:
kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
except KeyError as e:
- cls.logger.error("Cannot run ODL testcases. Please check env var: "
- "%s" % str(e))
- return False
-
- return cls.run(**kwargs)
-
- @classmethod
- def push_to_db(cls):
- try:
- result = ExecutionResult(cls.res_dir + 'output.xml')
- visitor = ODLResultVisitor()
- result.visit(visitor)
- start_time = timestamp_to_secs(result.suite.starttime)
- stop_time = timestamp_to_secs(result.suite.endtime)
- details = {}
- details['description'] = result.suite.name
- details['tests'] = visitor.get_data()
- if not ft_utils.push_results_to_db(
- "functest", "odl", start_time, stop_time,
- result.suite.status, details):
- cls.logger.error("Cannot push ODL results to DB")
- return False
- else:
- cls.logger.info("ODL results were successfully pushed to DB")
- return True
- except RobotError as e:
- cls.logger.error("Run tests before publishing: %s" % e.message)
+ self.logger.error("Cannot run ODL testcases. "
+ "Please check env var: "
+ "%s" % str(e))
+ return self.EX_RUN_ERROR
+ except Exception:
+ self.logger.exception("Cannot run ODL testcases.")
+ return self.EX_RUN_ERROR
+ return self.main(**kwargs)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
@@ -215,8 +221,12 @@ if __name__ == '__main__':
action='store_true')
args = vars(parser.parse_args())
- if not ODLTestCases.run(**args):
- sys.exit(os.EX_SOFTWARE)
- if args['pushtodb']:
- sys.exit(not ODLTestCases.push_to_db())
- sys.exit(os.EX_OK)
+ odl = ODLTestCases()
+ try:
+ result = odl.main(**args)
+ if result != TestCasesBase.TestCasesBase.EX_OK:
+ sys.exit(result)
+ if args['pushtodb']:
+ sys.exit(odl.push_to_db())
+ except Exception:
+ sys.exit(TestCasesBase.TestCasesBase.EX_RUN_ERROR)
diff --git a/testcases/Controllers/ODL/OpenDaylightUnitTesting.py b/testcases/Controllers/ODL/OpenDaylightUnitTesting.py
new file mode 100755
index 000000000..500888b22
--- /dev/null
+++ b/testcases/Controllers/ODL/OpenDaylightUnitTesting.py
@@ -0,0 +1,341 @@
+#!/usr/bin/env python
+
+import errno
+import logging
+import mock
+import os
+import unittest
+
+from robot.errors import RobotError
+
+from functest.core import TestCasesBase
+from functest.testcases.Controllers.ODL import OpenDaylightTesting
+
+
+class ODLTestCasesTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ _keystone_ip = "127.0.0.1"
+ _neutron_ip = "127.0.0.2"
+ _sdn_controller_ip = "127.0.0.3"
+ _os_tenantname = "admin"
+ _os_username = "admin"
+ _os_password = "admin"
+ _odl_webport = "8080"
+ _odl_restconfport = "8181"
+ _odl_username = "admin"
+ _odl_password = "admin"
+
+ def setUp(self):
+ if "INSTALLER_TYPE" in os.environ:
+ del os.environ["INSTALLER_TYPE"]
+ os.environ["OS_USERNAME"] = self._os_username
+ os.environ["OS_PASSWORD"] = self._os_password
+ os.environ["OS_TENANT_NAME"] = self._os_tenantname
+ self.test = OpenDaylightTesting.ODLTestCases()
+
+ @mock.patch('shutil.copy', side_effect=Exception())
+ def test_copy_opnf_testcases_exception(self, *args):
+ with self.assertRaises(Exception):
+ self.test.copy_opnf_testcases()
+
+ @mock.patch('shutil.copy', side_effect=IOError())
+ def test_copy_opnf_testcases_ioerror(self, *args):
+ self.assertFalse(self.test.copy_opnf_testcases())
+
+ @mock.patch('shutil.copy')
+ def test_copy_opnf_testcases(self, *args):
+ self.assertTrue(self.test.copy_opnf_testcases())
+
+ @mock.patch('fileinput.input', side_effect=Exception())
+ def test_set_robotframework_vars_failed(self, *args):
+ self.assertFalse(self.test.set_robotframework_vars())
+
+ @mock.patch('fileinput.input', return_value=[])
+ def test_set_robotframework_vars(self, args):
+ self.assertTrue(self.test.set_robotframework_vars())
+
+ def _test_run_missing_env_var(self, var):
+ del os.environ[var]
+ self.assertEqual(self.test.run(),
+ TestCasesBase.TestCasesBase.EX_RUN_ERROR)
+
+ @classmethod
+ def _fake_url_for(cls, service_type='identity', **kwargs):
+ if service_type == 'identity':
+ return "http://{}:5000/v2.0".format(
+ ODLTestCasesTesting._keystone_ip)
+ elif service_type == 'network':
+ return "http://{}:9696".format(ODLTestCasesTesting._neutron_ip)
+ else:
+ return None
+
+ @classmethod
+ def _get_fake_keystone_client(cls):
+ kclient = mock.Mock()
+ kclient.service_catalog = mock.Mock()
+ kclient.service_catalog.url_for = mock.Mock(
+ side_effect=cls._fake_url_for)
+ return kclient
+
+ def _get_main_kwargs(self, key=None):
+ kwargs = {'odlusername': self._odl_username,
+ 'odlpassword': self._odl_password,
+ 'keystoneip': self._keystone_ip,
+ 'neutronip': self._neutron_ip,
+ 'osusername': self._os_username,
+ 'ostenantname': self._os_tenantname,
+ 'ospassword': self._os_password,
+ 'odlip': self._sdn_controller_ip,
+ 'odlwebport': self._odl_webport,
+ 'odlrestconfport': self._odl_restconfport}
+ if key:
+ del kwargs[key]
+ return kwargs
+
+ def _test_main(self, status, *args):
+ kwargs = self._get_main_kwargs()
+ self.assertEqual(self.test.main(**kwargs), status)
+ if len(args) > 0:
+ args[0].assert_called_once_with(
+ OpenDaylightTesting.ODLTestCases.res_dir)
+ if len(args) > 1:
+ variable = ['KEYSTONE:{}'.format(self._keystone_ip),
+ 'NEUTRON:{}'.format(self._neutron_ip),
+ 'OSUSERNAME:"{}"'.format(self._os_username),
+ 'OSTENANTNAME:"{}"'.format(self._os_tenantname),
+ 'OSPASSWORD:"{}"'.format(self._os_password),
+ 'ODL_SYSTEM_IP:{}'.format(self._sdn_controller_ip),
+ 'PORT:{}'.format(self._odl_webport),
+ 'RESTCONFPORT:{}'.format(self._odl_restconfport)]
+ args[1].assert_called_once_with(
+ OpenDaylightTesting.ODLTestCases.basic_suite_dir,
+ OpenDaylightTesting.ODLTestCases.neutron_suite_dir,
+ log='NONE',
+ output=OpenDaylightTesting.ODLTestCases.res_dir + 'output.xml',
+ report='NONE',
+ stdout=mock.ANY,
+ variable=variable)
+ if len(args) > 2:
+ args[2].assert_called_with(
+ OpenDaylightTesting.ODLTestCases.res_dir + 'stdout.txt')
+
+ def _test_main_missing_keyword(self, key):
+ kwargs = self._get_main_kwargs(key)
+ self.assertEqual(self.test.main(**kwargs),
+ TestCasesBase.TestCasesBase.EX_RUN_ERROR)
+
+ def test_main_missing_odlusername(self):
+ self._test_main_missing_keyword('odlusername')
+
+ def test_main_missing_odlpassword(self):
+ self._test_main_missing_keyword('odlpassword')
+
+ def test_main_missing_keystoneip(self):
+ self._test_main_missing_keyword('keystoneip')
+
+ def test_main_missing_neutronip(self):
+ self._test_main_missing_keyword('neutronip')
+
+ def test_main_missing_osusername(self):
+ self._test_main_missing_keyword('osusername')
+
+ def test_main_missing_ostenantname(self):
+ self._test_main_missing_keyword('ostenantname')
+
+ def test_main_missing_ospassword(self):
+ self._test_main_missing_keyword('ospassword')
+
+ def test_main_missing_odlip(self):
+ self._test_main_missing_keyword('odlip')
+
+ def test_main_missing_odlwebport(self):
+ self._test_main_missing_keyword('odlwebport')
+
+ def test_main_missing_odlrestconfport(self):
+ self._test_main_missing_keyword('odlrestconfport')
+
+ def test_main_copy_opnf_testcases_failed(self):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=False):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR)
+ self.test.copy_opnf_testcases.assert_called_once_with()
+
+ def test_main_set_robotframework_vars_failed(self):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=False):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR)
+ self.test.set_robotframework_vars.assert_called_once_with(
+ self._odl_username, self._odl_password)
+
+ @mock.patch('os.makedirs', side_effect=Exception)
+ def test_main_makedirs_exception(self, mock_method):
+ with mock.patch.object(self.test,
+ 'copy_opnf_testcases', return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ self.assertRaises(Exception):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR,
+ mock_method)
+
+ @mock.patch('os.makedirs', side_effect=OSError)
+ def test_main_makedirs_oserror(self, mock_method):
+ with mock.patch.object(self.test,
+ 'copy_opnf_testcases', return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR,
+ mock_method)
+
+ @mock.patch('robot.run', side_effect=RobotError)
+ @mock.patch('os.makedirs')
+ def test_main_robot_run_failed(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ self.assertRaises(RobotError):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR, *args)
+
+ @mock.patch('robot.run')
+ @mock.patch('os.makedirs')
+ def test_main_parse_results_failed(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results',
+ side_effect=RobotError):
+ self._test_main(TestCasesBase.TestCasesBase.EX_RUN_ERROR, *args)
+
+ @mock.patch('os.remove', side_effect=Exception)
+ @mock.patch('robot.run')
+ @mock.patch('os.makedirs')
+ def test_main_remove_exception(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results'), \
+ self.assertRaises(Exception):
+ self._test_main(TestCasesBase.TestCasesBase.EX_OK, *args)
+
+ @mock.patch('os.remove')
+ @mock.patch('robot.run')
+ @mock.patch('os.makedirs')
+ def test_main(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results'):
+ self._test_main(TestCasesBase.TestCasesBase.EX_OK, *args)
+
+ @mock.patch('os.remove')
+ @mock.patch('robot.run')
+ @mock.patch('os.makedirs', side_effect=OSError(errno.EEXIST, ''))
+ def test_main_makedirs_oserror17(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results'):
+ self._test_main(TestCasesBase.TestCasesBase.EX_OK, *args)
+
+ @mock.patch('os.remove')
+ @mock.patch('robot.run', return_value=1)
+ @mock.patch('os.makedirs')
+ def test_main_testcases_in_failure(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results'):
+ self._test_main(TestCasesBase.TestCasesBase.EX_OK, *args)
+
+ @mock.patch('os.remove', side_effect=OSError)
+ @mock.patch('robot.run')
+ @mock.patch('os.makedirs')
+ def test_main_remove_oserror(self, *args):
+ with mock.patch.object(self.test, 'copy_opnf_testcases',
+ return_value=True), \
+ mock.patch.object(self.test, 'set_robotframework_vars',
+ return_value=True), \
+ mock.patch.object(self.test, 'parse_results'):
+ self._test_main(TestCasesBase.TestCasesBase.EX_OK, *args)
+
+ def _test_run(self, status=TestCasesBase.TestCasesBase.EX_OK,
+ exception=None, odlip="127.0.0.3", odlwebport="8080"):
+ with mock.patch('functest.utils.openstack_utils.get_keystone_client',
+ return_value=self._get_fake_keystone_client()):
+ if exception:
+ self.test.main = mock.Mock(side_effect=exception)
+ else:
+ self.test.main = mock.Mock(return_value=status)
+ self.assertEqual(self.test.run(), status)
+ self.test.main.assert_called_once_with(
+ keystoneip=self._keystone_ip, neutronip=self._neutron_ip,
+ odlip=odlip, odlpassword=self._odl_password,
+ odlrestconfport=self._odl_restconfport,
+ odlusername=self._odl_username, odlwebport=odlwebport,
+ ospassword=self._os_password, ostenantname=self._os_tenantname,
+ osusername=self._os_username)
+
+ def test_run_missing_os_username(self):
+ self._test_run_missing_env_var("OS_USERNAME")
+
+ def test_run_missing_os_password(self):
+ self._test_run_missing_env_var("OS_PASSWORD")
+
+ def test_run_missing_os_tenant_name(self):
+ self._test_run_missing_env_var("OS_TENANT_NAME")
+
+ def test_run_main_false(self):
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(TestCasesBase.TestCasesBase.EX_RUN_ERROR,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_run_main_exception(self):
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ with self.assertRaises(Exception):
+ self._test_run(status=TestCasesBase.TestCasesBase.EX_RUN_ERROR,
+ exception=Exception(),
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_run_without_installer_type(self):
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ self._test_run(TestCasesBase.TestCasesBase.EX_OK,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_run_fuel(self):
+ os.environ["INSTALLER_TYPE"] = "fuel"
+ self._test_run(TestCasesBase.TestCasesBase.EX_OK,
+ odlip=self._neutron_ip, odlwebport='8282')
+
+ def test_run_apex(self):
+ os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
+ os.environ["INSTALLER_TYPE"] = "apex"
+ self._test_run(TestCasesBase.TestCasesBase.EX_OK,
+ odlip=self._sdn_controller_ip, odlwebport='8181')
+
+ def test_run_joid(self):
+ os.environ["SDN_CONTROLLER"] = self._sdn_controller_ip
+ os.environ["INSTALLER_TYPE"] = "joid"
+ self._test_run(TestCasesBase.TestCasesBase.EX_OK,
+ odlip=self._sdn_controller_ip,
+ odlwebport=self._odl_webport)
+
+ def test_run_compass(self, *args):
+ os.environ["INSTALLER_TYPE"] = "compass"
+ self._test_run(TestCasesBase.TestCasesBase.EX_OK,
+ odlip=self._neutron_ip, odlwebport='8181')
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/utils/functest_utils.py b/utils/functest_utils.py
index ef865bedf..41b6485d9 100644
--- a/utils/functest_utils.py
+++ b/utils/functest_utils.py
@@ -341,19 +341,26 @@ def get_deployment_dir():
return deployment_dir
-def get_criteria_by_test(testname):
+def get_dict_by_test(testname):
with open(get_testcases_file()) as f:
testcases_yaml = yaml.safe_load(f)
for dic_tier in testcases_yaml.get("tiers"):
for dic_testcase in dic_tier['testcases']:
if dic_testcase['name'] == testname:
- return dic_testcase['criteria']
+ return dic_testcase
logger.error('Project %s is not defined in testcases.yaml' % testname)
return None
+def get_criteria_by_test(testname):
+ dict = get_dict_by_test(testname)
+ if dict:
+ return dict['criteria']
+ return None
+
+
# ----------------------------------------------------------
#
# YAML UTILS
diff --git a/utils/openstack_utils.py b/utils/openstack_utils.py
index e0da7d97d..39594a2a9 100755
--- a/utils/openstack_utils.py
+++ b/utils/openstack_utils.py
@@ -28,6 +28,15 @@ logger = ft_logger.Logger("openstack_utils").getLogger()
# *********************************************
# CREDENTIALS
# *********************************************
+class MissingEnvVar(Exception):
+
+ def __init__(self, var):
+ self.var = var
+
+ def __str__(self):
+ return str.format("Please set the mandatory env var: {}", self.var)
+
+
def check_credentials():
"""
Check if the OpenStack credentials (openrc) are sourced
@@ -51,8 +60,7 @@ def get_credentials(service):
envvars = ('OS_USERNAME', 'OS_PASSWORD', 'OS_AUTH_URL', 'OS_TENANT_NAME')
for envvar in envvars:
if os.getenv(envvar) is None:
- logger.error("'%s' is not exported as an env variable." % envvar)
- exit(-1)
+ raise MissingEnvVar(envvar)
# Unfortunately, each of the OpenStack client will request slightly
# different entries in their credentials dict.