X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=functest%2Fopnfv_tests%2Fsdn%2Fodl%2Fodl.py;h=c0e2a9aeb4339e0cc079a37ded75c2b3ac6a1f2f;hb=457321c2c8ed7e8dcb1daccb6d2fd9814e6a98ca;hp=0905e55ccc1db1d43a183232cae4762a993c8de1;hpb=6f798d51022c7709f678ae996a3a9b13de090aa0;p=functest.git diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py index 0905e55cc..c0e2a9aeb 100755 --- a/functest/opnfv_tests/sdn/odl/odl.py +++ b/functest/opnfv_tests/sdn/odl/odl.py @@ -7,6 +7,15 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 +"""Define classes required to run ODL suites. + +It has been designed for any context. But helpers are given for +running test suites in OPNFV environment. + +Example: + $ python odl.py +""" + import argparse import errno import fileinput @@ -15,17 +24,20 @@ import re import sys import urlparse -from robot.api import ExecutionResult, ResultVisitor +import robot.api from robot.errors import RobotError import robot.run from robot.utils.robottime import timestamp_to_secs -from functest.core import testcase_base +from functest.core import testcase import functest.utils.functest_logger as ft_logger import functest.utils.openstack_utils as op_utils +__author__ = "Cedric Ollivier " -class ODLResultVisitor(ResultVisitor): + +class ODLResultVisitor(robot.api.ResultVisitor): + """Visitor to get result details.""" def __init__(self): self._data = [] @@ -43,10 +55,12 @@ class ODLResultVisitor(ResultVisitor): self._data.append(output) def get_data(self): + """Get the details of the result.""" return self._data -class ODLTests(testcase_base.TestcaseBase): +class ODLTests(testcase.TestCase): + """ODL test runner.""" repos = "/home/opnfv/repos/" odl_test_repo = os.path.join(repos, "odl_test") @@ -54,15 +68,18 @@ class ODLTests(testcase_base.TestcaseBase): "csit/suites/openstack/neutron") basic_suite_dir = os.path.join(odl_test_repo, "csit/suites/integration/basic") + default_suites = [basic_suite_dir, neutron_suite_dir] res_dir = '/home/opnfv/functest/results/odl/' logger = ft_logger.Logger("opendaylight").getLogger() - def __init__(self): - testcase_base.TestcaseBase.__init__(self) - self.case_name = "odl" - @classmethod def set_robotframework_vars(cls, odlusername="admin", odlpassword="admin"): + """Set credentials in csit/variables/Variables.py. + + Returns: + True if credentials are set. + False otherwise. + """ odl_variables_files = os.path.join(cls.odl_test_repo, 'csit/variables/Variables.py') try: @@ -73,13 +90,14 @@ class ODLTests(testcase_base.TestcaseBase): odlpassword + "']"), line.rstrip()) return True - except Exception as e: - cls.logger.error("Cannot set ODL creds: %s" % str(e)) + except Exception as ex: # pylint: disable=broad-except + cls.logger.error("Cannot set ODL creds: %s", str(ex)) return False def parse_results(self): + """Parse output.xml and get the details in it.""" xml_file = os.path.join(self.res_dir, 'output.xml') - result = ExecutionResult(xml_file) + result = robot.api.ExecutionResult(xml_file) visitor = ODLResultVisitor() result.visit(visitor) self.criteria = result.suite.status @@ -89,35 +107,67 @@ class ODLTests(testcase_base.TestcaseBase): 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] + def main(self, suites=None, **kwargs): + """Run the test suites + + It has been designed to be called in any context. + It requires the following keyword arguments: + * odlusername, + * odlpassword, + * osauthurl, + * neutronip, + * osusername, + * ostenantname, + * ospassword, + * odlip, + * odlwebport, + * odlrestconfport. + + Here are the steps: + * set all RobotFramework_variables, + * create the output directories if required, + * get the results in output.xml, + * delete temporary files. + + Args: + **kwargs: Arbitrary keyword arguments. + + Returns: + EX_OK if all suites ran well. + EX_RUN_ERROR otherwise. + """ try: + if not suites: + suites = self.default_suites odlusername = kwargs['odlusername'] odlpassword = kwargs['odlpassword'] - variables = ['KEYSTONE:' + kwargs['keystoneip'], + osauthurl = kwargs['osauthurl'] + keystoneip = urlparse.urlparse(osauthurl).hostname + variables = ['KEYSTONE:' + keystoneip, 'NEUTRON:' + kwargs['neutronip'], + 'OS_AUTH_URL:"' + osauthurl + '"', 'OSUSERNAME:"' + kwargs['osusername'] + '"', 'OSTENANTNAME:"' + kwargs['ostenantname'] + '"', 'OSPASSWORD:"' + kwargs['ospassword'] + '"', 'ODL_SYSTEM_IP:' + kwargs['odlip'], 'PORT:' + kwargs['odlwebport'], 'RESTCONFPORT:' + kwargs['odlrestconfport']] - except KeyError as e: + except KeyError as ex: self.logger.error("Cannot run ODL testcases. Please check " - "%s" % str(e)) + "%s", str(ex)) return self.EX_RUN_ERROR if self.set_robotframework_vars(odlusername, odlpassword): try: os.makedirs(self.res_dir) - except OSError as e: - if e.errno != errno.EEXIST: + except OSError as ex: + if ex.errno != errno.EEXIST: self.logger.exception( - "Cannot create {}".format(self.res_dir)) + "Cannot create %s", self.res_dir) return self.EX_RUN_ERROR stdout_file = os.path.join(self.res_dir, 'stdout.txt') output_dir = os.path.join(self.res_dir, 'output.xml') with open(stdout_file, 'w+') as stdout: - robot.run(*dirs, variable=variables, + robot.run(*suites, variable=variables, output=output_dir, log='NONE', report='NONE', @@ -128,24 +178,39 @@ class ODLTests(testcase_base.TestcaseBase): 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) + except RobotError as ex: + self.logger.error("Run tests before publishing: %s", + ex.message) return self.EX_RUN_ERROR try: os.remove(stdout_file) except OSError: - self.logger.warning("Cannot remove {}".format(stdout_file)) + self.logger.warning("Cannot remove %s", stdout_file) return self.EX_OK else: return self.EX_RUN_ERROR - def run(self): + def run(self, **kwargs): + """Run suites in OPNFV environment + + It basically check env vars to call main() with the keywords + required. + + Args: + **kwargs: Arbitrary keyword arguments. + + Returns: + EX_OK if all suites ran well. + EX_RUN_ERROR otherwise. + """ try: - keystone_url = op_utils.get_endpoint(service_type='identity') + suites = self.default_suites + try: + suites = kwargs["suites"] + except KeyError: + pass neutron_url = op_utils.get_endpoint(service_type='network') - kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname} - kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname + kwargs = {'neutronip': urlparse.urlparse(neutron_url).hostname} kwargs['odlip'] = kwargs['neutronip'] kwargs['odlwebport'] = '8080' kwargs['odlrestconfport'] = '8181' @@ -156,73 +221,93 @@ class ODLTests(testcase_base.TestcaseBase): installer_type = os.environ['INSTALLER_TYPE'] kwargs['osusername'] = os.environ['OS_USERNAME'] kwargs['ostenantname'] = os.environ['OS_TENANT_NAME'] + kwargs['osauthurl'] = os.environ['OS_AUTH_URL'] kwargs['ospassword'] = os.environ['OS_PASSWORD'] if installer_type == 'fuel': kwargs['odlwebport'] = '8282' - elif installer_type == 'apex': + elif installer_type == 'apex' or installer_type == 'netvirt': kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP'] - kwargs['odlwebport'] = '8181' + kwargs['odlwebport'] = '8081' + kwargs['odlrestconfport'] = '8081' elif installer_type == 'joid': kwargs['odlip'] = os.environ['SDN_CONTROLLER'] elif installer_type == 'compass': kwargs['odlwebport'] = '8181' else: kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP'] - except KeyError as e: + except KeyError as ex: self.logger.error("Cannot run ODL testcases. " "Please check env var: " - "%s" % str(e)) + "%s", str(ex)) return self.EX_RUN_ERROR - except Exception: + except Exception: # pylint: disable=broad-except self.logger.exception("Cannot run ODL testcases.") return self.EX_RUN_ERROR - return self.main(**kwargs) + return self.main(suites, **kwargs) + + +class ODLParser(object): # pylint: disable=too-few-public-methods + """Parser to run ODL test suites.""" + + def __init__(self): + self.parser = argparse.ArgumentParser() + self.parser.add_argument( + '-n', '--neutronip', help='Neutron IP', + default='127.0.0.1') + self.parser.add_argument( + '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack', + default='http://127.0.0.1:5000/v2.0') + self.parser.add_argument( + '-a', '--osusername', help='Username for OpenStack', + default='admin') + self.parser.add_argument( + '-b', '--ostenantname', help='Tenantname for OpenStack', + default='admin') + self.parser.add_argument( + '-c', '--ospassword', help='Password for OpenStack', + default='admin') + self.parser.add_argument( + '-o', '--odlip', help='OpenDaylight IP', + default='127.0.0.1') + self.parser.add_argument( + '-w', '--odlwebport', help='OpenDaylight Web Portal Port', + default='8080') + self.parser.add_argument( + '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port', + default='8181') + self.parser.add_argument( + '-d', '--odlusername', help='Username for ODL', + default='admin') + self.parser.add_argument( + '-e', '--odlpassword', help='Password for ODL', + default='admin') + self.parser.add_argument( + '-p', '--pushtodb', help='Push results to DB', + action='store_true') + + def parse_args(self, argv=None): + """Parse arguments. + + It can call sys.exit if arguments are incorrect. + + Returns: + the arguments from cmdline + """ + if not argv: + argv = [] + return vars(self.parser.parse_args(argv)) if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-k', '--keystoneip', - help='Keystone IP', - default='127.0.0.1') - parser.add_argument('-n', '--neutronip', - help='Neutron IP', - default='127.0.0.1') - parser.add_argument('-a', '--osusername', - help='Username for OpenStack', - default='admin') - parser.add_argument('-b', '--ostenantname', - help='Tenantname for OpenStack', - default='admin') - parser.add_argument('-c', '--ospassword', - help='Password for OpenStack', - default='admin') - parser.add_argument('-o', '--odlip', - help='OpenDaylight IP', - default='127.0.0.1') - parser.add_argument('-w', '--odlwebport', - help='OpenDaylight Web Portal Port', - default='8080') - parser.add_argument('-r', '--odlrestconfport', - help='OpenDaylight RESTConf Port', - default='8181') - parser.add_argument('-d', '--odlusername', - help='Username for ODL', - default='admin') - parser.add_argument('-e', '--odlpassword', - help='Password for ODL', - default='admin') - parser.add_argument('-p', '--pushtodb', - help='Push results to DB', - action='store_true') - - args = vars(parser.parse_args()) - odl = ODLTests() + ODL = ODLTests() + PARSER = ODLParser() + ARGS = PARSER.parse_args(sys.argv[1:]) try: - result = odl.main(**args) - if result != testcase_base.TestcaseBase.EX_OK: - sys.exit(result) - if args['pushtodb']: - sys.exit(odl.push_to_db()) - except Exception: - sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR) + RESULT = ODL.main(ODLTests.default_suites, **ARGS) + if RESULT != testcase.TestCase.EX_OK: + sys.exit(RESULT) + if ARGS['pushtodb']: + sys.exit(ODL.push_to_db()) + except Exception: # pylint: disable=broad-except + sys.exit(testcase.TestCase.EX_RUN_ERROR)