diff options
Diffstat (limited to 'functest/opnfv_tests')
25 files changed, 530 insertions, 601 deletions
diff --git a/functest/opnfv_tests/features/barometer.py b/functest/opnfv_tests/features/barometer.py index 32067284..6011340f 100644 --- a/functest/opnfv_tests/features/barometer.py +++ b/functest/opnfv_tests/features/barometer.py @@ -8,10 +8,10 @@ from baro_tests import collectd -import functest.core.feature_base as base +import functest.core.feature as base -class BarometerCollectd(base.FeatureBase): +class BarometerCollectd(base.Feature): ''' Class for executing barometercollectd testcase. ''' diff --git a/functest/opnfv_tests/features/copper.py b/functest/opnfv_tests/features/copper.py index 735b315d..689341ea 100644 --- a/functest/opnfv_tests/features/copper.py +++ b/functest/opnfv_tests/features/copper.py @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import functest.core.feature_base as base +import functest.core.feature as base -class Copper(base.FeatureBase): +class Copper(base.Feature): def __init__(self): super(Copper, self).__init__(project='copper', case='copper-notification', diff --git a/functest/opnfv_tests/features/doctor.py b/functest/opnfv_tests/features/doctor.py index 4d295a67..d32bbfc9 100644 --- a/functest/opnfv_tests/features/doctor.py +++ b/functest/opnfv_tests/features/doctor.py @@ -13,10 +13,10 @@ # 0.2: measure test duration and publish results under json format # # -import functest.core.feature_base as base +import functest.core.feature as base -class Doctor(base.FeatureBase): +class Doctor(base.Feature): def __init__(self): super(Doctor, self).__init__(project='doctor', case='doctor-notification', diff --git a/functest/opnfv_tests/features/domino.py b/functest/opnfv_tests/features/domino.py index b36220fa..e34429bc 100644 --- a/functest/opnfv_tests/features/domino.py +++ b/functest/opnfv_tests/features/domino.py @@ -14,10 +14,10 @@ # 0.3: add report flag to push results when needed # 0.4: refactoring to match Test abstraction class -import functest.core.feature_base as base +import functest.core.feature as base -class Domino(base.FeatureBase): +class Domino(base.Feature): def __init__(self): super(Domino, self).__init__(project='domino', case='domino-multinode', diff --git a/functest/opnfv_tests/features/netready.py b/functest/opnfv_tests/features/netready.py index dec2a23c..88f377c2 100644 --- a/functest/opnfv_tests/features/netready.py +++ b/functest/opnfv_tests/features/netready.py @@ -8,10 +8,10 @@ # # -import functest.core.feature_base as base +import functest.core.feature as base -class GluonVping(base.FeatureBase): +class GluonVping(base.Feature): def __init__(self): super(GluonVping, self).__init__(project='netready', diff --git a/functest/opnfv_tests/features/odl_sfc.py b/functest/opnfv_tests/features/odl_sfc.py index 431cd47e..fff7f2b0 100644 --- a/functest/opnfv_tests/features/odl_sfc.py +++ b/functest/opnfv_tests/features/odl_sfc.py @@ -7,16 +7,14 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -import functest.core.feature_base as base -from sfc.tests.functest import run_tests +import functest.core.feature as base -class OpenDaylightSFC(base.FeatureBase): +class OpenDaylightSFC(base.Feature): def __init__(self): super(OpenDaylightSFC, self).__init__(project='sfc', case='functest-odl-sfc', repo='dir_repo_sfc') - - def execute(self): - return run_tests.main() + dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo) + self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest diff --git a/functest/opnfv_tests/features/promise.py b/functest/opnfv_tests/features/promise.py index 15636fbf..a7f4e628 100644 --- a/functest/opnfv_tests/features/promise.py +++ b/functest/opnfv_tests/features/promise.py @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import functest.core.feature_base as base +import functest.core.feature as base -class Promise(base.FeatureBase): +class Promise(base.Feature): def __init__(self): super(Promise, self).__init__(project='promise', case='promise', diff --git a/functest/opnfv_tests/features/sdnvpn.py b/functest/opnfv_tests/features/sdnvpn.py index 1919a03c..10e3146c 100644 --- a/functest/opnfv_tests/features/sdnvpn.py +++ b/functest/opnfv_tests/features/sdnvpn.py @@ -7,10 +7,10 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -import functest.core.feature_base as base +import functest.core.feature as base -class SdnVpnTests(base.FeatureBase): +class SdnVpnTests(base.Feature): def __init__(self): super(SdnVpnTests, self).__init__(project='sdnvpn', diff --git a/functest/opnfv_tests/features/security_scan.py b/functest/opnfv_tests/features/security_scan.py index 58f0ec74..2374b39f 100644 --- a/functest/opnfv_tests/features/security_scan.py +++ b/functest/opnfv_tests/features/security_scan.py @@ -8,11 +8,11 @@ # http://www.apache.org/licenses/LICENSE-2.0 # -import functest.core.feature_base as base +import functest.core.feature as base from functest.utils.constants import CONST -class SecurityScan(base.FeatureBase): +class SecurityScan(base.Feature): def __init__(self): super(SecurityScan, self).__init__(project='securityscanning', case='security_scan', diff --git a/functest/opnfv_tests/mano/orchestra.py b/functest/opnfv_tests/mano/orchestra.py index fd5e40d0..a9cf0ae6 100644 --- a/functest/opnfv_tests/mano/orchestra.py +++ b/functest/opnfv_tests/mano/orchestra.py @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import functest.core.feature_base as base +import functest.core.feature as base -class Orchestra(base.FeatureBase): +class Orchestra(base.Feature): def __init__(self): super(Orchestra, self).__init__(project='orchestra', case='orchestra', diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index 46d6a570..8c6abc15 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -17,7 +17,7 @@ import time import iniparse import yaml -from functest.core import testcase_base +from functest.core import testcase from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger import functest.utils.functest_utils as ft_utils @@ -26,7 +26,7 @@ import functest.utils.openstack_utils as os_utils logger = ft_logger.Logger('Rally').getLogger() -class RallyBase(testcase_base.TestcaseBase): +class RallyBase(testcase.TestCase): TESTS = ['authenticate', 'glance', 'cinder', 'heat', 'keystone', 'neutron', 'nova', 'quotas', 'requests', 'vm', 'all'] GLANCE_IMAGE_NAME = CONST.openstack_image_name @@ -526,10 +526,10 @@ class RallyBase(testcase_base.TestcaseBase): self._run_tests() self._generate_report() self._clean_up() - res = testcase_base.TestcaseBase.EX_OK + res = testcase.TestCase.EX_OK except Exception as e: logger.error('Error with run: %s' % e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR + res = testcase.TestCase.EX_RUN_ERROR self.stop_time = time.time() return res diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py index 4312b7f9..37aa9e39 100755 --- a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py +++ b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py @@ -12,18 +12,18 @@ import sys import subprocess import time -from functest.core import testcase_base +from functest.core import testcase from functest.opnfv_tests.openstack.tempest import conf_utils -from functest.utils import openstack_utils from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger import functest.utils.functest_utils as ft_utils +from tempest_conf import TempestConf """ logging configuration """ logger = ft_logger.Logger("refstack_defcore").getLogger() -class RefstackClient(testcase_base.TestcaseBase): +class RefstackClient(testcase.TestCase): def __init__(self): super(RefstackClient, self).__init__() @@ -35,12 +35,6 @@ class RefstackClient(testcase_base.TestcaseBase): self.CONF_PATH) self.defcorelist = os.path.join(self.FUNCTEST_TEST, self.DEFCORE_LIST) - self.VERIFIER_ID = conf_utils.get_verifier_id() - self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir( - self.VERIFIER_ID) - self.DEPLOYMENT_ID = conf_utils.get_verifier_deployment_id() - self.DEPLOYMENT_DIR = conf_utils.get_verifier_deployment_dir( - self.VERIFIER_ID, self.DEPLOYMENT_ID) def source_venv(self): @@ -143,59 +137,62 @@ class RefstackClient(testcase_base.TestcaseBase): logger.info("Testcase %s success_rate is %s%%, is marked as %s" % (self.case_name, success_rate, self.criteria)) - def defcore_env_prepare(self): - try: - img_flavor_dict = conf_utils.create_tempest_resources( - use_custom_images=True, use_custom_flavors=True) - conf_utils.configure_tempest_defcore( - self.DEPLOYMENT_DIR, img_flavor_dict) - self.source_venv() - res = testcase_base.TestcaseBase.EX_OK - except KeyError as e: - logger.error("defcore prepare env error with: %s", e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR - - return res - def run(self): + '''used for functest command line, + functest testcase run refstack_defcore''' self.start_time = time.time() if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR): os.makedirs(conf_utils.REFSTACK_RESULTS_DIR) try: - self.defcore_env_prepare() + tempestconf = TempestConf() + tempestconf.generate_tempestconf() + self.source_venv() self.run_defcore_default() self.parse_refstack_result() - res = testcase_base.TestcaseBase.EX_OK + res = testcase.TestCase.EX_OK except Exception as e: logger.error('Error with run: %s', e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR + res = testcase.TestCase.EX_RUN_ERROR self.stop_time = time.time() return res + def _prep_test(self): + '''Check that the config file exists.''' + if not os.path.isfile(self.confpath): + logger.error("Conf file not valid: %s" % self.confpath) + if not os.path.isfile(self.testlist): + logger.error("testlist file not valid: %s" % self.testlist) + def main(self, **kwargs): + '''used for manually running, + python refstack_client.py -c <tempest_conf_path> + --testlist <testlist_path> + can generate a reference tempest.conf by + python tempest_conf.py + ''' try: - tempestconf = kwargs['config'] - testlist = kwargs['testlist'] + self.confpath = kwargs['config'] + self.testlist = kwargs['testlist'] except KeyError as e: logger.error("Cannot run refstack client. Please check " "%s", e) return self.EX_RUN_ERROR try: - openstack_utils.source_credentials(CONST.openstack_creds) - self.defcore_env_prepare() - self.run_defcore(tempestconf, testlist) - res = testcase_base.TestcaseBase.EX_OK + self.source_venv() + self._prep_test() + self.run_defcore(self.confpath, self.testlist) + res = testcase.TestCase.EX_OK except Exception as e: logger.error('Error with run: %s', e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR + res = testcase.TestCase.EX_RUN_ERROR return res -class RefstackClientParser(testcase_base.TestcaseBase): +class RefstackClientParser(testcase.TestCase): def __init__(self): super(RefstackClientParser, self).__init__() @@ -228,7 +225,7 @@ if __name__ == '__main__': args = parser.parse_args(sys.argv[1:]) try: result = refstackclient.main(**args) - if result != testcase_base.TestcaseBase.EX_OK: + if result != testcase.TestCase.EX_OK: sys.exit(result) except Exception: - sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR) + sys.exit(testcase.TestCase.EX_RUN_ERROR) diff --git a/functest/opnfv_tests/openstack/refstack_client/tempest_conf.py b/functest/opnfv_tests/openstack/refstack_client/tempest_conf.py new file mode 100755 index 00000000..5624ed79 --- /dev/null +++ b/functest/opnfv_tests/openstack/refstack_client/tempest_conf.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# matthew.lijun@huawei.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +import sys + +from functest.core import testcase +from functest.opnfv_tests.openstack.tempest import conf_utils +from functest.utils import openstack_utils +from functest.utils.constants import CONST +import functest.utils.functest_logger as ft_logger + +""" logging configuration """ +logger = ft_logger.Logger("refstack_defcore").getLogger() + + +class TempestConf(object): + def __init__(self): + self.VERIFIER_ID = conf_utils.get_verifier_id() + self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir( + self.VERIFIER_ID) + self.DEPLOYMENT_ID = conf_utils.get_verifier_deployment_id() + self.DEPLOYMENT_DIR = conf_utils.get_verifier_deployment_dir( + self.VERIFIER_ID, self.DEPLOYMENT_ID) + + def generate_tempestconf(self): + try: + openstack_utils.source_credentials(CONST.openstack_creds) + img_flavor_dict = conf_utils.create_tempest_resources( + use_custom_images=True, use_custom_flavors=True) + conf_utils.configure_tempest_defcore( + self.DEPLOYMENT_DIR, img_flavor_dict) + except KeyError as e: + logger.error("defcore prepare env error with: %s", e) + + def main(self): + try: + self.generate_tempestconf() + res = testcase.TestCase.EX_OK + except Exception as e: + logger.error('Error with run: %s', e) + res = testcase.TestCase.EX_RUN_ERROR + + return res + +if __name__ == '__main__': + tempestconf = TempestConf() + result = tempestconf.main() + if result != testcase.TestCase.EX_OK: + sys.exit(result) diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt index 43edabc1..75bbd749 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt @@ -71,3 +71,15 @@ - fuel tests: - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops + + + # https://bugs.opendaylight.org/show_bug.cgi?id=5586 + scenarios: + - os-odl-bgpvpn-ha + - os-odl-gluon-noha + - os-odl_l2-bgpvpn-ha + installers: + - apex + - fuel + tests: + - tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 54556a32..0addbd17 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -16,7 +16,7 @@ import time import yaml -from functest.core import testcase_base +from functest.core import testcase from functest.opnfv_tests.openstack.tempest import conf_utils from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger @@ -26,7 +26,7 @@ import functest.utils.functest_utils as ft_utils logger = ft_logger.Logger("Tempest").getLogger() -class TempestCommon(testcase_base.TestcaseBase): +class TempestCommon(testcase.TestCase): def __init__(self): super(TempestCommon, self).__init__() @@ -223,10 +223,10 @@ class TempestCommon(testcase_base.TestcaseBase): self.apply_tempest_blacklist() self.run_verifier_tests() self.parse_verifier_result() - res = testcase_base.TestcaseBase.EX_OK + res = testcase.TestCase.EX_OK except Exception as e: logger.error('Error with run: %s' % e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR + res = testcase.TestCase.EX_RUN_ERROR self.stop_time = time.time() return res diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py index 9d57cfae..584ded38 100644 --- a/functest/opnfv_tests/openstack/vping/vping_base.py +++ b/functest/opnfv_tests/openstack/vping/vping_base.py @@ -12,12 +12,12 @@ import pprint import time from datetime import datetime -import functest.core.testcase_base as testcase_base +import functest.core.testcase as testcase import functest.utils.openstack_utils as os_utils from functest.utils.constants import CONST -class VPingBase(testcase_base.TestcaseBase): +class VPingBase(testcase.TestCase): def __init__(self): super(VPingBase, self).__init__() self.logger = None @@ -52,23 +52,23 @@ class VPingBase(testcase_base.TestcaseBase): def run(self, **kwargs): if not self.check_repo_exist(): - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR image_id = self.create_image() if not image_id: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR flavor = self.get_flavor() if not flavor: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR network_id = self.create_network_full() if not network_id: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR sg_id = self.create_security_group() if not sg_id: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR self.delete_exist_vms() @@ -84,7 +84,7 @@ class VPingBase(testcase_base.TestcaseBase): None, sg_id) if not vm1: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR test_ip = self.get_test_ip(vm1) vm2 = self.boot_vm(self.vm2_name, @@ -94,17 +94,17 @@ class VPingBase(testcase_base.TestcaseBase): test_ip, sg_id) if not vm2: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR EXIT_CODE = self.do_vping(vm2, test_ip) - if EXIT_CODE == testcase_base.TestcaseBase.EX_RUN_ERROR: + if EXIT_CODE == testcase.TestCase.EX_RUN_ERROR: return EXIT_CODE self.stop_time = time.time() self.parse_result(EXIT_CODE, self.start_time, self.stop_time) - return testcase_base.TestcaseBase.EX_OK + return testcase.TestCase.EX_OK def boot_vm_preparation(self, config, vmname, test_ip): pass diff --git a/functest/opnfv_tests/openstack/vping/vping_ssh.py b/functest/opnfv_tests/openstack/vping/vping_ssh.py index 7a58a41f..fc2f01c6 100755 --- a/functest/opnfv_tests/openstack/vping/vping_ssh.py +++ b/functest/opnfv_tests/openstack/vping/vping_ssh.py @@ -19,7 +19,7 @@ from scp import SCPClient import functest.utils.functest_logger as ft_logger import functest.utils.openstack_utils as os_utils import vping_base -import functest.core.testcase_base as testcase_base +import functest.core.testcase as testcase class VPingSSH(vping_base.VPingBase): @@ -32,12 +32,12 @@ class VPingSSH(vping_base.VPingBase): def do_vping(self, vm, test_ip): floatip = self.add_float_ip(vm) if not floatip: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR ssh = self.establish_ssh(vm, floatip) if not ssh: - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR if not self.transfer_ping_script(ssh, floatip): - return testcase_base.TestcaseBase.EX_RUN_ERROR + return testcase.TestCase.EX_RUN_ERROR return self.do_vping_ssh(ssh, test_ip) def add_float_ip(self, vm): diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py index c8e9c492..ccc1101a 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 @@ -20,12 +29,15 @@ 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 <cedric.ollivier@orange.com>" + class ODLResultVisitor(robot.api.ResultVisitor): + """Visitor to get result details.""" def __init__(self): self._data = [] @@ -43,10 +55,12 @@ class ODLResultVisitor(robot.api.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") @@ -59,11 +73,17 @@ class ODLTests(testcase_base.TestcaseBase): logger = ft_logger.Logger("opendaylight").getLogger() def __init__(self): - testcase_base.TestcaseBase.__init__(self) + testcase.TestCase.__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: @@ -74,11 +94,12 @@ 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 = robot.api.ExecutionResult(xml_file) visitor = ODLResultVisitor() @@ -90,8 +111,38 @@ class ODLTests(testcase_base.TestcaseBase): self.details['description'] = result.suite.name self.details['tests'] = visitor.get_data() - def main(self, suites=default_suites, **kwargs): + 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'] osauthurl = kwargs['osauthurl'] @@ -105,17 +156,17 @@ class ODLTests(testcase_base.TestcaseBase): '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') @@ -131,19 +182,31 @@ 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, **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: suites = self.default_suites try: @@ -176,19 +239,20 @@ class ODLTests(testcase_base.TestcaseBase): 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(suites, **kwargs) -class ODLParser(object): +class ODLParser(object): # pylint: disable=too-few-public-methods + """Parser to run ODL test suites.""" def __init__(self): self.parser = argparse.ArgumentParser() @@ -226,19 +290,28 @@ class ODLParser(object): '-p', '--pushtodb', help='Push results to DB', action='store_true') - def parse_args(self, argv=[]): + 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__': - odl = ODLTests() - parser = ODLParser() - args = parser.parse_args(sys.argv[1:]) + ODL = ODLTests() + PARSER = ODLParser() + ARGS = PARSER.parse_args(sys.argv[1:]) try: - result = odl.main(ODLTests.default_suites, **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) diff --git a/functest/opnfv_tests/sdn/onos/onos.py b/functest/opnfv_tests/sdn/onos/onos.py index 8bc73832..d482ae32 100644 --- a/functest/opnfv_tests/sdn/onos/onos.py +++ b/functest/opnfv_tests/sdn/onos/onos.py @@ -14,7 +14,7 @@ import shutil import time import urlparse -from functest.core import testcase_base +from functest.core import testcase from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger import functest.utils.functest_utils as ft_utils @@ -24,7 +24,7 @@ import functest.utils.openstack_utils as openstack_utils logger = ft_logger.Logger(__name__).getLogger() -class OnosBase(testcase_base.TestcaseBase): +class OnosBase(testcase.TestCase): onos_repo_path = CONST.dir_repo_onos onos_sfc_image_name = CONST.onos_sfc_image_name onos_sfc_image_path = os.path.join(CONST.dir_functest_data, @@ -39,10 +39,10 @@ class OnosBase(testcase_base.TestcaseBase): self.start_time = time.time() try: self._run() - res = testcase_base.TestcaseBase.EX_OK + res = testcase.TestCase.EX_OK except Exception as e: logger.error('Error with run: %s', e) - res = testcase_base.TestcaseBase.EX_RUN_ERROR + res = testcase.TestCase.EX_RUN_ERROR self.stop_time = time.time() return res diff --git a/functest/opnfv_tests/vnf/aaa/aaa.py b/functest/opnfv_tests/vnf/aaa/aaa.py index f1c265f4..bdedcf7c 100755 --- a/functest/opnfv_tests/vnf/aaa/aaa.py +++ b/functest/opnfv_tests/vnf/aaa/aaa.py @@ -11,7 +11,7 @@ import sys import argparse -import functest.core.testcase_base as testcase_base +import functest.core.testcase as testcase import functest.core.vnf_base as vnf_base import functest.utils.functest_logger as ft_logger @@ -62,9 +62,9 @@ if __name__ == '__main__': aaa_vnf = AaaVnf() try: result = aaa_vnf.main(**args) - if result != testcase_base.TestcaseBase.EX_OK: + if result != testcase.TestCase.EX_OK: sys.exit(result) if args['pushtodb']: sys.exit(aaa_vnf.push_to_db()) except Exception: - sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR) + sys.exit(testcase.TestCase.EX_RUN_ERROR) diff --git a/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py b/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py new file mode 100644 index 00000000..f21ce3f9 --- /dev/null +++ b/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 All rights reserved +# This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# +# http://www.apache.org/licenses/LICENSE-2.0 +import json +import os +import shutil + +import requests + +import functest.core.vnf_base as vnf_base +from functest.utils.constants import CONST +import functest.utils.functest_logger as ft_logger +import functest.utils.functest_utils as ft_utils + + +class ClearwaterOnBoardingBase(vnf_base.VnfOnBoardingBase): + + def __init__(self, project='functest', case='', repo='', cmd=''): + self.logger = ft_logger.Logger(__name__).getLogger() + super(ClearwaterOnBoardingBase, self).__init__( + project, case, repo, cmd) + self.case_dir = os.path.join(CONST.dir_functest_test, 'vnf', 'ims') + self.data_dir = CONST.dir_ims_data + self.result_dir = os.path.join(CONST.dir_results, case) + self.test_dir = CONST.dir_repo_vims_test + + if not os.path.exists(self.data_dir): + os.makedirs(self.data_dir) + if not os.path.exists(self.result_dir): + os.makedirs(self.result_dir) + + def config_ellis(self, ellis_ip, signup_code='secret', two_numbers=False): + output_dict = {} + self.logger.info('Configure Ellis: %s', ellis_ip) + output_dict['ellis_ip'] = ellis_ip + account_url = 'http://{0}/accounts'.format(ellis_ip) + params = {"password": "functest", + "full_name": "opnfv functest user", + "email": "functest@opnfv.org", + "signup_code": signup_code} + rq = requests.post(account_url, data=params) + output_dict['login'] = params + if rq.status_code != 201 and rq.status_code != 409: + raise Exception("Unable to create an account for number" + " provision: %s" % rq.json()['reason']) + self.logger.info('Account is created on Ellis: %s', params) + + session_url = 'http://{0}/session'.format(ellis_ip) + session_data = { + 'username': params['email'], + 'password': params['password'], + 'email': params['email'] + } + rq = requests.post(session_url, data=session_data) + if rq.status_code != 201: + raise Exception('Failed to get cookie for Ellis') + cookies = rq.cookies + self.logger.info('Cookies: %s' % cookies) + + number_url = 'http://{0}/accounts/{1}/numbers'.format( + ellis_ip, + params['email']) + self.logger.info('Create 1st calling number on Ellis') + number_res = self.create_ellis_number(number_url, cookies) + output_dict['number'] = number_res + + if two_numbers: + self.logger.info('Create 2nd calling number on Ellis') + number_res = self.create_ellis_number(number_url, cookies) + output_dict['number2'] = number_res + + return output_dict + + def create_ellis_number(self, number_url, cookies): + rq = requests.post(number_url, cookies=cookies) + + if rq.status_code != 200: + if rq and rq.json(): + reason = rq.json()['reason'] + else: + reason = rq + raise Exception("Unable to create a number: %s" % reason) + number_res = rq.json() + self.logger.info('Calling number is created: %s', number_res) + return number_res + + def run_clearwater_live_test(self, dns_ip, public_domain, + bono_ip=None, ellis_ip=None, + signup_code='secret'): + self.logger.info('Run Clearwater live test') + nameservers = ft_utils.get_resolvconf_ns() + resolvconf = ['{0}{1}{2}'.format(os.linesep, 'nameserver ', ns) + for ns in nameservers] + self.logger.debug('resolvconf: %s', resolvconf) + dns_file = '/etc/resolv.conf' + dns_file_bak = '/etc/resolv.conf.bak' + shutil.copy(dns_file, dns_file_bak) + script = ('echo -e "nameserver {0}{1}" > {2};' + 'source /etc/profile.d/rvm.sh;' + 'cd {3};' + 'rake test[{4}] SIGNUP_CODE={5}' + .format(dns_ip, + ''.join(resolvconf), + dns_file, + self.test_dir, + public_domain, + signup_code)) + if bono_ip and ellis_ip: + subscript = ' PROXY={0} ELLIS={1}'.format(bono_ip, ellis_ip) + script = '{0}{1}'.format(script, subscript) + script = ('{0}{1}'.format(script, ' --trace')) + cmd = "/bin/bash -c '{0}'".format(script) + self.logger.info('Live test cmd: %s', cmd) + output_file = os.path.join(self.result_dir, "ims_test_output.txt") + ft_utils.execute_command(cmd, + error_msg='Clearwater live test failed', + output_file=output_file) + + with open(dns_file_bak, 'r') as bak_file: + result = bak_file.read() + with open(dns_file, 'w') as f: + f.write(result) + + f = open(output_file, 'r') + result = f.read() + if result != "": + self.logger.debug(result) + + vims_test_result = "" + tempFile = os.path.join(self.test_dir, "temp.json") + try: + self.logger.debug("Trying to load test results") + with open(tempFile) as f: + vims_test_result = json.load(f) + f.close() + except Exception: + self.logger.error("Unable to retrieve test results") + + try: + os.remove(tempFile) + except Exception: + self.logger.error("Deleting file failed") + + return vims_test_result diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py index f7dfd532..404f208e 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py @@ -7,42 +7,37 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 -import json import os -import requests -import subprocess import sys import time + +import requests import yaml -import functest.core.vnf_base as vnf_base +from functest.opnfv_tests.vnf.ims.clearwater import Clearwater +import functest.opnfv_tests.vnf.ims.clearwater_ims_base as clearwater_ims_base +from functest.opnfv_tests.vnf.ims.orchestrator_cloudify import Orchestrator +from functest.utils.constants import CONST import functest.utils.functest_logger as ft_logger import functest.utils.functest_utils as ft_utils import functest.utils.openstack_utils as os_utils -from clearwater import Clearwater -from functest.utils.constants import CONST -from orchestrator_cloudify import Orchestrator - -class ImsVnf(vnf_base.VnfOnBoardingBase): +class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase): def __init__(self, project='functest', case='cloudify_ims', repo='', cmd=''): - super(ImsVnf, self).__init__(project, case, repo, cmd) - self.logger = ft_logger.Logger("vIMS").getLogger() - self.case_dir = os.path.join(CONST.dir_functest_test, 'vnf/ims/') - self.data_dir = CONST.dir_ims_data - self.test_dir = CONST.dir_repo_vims_test + super(CloudifyIms, self).__init__(project, case, repo, cmd) + self.logger = ft_logger.Logger(__name__).getLogger() # Retrieve the configuration try: self.config = CONST.__getattribute__( 'vnf_{}_config'.format(self.case_name)) - except: + except Exception: raise Exception("VNF config file not found") - config_file = self.case_dir + self.config + config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict( requirements=get_config("cloudify.requirements", config_file), blueprint=get_config("cloudify.blueprint", config_file), @@ -61,10 +56,6 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): self.images = get_config("tenant_images", config_file) self.logger.info("Images needed for vIMS: %s" % self.images) - # vIMS Data directory creation - if not os.path.exists(self.data_dir): - os.makedirs(self.data_dir) - def deploy_orchestrator(self, **kwargs): self.logger.info("Additional pre-configuration steps") @@ -82,7 +73,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): image_id = os_utils.get_image_id(self.glance_client, image_name) self.logger.debug("image_id: %s" % image_id) - except: + except Exception: self.logger.error("Unexpected error: %s" % sys.exc_info()[0]) if image_id == '': @@ -177,10 +168,11 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): self.logger.debug("Resolvconf set") self.logger.info("Prepare virtualenv for cloudify-cli") - cmd = "chmod +x " + self.case_dir + "create_venv.sh" + venv_scrit_dir = os.path.join(self.case_dir, "create_venv.sh") + cmd = "chmod +x " + venv_scrit_dir ft_utils.execute_command(cmd) time.sleep(3) - cmd = self.case_dir + "create_venv.sh " + self.data_dir + cmd = venv_scrit_dir + " " + self.data_dir ft_utils.execute_command(cmd) cfy.download_manager_blueprint( @@ -251,99 +243,25 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): self.logger.debug("Trying to get clearwater manager IP ... ") mgr_ip = os.popen(cmd).read() mgr_ip = mgr_ip.splitlines()[0] - except: + except Exception: self.step_failure("Unable to retrieve the IP of the " "cloudify manager server !") - api_url = "http://" + mgr_ip + "/api/v2" - dep_outputs = requests.get(api_url + "/deployments/" + - self.vnf['deployment_name'] + "/outputs") - dns_ip = dep_outputs.json()['outputs']['dns_ip'] - ellis_ip = dep_outputs.json()['outputs']['ellis_ip'] - - self.logger.debug("DNS ip : %s" % dns_ip) - self.logger.debug("ELLIS ip : %s" % ellis_ip) - - ellis_url = "http://" + ellis_ip + "/" - url = ellis_url + "accounts" - - params = {"password": "functest", - "full_name": "opnfv functest user", - "email": "functest@opnfv.fr", - "signup_code": "secret"} - - rq = requests.post(url, data=params) - i = 30 - while rq.status_code != 201 and i > 0: - rq = requests.post(url, data=params) - self.logger.debug("Account creation http status code: %s" - % rq.status_code) - i = i - 1 - time.sleep(10) - - if rq.status_code == 201: - url = ellis_url + "session" - rq = requests.post(url, data=params) - cookies = rq.cookies - else: - self.step_failure("Unable to create an account") - - url = ellis_url + "accounts/" + params['email'] + "/numbers" - if cookies != "": - rq = requests.post(url, cookies=cookies) - i = 24 - while rq.status_code != 200 and i > 0: - rq = requests.post(url, cookies=cookies) - self.logger.debug("Number creation http status code: %s" - % rq.status_code) - i = i - 1 - time.sleep(25) - - if rq.status_code != 200: - self.step_failure("Unable to create a number: %s" - % rq.json()['reason']) - - nameservers = ft_utils.get_resolvconf_ns() - resolvconf = "" - for ns in nameservers: - resolvconf += "\nnameserver " + ns + self.logger.info('Cloudify Manager: %s', mgr_ip) + api_url = 'http://{0}/api/v2/deployments/{1}/outputs'.format( + mgr_ip, self.vnf['deployment_name']) + dep_outputs = requests.get(api_url) + self.logger.info(api_url) + outputs = dep_outputs.json()['outputs'] + self.logger.info("Deployment outputs: %s", outputs) + dns_ip = outputs['dns_ip'] + ellis_ip = outputs['ellis_ip'] + self.config_ellis(ellis_ip) if dns_ip != "": - script = ('echo -e "nameserver ' + dns_ip + resolvconf + - '" > /etc/resolv.conf; ') - script += 'source /etc/profile.d/rvm.sh; ' - script += 'cd {0}; ' - script += ('rake test[{1}] SIGNUP_CODE="secret"') - - cmd = ("/bin/bash -c '" + - script.format(self.data_dir, self.inputs["public_domain"]) + - "'") - output_file = "output.txt" - f = open(output_file, 'w+') - subprocess.call(cmd, shell=True, stdout=f, - stderr=subprocess.STDOUT) - f.close() - - f = open(output_file, 'r') - result = f.read() - if result != "": - self.logger.debug(result) - - vims_test_result = "" - tempFile = os.path.join(self.test_dir, "temp.json") - try: - self.logger.debug("Trying to load test results") - with open(tempFile) as f: - vims_test_result = json.load(f) - f.close() - except: - self.logger.error("Unable to retrieve test results") - - try: - os.remove(tempFile) - except: - self.logger.error("Deleting file failed") - + vims_test_result = self.run_clearwater_live_test( + dns_ip=dns_ip, + public_domain=self.inputs["public_domain"]) if vims_test_result != '': return {'status': 'PASS', 'result': vims_test_result} else: @@ -352,7 +270,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): def clean(self): self.vnf['object'].undeploy_vnf() self.orchestrator['object'].undeploy_manager() - super(ImsVnf, self).clean() + super(CloudifyIms, self).clean() def main(self, **kwargs): self.logger.info("Cloudify IMS VNF onboarding test starting") diff --git a/functest/opnfv_tests/vnf/ims/opera_ims.py b/functest/opnfv_tests/vnf/ims/opera_ims.py index 7ead401f..d022b3c7 100755..100644 --- a/functest/opnfv_tests/vnf/ims/opera_ims.py +++ b/functest/opnfv_tests/vnf/ims/opera_ims.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2016 Orange and others. +# Copyright (c) 2017 HUAWEI TECHNOLOGIES CO.,LTD and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 @@ -8,381 +8,117 @@ # http://www.apache.org/licenses/LICENSE-2.0 import json -import socket -import sys +import os import time -import yaml -import functest.core.vnf_base as vnf_base -import functest.utils.functest_logger as ft_logger -import functest.utils.functest_utils as ft_utils -import functest.utils.openstack_utils as os_utils -import os +from opera import openo_connect +import requests + +import functest.opnfv_tests.vnf.ims.clearwater_ims_base as clearwater_ims_base from functest.utils.constants import CONST +import functest.utils.functest_logger as ft_logger -from org.openbaton.cli.agents.agents import MainAgent -from org.openbaton.cli.errors.errors import NfvoException +class OperaIms(clearwater_ims_base.ClearwaterOnBoardingBase): -def servertest(host, port): - args = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM) - for family, socktype, proto, canonname, sockaddr in args: - s = socket.socket(family, socktype, proto) + def __init__(self, project='functest', case='opera_ims', + repo=CONST.dir_repo_opera, cmd=''): + super(OperaIms, self).__init__(project, case, repo, cmd) + self.logger = ft_logger.Logger(__name__).getLogger() + self.ellis_file = os.path.join(self.result_dir, 'ellis.info') + self.live_test_file = os.path.join(self.result_dir, + 'live_test_report.json') try: - s.connect(sockaddr) - except socket.error: - return False + self.openo_msb_endpoint = os.environ['OPENO_MSB_ENDPOINT'] + except KeyError: + raise Exception('OPENO_MSB_ENDPOINT is not specified,' + ' put it as <OPEN-O ip>:<port>') else: - s.close() - return True - -# ---------------------------------------------------------- -# -# UTILS -# -# ----------------------------------------------------------- - - -def get_config(parameter, file): - """ - Returns the value of a given parameter in file.yaml - parameter must be given in string format with dots - Example: general.openstack.image_name - """ - with open(file) as f: - file_yaml = yaml.safe_load(f) - f.close() - value = file_yaml - for element in parameter.split("."): - value = value.get(element) - if value is None: - raise ValueError("The parameter %s is not defined in" - " reporting.yaml" % parameter) - return value - - -def download_and_add_image_on_glance(glance, image_name, - image_url, data_dir): - dest_path = data_dir - if not os.path.exists(dest_path): - os.makedirs(dest_path) - file_name = image_url.rsplit('/')[-1] - if not ft_utils.download_url(image_url, dest_path): - return False - image = os_utils.create_glance_image( - glance, image_name, dest_path + file_name) - if not image: - return False - return image - - -class ImsVnf(vnf_base.VnfOnBoardingBase): - - def __init__(self, project='functest', case='orchestra_ims', - repo='', cmd=''): - super(ImsVnf, self).__init__(project, case, repo, cmd) - self.ob_password = "openbaton" - self.ob_username = "admin" - self.ob_https = False - self.ob_port = "8080" - self.ob_ip = "localhost" - self.ob_instance_id = "" - self.logger = ft_logger.Logger("orchestra_ims").getLogger() - self.case_dir = os.path.join(CONST.dir_functest_test, 'vnf/ims/') - self.data_dir = CONST.dir_ims_data - self.test_dir = CONST.dir_repo_vims_test - self.ob_projectid = "" - self.keystone_client = os_utils.get_keystone_client() - self.ob_nsr_id = "" - self.main_agent = None - # vIMS Data directory creation - if not os.path.exists(self.data_dir): - os.makedirs(self.data_dir) - # Retrieve the configuration - try: - self.config = CONST.__getattribute__( - 'vnf_{}_config'.format(self.case_name)) - except: - raise Exception("Orchestra VNF config file not found") - config_file = self.case_dir + self.config - self.imagename = get_config("openbaton.imagename", config_file) - self.market_link = get_config("openbaton.marketplace_link", - config_file) - self.images = get_config("tenant_images", config_file) - - def deploy_orchestrator(self, **kwargs): - self.logger.info("Additional pre-configuration steps") - nova_client = os_utils.get_nova_client() - neutron_client = os_utils.get_neutron_client() - glance_client = os_utils.get_glance_client() - - # needs some images - self.logger.info("Upload some OS images if it doesn't exist") - temp_dir = os.path.join(self.data_dir, "tmp/") - for image_name, image_url in self.images.iteritems(): - self.logger.info("image: %s, url: %s" % (image_name, image_url)) - try: - image_id = os_utils.get_image_id(glance_client, - image_name) - self.logger.info("image_id: %s" % image_id) - except: - self.logger.error("Unexpected error: %s" % sys.exc_info()[0]) - - if image_id == '': - self.logger.info("""%s image doesn't exist on glance repository. Try - downloading this image and upload on glance !""" % image_name) - image_id = download_and_add_image_on_glance(glance_client, - image_name, - image_url, - temp_dir) - if image_id == '': - self.step_failure( - "Failed to find or upload required OS " - "image for this deployment") - network_dic = os_utils.create_network_full(neutron_client, - "openbaton_mgmt", - "openbaton_mgmt_subnet", - "openbaton_router", - "192.168.100.0/24") - - # orchestrator VM flavor - self.logger.info("Check medium Flavor is available, if not create one") - flavor_exist, flavor_id = os_utils.get_or_create_flavor( - "m1.medium", - "4096", - '1', - '2', - public=True) - self.logger.debug("Flavor id: %s" % flavor_id) - - if not network_dic: - self.logger.error("There has been a problem when creating the " - "neutron network") - - network_id = network_dic["net_id"] - - self.logger.info("Creating floating IP for VM in advance...") - floatip_dic = os_utils.create_floating_ip(neutron_client) - floatip = floatip_dic['fip_addr'] - - if floatip is None: - self.logger.error("Cannot create floating IP.") - - userdata = "#!/bin/bash\n" - userdata += "set -x\n" - userdata += "set -e\n" - userdata += "echo \"nameserver 8.8.8.8\" >> /etc/resolv.conf\n" - userdata += "apt-get install curl\n" - userdata += ("echo \"rabbitmq_broker_ip=%s\" > ./config_file\n" - % floatip) - userdata += "echo \"mysql=no\" >> ./config_file\n" - userdata += ("echo \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuPXrV3" - "geeHc6QUdyUr/1Z+yQiqLcOskiEGBiXr4z76MK4abiFmDZ18OMQlc" - "fl0p3kS0WynVgyaOHwZkgy/DIoIplONVr2CKBKHtPK+Qcme2PVnCtv" - "EqItl/FcD+1h5XSQGoa+A1TSGgCod/DPo+pes0piLVXP8Ph6QS1k7S" - "ic7JDeRQ4oT1bXYpJ2eWBDMfxIWKZqcZRiGPgMIbJ1iEkxbpeaAd9O" - "4MiM9nGCPESmed+p54uYFjwEDlAJZShcAZziiZYAvMZhvAhe6USljc" - "7YAdalAnyD/jwCHuwIrUw/lxo7UdNCmaUxeobEYyyFA1YVXzpNFZya" - "XPGAAYIJwEq/ openbaton@opnfv\" >> /home/ubuntu/.ssh/aut" - "horized_keys\n") - userdata += "cat ./config_file\n" - userdata += ("curl -s http://get.openbaton.org/bootstrap " - "> ./bootstrap\n") - userdata += "export OPENBATON_COMPONENT_AUTOSTART=false\n" - bootstrap = "sh ./bootstrap release -configFile=./config_file" - userdata += bootstrap + "\n" - - userdata += ("echo \"nfvo.plugin.timeout=300000\" >> " - "/etc/openbaton/openbaton-nfvo.properties\n") - userdata += "service openbaton-nfvo restart\n" - userdata += "service openbaton-vnfm-generic restart\n" - - sg_id = os_utils.create_security_group_full(neutron_client, - "orchestra-sec-group", - "allowall") - - os_utils.create_secgroup_rule(neutron_client, sg_id, "ingress", - "icmp", 0, 255) - os_utils.create_secgroup_rule(neutron_client, sg_id, "egress", - "icmp", 0, 255) - os_utils.create_secgroup_rule(neutron_client, sg_id, "ingress", - "tcp", 1, 65535) - os_utils.create_secgroup_rule(neutron_client, sg_id, "ingress", - "udp", 1, 65535) - os_utils.create_secgroup_rule(neutron_client, sg_id, "egress", - "tcp", 1, 65535) - os_utils.create_secgroup_rule(neutron_client, sg_id, "egress", - "udp", 1, 65535) - - self.logger.info("Security group set") - - self.logger.info("Create instance....") - self.logger.info("flavor: m1.medium\n" - "image: %s\n" - "network_id: %s\n" - "userdata: %s\n" - % (self.imagename, network_id, userdata)) - - instance = os_utils.create_instance_and_wait_for_active( - "m1.medium", - os_utils.get_image_id(glance_client, self.imagename), - network_id, - "orchestra-openbaton", - config_drive=False, - userdata=userdata) + self.logger.info('OPEN-O endpoint is: %s', self.openo_msb_endpoint) - self.ob_instance_id = instance.id + def prepare(self): + pass - self.logger.info("Adding sec group to orchestra instance") - os_utils.add_secgroup_to_instance(nova_client, - self.ob_instance_id, sg_id) - - self.logger.info("Associating floating ip: '%s' to VM '%s' " - % (floatip, "orchestra-openbaton")) - if not os_utils.add_floating_ip(nova_client, instance.id, floatip): - self.logger.error("Cannot associate floating IP to VM.") - self.step_failure("Cannot associate floating IP to VM.") - - self.logger.info("Waiting for nfvo to be up and running...") - x = 0 - while x < 100: - if servertest(floatip, "8080"): - break - else: - self.logger.debug("openbaton is not started yet") - time.sleep(5) - x += 1 - - if x == 100: - self.logger.error("Openbaton is not started correctly") - self.step_failure("Openbaton is not started correctly") - - self.ob_ip = floatip - self.ob_password = "openbaton" - self.ob_username = "admin" - self.ob_https = False - self.ob_port = "8080" - - self.logger.info("Deploy orchestrator: OK") + def clean(self): + pass def deploy_vnf(self): - self.logger.info("vIMS Deployment") - - self.main_agent = MainAgent(nfvo_ip=self.ob_ip, - nfvo_port=self.ob_port, - https=self.ob_https, - version=1, - username=self.ob_username, - password=self.ob_password) - - project_agent = self.main_agent.get_agent("project", self.ob_projectid) - for p in json.loads(project_agent.find()): - if p.get("name") == "default": - self.ob_projectid = p.get("id") - break - - self.logger.debug("project id: %s" % self.ob_projectid) - if self.ob_projectid == "": - self.logger.error("Default project id was not found!") - self.step_failure("Default project id was not found!") - - vim_json = { - "name": "vim-instance", - "authUrl": os_utils.get_credentials().get("auth_url"), - "tenant": os_utils.get_credentials().get("tenant_name"), - "username": os_utils.get_credentials().get("username"), - "password": os_utils.get_credentials().get("password"), - # "keyPair": "opnfv", - # TODO change the keypair to correct value - # or upload a correct one or remove it - "securityGroups": [ - "default", - "orchestra-sec-group" - ], - "type": "openstack", - "location": { - "name": "opnfv", - "latitude": "52.525876", - "longitude": "13.314400" - } - } - - self.logger.debug("vim: %s" % vim_json) - - self.main_agent.get_agent( - "vim", - project_id=self.ob_projectid).create(entity=json.dumps(vim_json)) - - market_agent = self.main_agent.get_agent("market", - project_id=self.ob_projectid) - - nsd = {} - try: - self.logger.info("sending: %s" % self.market_link) - nsd = market_agent.create(entity=self.market_link) - self.logger.info("Onboarded nsd: " + nsd.get("name")) - except NfvoException as e: - self.step_failure(e.message) - - nsr_agent = self.main_agent.get_agent("nsr", - project_id=self.ob_projectid) - nsd_id = nsd.get('id') - if nsd_id is None: - self.step_failure("NSD not onboarded correctly") - - nsr = None try: - nsr = nsr_agent.create(nsd_id) - except NfvoException as e: - self.step_failure(e.message) - - if nsr.get('code') is not None: - self.logger.error( - "vIMS cannot be deployed: %s -> %s" % - (nsr.get('code'), nsr.get('message'))) - self.step_failure("vIMS cannot be deployed") - - i = 0 - self.logger.info("waiting NSR to go to active...") - while nsr.get("status") != 'ACTIVE' and nsr.get("status") != 'ERROR': - i += 1 - if i == 100: - self.step_failure("After %s sec the nsr did not go to active.." - % 5 * 100) - time.sleep(5) - nsr = json.loads(nsr_agent.find(nsr.get('id'))) - - if nsr.get("status") == 'ACTIVE': - deploy_vnf = {'status': "PASS", 'result': nsr} - self.logger.info("Deploy VNF: OK") + openo_connect.create_service(self.openo_msb_endpoint, + 'functest_opera', + 'VNF for functest testing') + except Exception as e: + self.logger.error(e) + return {'status': 'FAIL', 'result': e} else: - deploy_vnf = {'status': "FAIL", 'result': nsr} - self.logger.error("Deploy VNF: ERROR") - self.step_failure("Deploy vIMS failed") - self.ob_nsr_id = nsr.get("id") - return deploy_vnf + self.logger.info('vIMS deployment is kicked off') + return {'status': 'PASS', 'result': ''} - def test_vnf(self): - # Adaptations probably needed - # code used for cloudify_ims - # ruby client on jumphost calling the vIMS on the SUT - return + def dump_info(self, info_file, result): + with open(info_file, 'w') as f: + self.logger.debug('Save information to file: %s', info_file) + json.dump(result, f) - def clean(self): - self.main_agent.get_agent( - "nsr", - project_id=self.ob_projectid).delete(self.ob_nsr_id) - time.sleep(5) - os_utils.delete_instance(nova_client=os_utils.get_nova_client(), - instance_id=self.ob_instance_id) - # TODO question is the clean removing also the VM? - # I think so since is goinf to remove the tenant... - super(ImsVnf, self).clean() + def test_vnf(self): + vnfm_ip = openo_connect.get_vnfm_ip(self.openo_msb_endpoint) + self.logger.info('VNFM IP: %s', vnfm_ip) + vnf_status_url = 'http://{0}:5000/api/v1/model/status'.format(vnfm_ip) + vnf_alive = False + retry = 15 + + self.logger.info('Check the VNF status') + while retry > 0: + rq = requests.get(vnf_status_url) + response = rq.json() + vnf_alive = response['vnf_alive'] + msg = response['msg'] + self.logger.info(msg) + if vnf_alive: + break + self.logger.info('check again in one minute...') + retry = retry - 1 + time.sleep(60) + + if not vnf_alive: + raise Exception('VNF failed to start: {0}'.format(msg)) + + ellis_config_url = ('http://{0}:5000/api/v1/model/ellis/configure' + .format(vnfm_ip)) + rq = requests.get(ellis_config_url, timeout=60) + if rq.json() and not rq.json()['ellis_ok']: + self.logger.error(rq.json()['data']) + raise Exception('Failed to configure Ellis') + + self.logger.info('Get Clearwater deployment detail') + vnf_info_url = ('http://{0}:5000/api/v1/model/output' + .format(vnfm_ip)) + rq = requests.get(vnf_info_url, timeout=60) + data = rq.json()['data'] + self.logger.info(data) + bono_ip = data['bono_ip'] + ellis_ip = data['ellis_ip'] + dns_ip = data['dns_ip'] + result = self.config_ellis(ellis_ip, 'signup', True) + self.logger.debug('Ellis Result: %s', result) + self.dump_info(self.ellis_file, result) + + if dns_ip: + vims_test_result = self.run_clearwater_live_test( + dns_ip, + 'clearwater.local', + bono_ip, + ellis_ip, + 'signup') + if vims_test_result != '': + self.dump_info(self.live_test_file, vims_test_result) + return {'status': 'PASS', 'result': vims_test_result} + else: + return {'status': 'FAIL', 'result': ''} def main(self, **kwargs): - self.logger.info("Orchestra IMS VNF onboarding test starting") + self.logger.info("Start to run Opera vIMS VNF onboarding test") self.execute() - self.logger.info("Orchestra IMS VNF onboarding test executed") + self.logger.info("Opera vIMS VNF onboarding test finished") if self.criteria is "PASS": return self.EX_OK else: @@ -391,10 +127,3 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): def run(self): kwargs = {} return self.main(**kwargs) - - -if __name__ == '__main__': - test = ImsVnf() - test.deploy_orchestrator() - test.deploy_vnf() - test.clean() diff --git a/functest/opnfv_tests/vnf/rnc/parser.py b/functest/opnfv_tests/vnf/rnc/parser.py index 1cff7220..133145d7 100644 --- a/functest/opnfv_tests/vnf/rnc/parser.py +++ b/functest/opnfv_tests/vnf/rnc/parser.py @@ -15,10 +15,10 @@ # limitations under the License. # -import functest.core.feature_base as base +import functest.core.feature as base -class Parser(base.FeatureBase): +class Parser(base.Feature): def __init__(self): super(Parser, self).__init__(project='parser', case='parser-basics', diff --git a/functest/opnfv_tests/vnf/router/vyos_vrouter.py b/functest/opnfv_tests/vnf/router/vyos_vrouter.py index 94a3ecfd..e188c3fb 100644 --- a/functest/opnfv_tests/vnf/router/vyos_vrouter.py +++ b/functest/opnfv_tests/vnf/router/vyos_vrouter.py @@ -6,16 +6,16 @@ # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 -import functest.core.feature_base as base +import functest.core.feature as base import json import os RESULT_DETAILS_FILE = "test_result.json" -class VrouterVnf(base.FeatureBase): +class VrouterVnf(base.Feature): def __init__(self): - super(VrouterVnf, self).__init__(project='vRouter', + super(VrouterVnf, self).__init__(project='functest', case='vyos_vrouter', repo='dir_repo_vrouter') self.cmd = 'cd %s && ./run.sh' % self.repo |