diff options
-rw-r--r-- | docker/Dockerfile | 12 | ||||
-rwxr-xr-x | functest/ci/config_functest.yaml | 107 | ||||
-rwxr-xr-x | functest/ci/testcases.yaml | 71 | ||||
-rw-r--r-- | functest/core/vnf_base.py | 246 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/copper.py | 2 | ||||
-rwxr-xr-x | functest/opnfv_tests/mano/orchestra.py | 24 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/aaa/__init__.py | 0 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/aaa/aaa.py | 71 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/__init__.py | 0 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/cloudify_ims.py | 277 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/opera_ims.py | 154 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/orchestra_ims.py | 156 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py (renamed from functest/opnfv_tests/vnf/ims/orchestrator.py) | 0 | ||||
-rwxr-xr-x | functest/opnfv_tests/vnf/ims/vims.py | 506 | ||||
-rw-r--r-- | functest/tests/unit/core/test_vnf_base.py | 52 | ||||
-rw-r--r-- | functest/utils/functest_constants.py | 5 |
16 files changed, 1115 insertions, 568 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile index 0b7ca19e4..dce657e8e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -43,6 +43,7 @@ ARG FUNCTEST_RESULTS_DIR=${FUNCTEST_BASE_DIR}/results ARG FUNCTEST_REPO_DIR=${REPOS_DIR}/functest ARG FUNCTEST_TEST_DIR=${FUNCTEST_REPO_DIR}/functest/opnfv_tests ARG RELENG_MODULE_DIR=${REPOS_DIR}/releng/modules +ARG REPOS_VNFS_DIR=${REPOS_DIR}/vnfs # Environment variables ENV HOME /home/opnfv @@ -81,6 +82,7 @@ wget \ RUN pip install --upgrade pip RUN mkdir -p ${REPOS_DIR} \ + && mkdir -p ${REPOS_VNFS_DIR} \ && mkdir -p ${FUNCTEST_BASE_DIR}/results \ && mkdir -p ${FUNCTEST_BASE_DIR}/conf \ && mkdir -p /root/.ssh \ @@ -110,7 +112,7 @@ RUN git clone --depth 1 -b $TEMPEST_TAG https://github.com/openstack/tempest.git # other repositories RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git ${REPOS_DIR}/odl_test -RUN git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test ${REPOS_DIR}/vims-test +RUN git clone --depth 1 -b $VIMS_TAG https://github.com/boucherv-orange/clearwater-live-test ${REPOS_VNFS_DIR}/vims-test RUN git clone --depth 1 https://github.com/wuwenbin2/OnosSystemTest.git ${REPOS_DIR}/onos RUN cd ${FUNCTEST_REPO_DIR} \ @@ -153,16 +155,16 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install . RUN cd ${REPOS_DIR}/moon/moonclient/ && python setup.py install RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ - && cd ${REPOS_DIR}/vims-test \ + && cd ${REPOS_VNFS_DIR}/vims-test \ && rvm autolibs enable" RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ - && cd ${REPOS_DIR}/vims-test \ + && cd ${REPOS_VNFS_DIR}/vims-test \ && rvm install 1.9.3" RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ - && cd ${REPOS_DIR}/vims-test \ + && cd ${REPOS_VNFS_DIR}/vims-test \ && rvm use 1.9.3" RUN /bin/bash -c ". /etc/profile.d/rvm.sh \ - && cd ${REPOS_DIR}/vims-test \ + && cd ${REPOS_VNFS_DIR}/vims-test \ && bundle install" RUN sh -c 'curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -' \ diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml index a67b03ed8..25be17240 100755 --- a/functest/ci/config_functest.yaml +++ b/functest/ci/config_functest.yaml @@ -16,7 +16,7 @@ general: dir_repo_rally: /home/opnfv/repos/rally repo_tempest: /home/opnfv/repos/tempest dir_repo_releng: /home/opnfv/repos/releng - dir_repo_vims_test: /home/opnfv/repos/vims-test + repo_vims_test: /home/opnfv/repos/vnfs/vims-test repo_sdnvpn: /home/opnfv/repos/sdnvpn repo_sfc: /home/opnfv/repos/sfc dir_repo_onos: /home/opnfv/repos/onos @@ -110,53 +110,64 @@ rally: subnet_cidr: 192.168.140.0/24 router_name: rally-router -vIMS: - general: - tenant_name: vIMS - tenant_description: vIMS Functionality Testing - images: - ubuntu: - image_url: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img - image_name: ubuntu_14.04 - centos: - image_url: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1510.qcow2 - image_name: centos_7 - cloudify: - blueprint: - url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git - branch: "3.3.1-build" - requierments: - ram_min: 3000 - os_image: centos_7 - inputs: - keystone_username: "" - keystone_password: "" - keystone_tenant_name: "" - keystone_url: "" - manager_public_key_name: 'manager-kp' - agent_public_key_name: 'agent-kp' - image_id: "" - flavor_id: "3" - external_network_name: "" - ssh_user: centos - agents_user: ubuntu - clearwater: - blueprint: - file_name: 'openstack-blueprint.yaml' - name: "clearwater-opnfv" - destination_folder: "opnfv-cloudify-clearwater" - url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git - branch: "stable" - deployment-name: 'clearwater-opnfv' - requierments: - ram_min: 1700 - os_image: ubuntu_14.04 - inputs: - image_id: '' - flavor_id: '' - agent_user: 'ubuntu' - external_network_name: '' - public_domain: clearwater.opnfv +vnf: + aaa: + tenant_name: aaa + tenant_description: Freeradius server + tenant_images: {} + juju_epc: + tenant_name: epc + tenant_description: OAI EPC deployed with Juju + tenant_images: {} + cloudify_ims: + tenant_name: cloudify_ims + tenant_description: vIMS + tenant_images: + ubuntu_14.04: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img + centos_7: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1510.qcow2 + cloudify: + blueprint: + url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git + branch: "3.3.1-build" + requierments: + ram_min: 3000 + os_image: centos_7 + inputs: + keystone_username: "" + keystone_password: "" + keystone_tenant_name: "" + keystone_url: "" + manager_public_key_name: 'manager-kp' + agent_public_key_name: 'agent-kp' + image_id: "" + flavor_id: "3" + external_network_name: "" + ssh_user: centos + agents_user: ubuntu + clearwater: + blueprint: + file_name: 'openstack-blueprint.yaml' + name: "clearwater-opnfv" + destination_folder: "opnfv-cloudify-clearwater" + url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git + branch: "stable" + deployment_name: 'clearwater-opnfv' + requirements: + ram_min: 1700 + os_image: ubuntu_14.04 + inputs: + image_id: '' + flavor_id: '' + agent_user: 'ubuntu' + external_network_name: '' + public_domain: clearwater.opnfv + orchestra_ims: + tenant_name: orchestra_ims + tenant_description: ims deployed with openbaton + opera_ims: + tenant_name: opera_ims + tenant_description: ims deployed with open-o + ONOS: general: onosbench_username: 'root' diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index 446a3b851..ede082856 100755 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -70,6 +70,7 @@ tiers: run: module: 'functest.opnfv_tests.openstack.tempest.tempest' class: 'TempestSmokeSerial' + - name: rally_sanity criteria: 'success_rate == 100%' @@ -214,7 +215,6 @@ tiers: dependencies: installer: 'apex' scenario: '^((?!fdio).)*$' - - name: copper criteria: 'status == "PASS"' @@ -227,7 +227,6 @@ tiers: run: module: 'functest.opnfv_tests.features.copper' class: 'Copper' - - name: moon criteria: 'status == "PASS"' @@ -282,6 +281,18 @@ tiers: run: module: 'functest.opnfv_tests.vnf.rnc.parser' class: 'Parser' + - + name: orchestra + criteria: 'ret == 0' + blocking: false + description: >- + Test OpenBaton (Orchestra) stack + dependencies: + installer: 'joid' + scenario: 'unknown' + run: + module: 'functest.opnfv_tests.features.orchestrator.orchestra' + class: 'OpenbatonOrchestrator' - name: components order: 3 @@ -323,7 +334,7 @@ tiers: Collection of VNF test cases. testcases: - - name: vims + name: cloudify_ims criteria: 'status == "PASS"' blocking: false description: >- @@ -332,3 +343,57 @@ tiers: dependencies: installer: '' scenario: '(ocl)|(nosdn)|^(os-odl)((?!bgpvpn).)*$' + run: + module: 'functest.opnfv_tests.vnf.ims.cloudify_ims' + class: 'ImsVnf' + - + name: aaa + criteria: 'ret == 0' + blocking: false + description: >- + Test suite from Parser project. + dependencies: + installer: '' + scenario: '' + run: + module: 'functest.opnfv_tests.vnf.aaa.aaa' + class: 'AaaVnf' + + - + name: juju_epc + criteria: 'ret == 0' + blocking: false + description: >- + Test suite from OAI project, vEPC deployed with Juju. + dependencies: + installer: 'unknown' + scenario: 'unknown' + run: + module: 'functest.opnfv_tests.vnf.epc.epc' + class: 'EpcVnf' + + - + name: orchestra_ims + criteria: 'ret == 0' + blocking: false + description: >- + VNF deployment with OpenBaton (Orchestra) + dependencies: + installer: 'unknown' + scenario: 'unknown' + run: + module: 'functest.opnfv_tests.vnf.ims.orchestra_ims' + class: 'ImsVnf' + + - + name: opera_ims + criteria: 'ret == 0' + blocking: false + description: >- + Evolution of vIMS + dependencies: + installer: 'unknown' + scenario: 'unknown' + run: + module: 'functest.opnfv_tests.vnf.ims.opera_ims' + class: 'ImsVnf' diff --git a/functest/core/vnf_base.py b/functest/core/vnf_base.py new file mode 100644 index 000000000..995204940 --- /dev/null +++ b/functest/core/vnf_base.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 os +import time + +import inspect + + +import functest.utils.functest_logger as ft_logger +import functest.utils.openstack_utils as os_utils +import functest.utils.functest_utils as ft_utils +import testcase_base as base +from functest.utils.constants import CONST + + +class VnfOnBoardingBase(base.TestcaseBase): + + logger = ft_logger.Logger(__name__).getLogger() + + def __init__(self, project='functest', case='', repo='', cmd=''): + super(VnfOnBoardingBase, self).__init__() + self.repo = repo + self.project_name = project + self.case_name = case + self.cmd = cmd + self.details = {} + self.data_dir = CONST.dir_functest_data + self.details['orchestrator'] = {} + self.details['vnf'] = {} + self.details['test_vnf'] = {} + try: + self.tenant_name = CONST.__getattribute__( + 'vnf_{}_tenant_name'.format(self.case_name)) + self.tenant_description = CONST.__getattribute__( + 'vnf_{}_tenant_description'.format(self.case_name)) + except: + raise Exception("Unknown VNF case=" + self.case_name) + + try: + self.tenant_images = CONST.__getattribute__( + 'vnf_{}_tenant_images'.format(self.case_name)) + except: + self.logger.warn("No tenant image defined for this VNF") + + def execute(self): + self.start_time = time.time() + # Prepare the test (Create Tenant, User, ...) + self.logger.info("Create VNF Onboarding environment") + self.prepare() + + # Deploy orchestrator + try: + self.logger.info("Deploy orchestrator (if necessary)") + orchestrator_ready_time = time.time() + res_orchestrator = self.deploy_orchestrator() + # orchestrator is not mandatory + if res_orchestrator is not None: + self.details['orchestrator']['status'] = ( + res_orchestrator['status']) + self.details['orchestrator']['result'] = ( + res_orchestrator['result']) + self.details['orchestrator']['duration'] = round( + orchestrator_ready_time - self.start_time, 1) + except: + self.logger.warn("Problem with the Orchestrator") + + # Deploy VNF + try: + self.logger.info("Deploy VNF " + self.case_name) + res_deploy_vnf = self.deploy_vnf() + vnf_ready_time = time.time() + self.details['vnf']['status'] = res_deploy_vnf['status'] + self.details['vnf']['result'] = res_deploy_vnf['result'] + self.details['vnf']['duration'] = round( + vnf_ready_time - orchestrator_ready_time, 1) + except: + raise Exception("Error during VNF deployment") + + # Test VNF + try: + self.logger.info("Test VNF") + res_test_vnf = self.test_vnf() + test_vnf_done_time = time.time() + self.details['test_vnf']['status'] = res_test_vnf['status'] + self.details['test_vnf']['result'] = res_test_vnf['result'] + self.details['test_vnf']['duration'] = round( + test_vnf_done_time - vnf_ready_time, 1) + except: + raise Exception("Error when running VNF tests") + + # Clean the system + self.clean() + self.stop_time = time.time() + + exit_code = self.parse_results() + self.log_results() + return exit_code + + # prepare state could consist in the creation of the resources + # a dedicated user + # a dedictaed tenant + # dedicated images + def prepare(self): + self.creds = os_utils.get_credentials() + self.keystone_client = os_utils.get_keystone_client() + + self.logger.info("Prepare OpenStack plateform(create tenant and user)") + user_id = os_utils.get_user_id(self.keystone_client, + self.creds['username']) + if user_id == '': + self.step_failure("Failed to get id of " + + self.creds['username']) + + tenant_id = os_utils.create_tenant( + self.keystone_client, self.tenant_name, self.tenant_description) + if not tenant_id: + self.step_failure("Failed to create " + + self.tenant_name + " tenant") + + roles_name = ["admin", "Admin"] + role_id = '' + for role_name in roles_name: + if role_id == '': + role_id = os_utils.get_role_id(self.keystone_client, role_name) + + if role_id == '': + self.logger.error("Failed to get id for %s role" % role_name) + self.step_failure("Failed to get role id of " + role_name) + + if not os_utils.add_role_user(self.keystone_client, user_id, + role_id, tenant_id): + self.logger.error("Failed to add %s on tenant" % + self.creds['username']) + self.step_failure("Failed to add %s on tenant" % + self.creds['username']) + + user_id = os_utils.create_user(self.keystone_client, + self.tenant_name, + self.tenant_name, + None, + tenant_id) + if not user_id: + self.logger.error("Failed to create %s user" % self.tenant_name) + self.step_failure("Failed to create user ") + + self.logger.info("Update OpenStack creds informations") + self.creds.update({ + "username": self.tenant_name, + "password": self.tenant_name, + "tenant": self.tenant_name, + }) + self.glance_client = os_utils.get_glance_client(self.creds) + self.neutron_client = os_utils.get_neutron_client(self.creds) + self.nova_client = os_utils.get_nova_client(self.creds) + + 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(): + image_id = os_utils.get_image_id(self.glance_client, image_name) + + 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 = os_utils.download_and_add_image_on_glance( + self.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") + + self.logger.info("Update security group quota for this tenant") + + if not os_utils.update_sg_quota(self.neutron_client, + tenant_id, 50, 100): + self.step_failure("Failed to update security group quota" + + " for tenant " + self.tenant_name) + + # orchestrator is not mandatory to dpeloy and test VNF + def deploy_orchestrator(self, **kwargs): + pass + + # TODO see how to use built-in exception from releng module + def deploy_vnf(self): + self.logger.error("VNF must be deployed") + raise Exception("VNF not deployed") + + def test_vnf(self): + self.logger.error("VNF must be tested") + raise Exception("VNF not tested") + + def clean(self): + self.logger.info("test cleaning") + + self.logger.info("Removing %s tenant .." % self.tenant_name) + tenant_id = os_utils.get_tenant_id(self.keystone_client, + self.tenant_name) + if tenant_id == '': + self.logger.error("Error : Failed to get id of %s tenant" % + self.tenant_name) + else: + if not os_utils.delete_tenant(self.keystone_client, tenant_id): + self.logger.error("Error : Failed to remove %s tenant" % + self.tenant_name) + + self.logger.info("Removing %s user .." % self.tenant_name) + user_id = os_utils.get_user_id( + self.keystone_client, self.tenant_name) + if user_id == '': + self.logger.error("Error : Failed to get id of %s user" % + self.tenant_name) + else: + if not os_utils.delete_user(self.keystone_client, user_id): + self.logger.error("Error : Failed to remove %s user" % + self.tenant_name) + + def parse_results(self): + exit_code = self.EX_OK + self.criteria = "PASS" + self.logger.info(self.details) + # The 2 VNF steps must be OK to get a PASS result + if (self.details['vnf']['status'] is not "PASS" or + self.details['test_vnf']['status'] is not "PASS"): + exit_code = self.EX_RUN_ERROR + self.criteria = "FAIL" + return exit_code + + def log_results(self): + ft_utils.logger_test_results(self.project_name, + self.case_name, + self.criteria, + self.details) + + def step_failure(self, error_msg): + part = inspect.stack()[1][3] + self.details[part]['status'] = 'FAIL' + self.details[part]['result'] = error_msg + raise Exception(error_msg) diff --git a/functest/opnfv_tests/features/copper.py b/functest/opnfv_tests/features/copper.py index 204fa3374..a10364e26 100755 --- a/functest/opnfv_tests/features/copper.py +++ b/functest/opnfv_tests/features/copper.py @@ -22,4 +22,4 @@ class Copper(base.FeatureBase): super(Copper, self).__init__(project='copper', case='copper-notification', repo='dir_repo_copper') - self.cmd = 'cd %s/tests && ./run.sh' % self.repo + self.cmd = 'bash %s/tests/run.sh' % self.repo diff --git a/functest/opnfv_tests/mano/orchestra.py b/functest/opnfv_tests/mano/orchestra.py new file mode 100755 index 000000000..fd5e40d05 --- /dev/null +++ b/functest/opnfv_tests/mano/orchestra.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import functest.core.feature_base as base + + +class Orchestra(base.FeatureBase): + def __init__(self): + super(Orchestra, self).__init__(project='orchestra', + case='orchestra', + repo='dir_repo_orchestra') + # TODO + # self.cmd = "%s/tests/run.sh %s/tests" % (self.repo, self.repo) diff --git a/functest/opnfv_tests/vnf/aaa/__init__.py b/functest/opnfv_tests/vnf/aaa/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/functest/opnfv_tests/vnf/aaa/__init__.py diff --git a/functest/opnfv_tests/vnf/aaa/aaa.py b/functest/opnfv_tests/vnf/aaa/aaa.py new file mode 100644 index 000000000..8898b9fc9 --- /dev/null +++ b/functest/opnfv_tests/vnf/aaa/aaa.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 + +import argparse + +import functest.core.testcase_base as testcase_base +import functest.core.vnf_base as vnf_base +import functest.utils.functest_logger as ft_logger + + +class AaaVnf(vnf_base.VnfOnBoardingBase): + + logger = ft_logger.Logger("VNF AAA").getLogger() + + def __init__(self): + super(AaaVnf, self).__init__() + self.case_name = "aaa" + + def deploy_orchestrator(self): + self.logger.info("No VNFM needed to deploy a free radius here") + return None + +# TODO see how to use build in exception form releng module + def deploy_vnf(self): + self.logger.info("Freeradius VNF deployment") + # TODO apt-get update + config tuning + deploy_vnf = {} + deploy_vnf['status'] = "PASS" + deploy_vnf['result'] = {} + return deploy_vnf + + def test_vnf(self): + self.logger.info("Run test towards freeradius") + # TODO: once the freeradius is deployed..make some tests + test_vnf = {} + test_vnf['status'] = "PASS" + test_vnf['result'] = {} + return test_vnf + + def main(self, **kwargs): + self.logger.info("AAA VNF onboarding") + self.execute() + if self.criteria is "PASS": + return self.EX_OK + else: + return self.EX_RUN_ERROR + + def run(self): + kwargs = {} + return self.main(**kwargs) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + args = vars(parser.parse_args()) + aaa_vnf = AaaVnf() + try: + result = aaa_vnf.main(**args) + if result != testcase_base.TestcaseBase.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) diff --git a/functest/opnfv_tests/vnf/ims/__init__.py b/functest/opnfv_tests/vnf/ims/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/functest/opnfv_tests/vnf/ims/__init__.py diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py new file mode 100644 index 000000000..e584519b7 --- /dev/null +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 requests +import subprocess +import time + +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 + +from clearwater import Clearwater +from functest.utils.constants import CONST +from orchestrator_cloudify import Orchestrator + + +class ImsVnf(vnf_base.VnfOnBoardingBase): + + def __init__(self, project='functest', case='', repo='', cmd=''): + super(ImsVnf, self).__init__(project, case, repo, cmd) + self.logger = ft_logger.Logger("vIMS").getLogger() + self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/') + self.data_dir = CONST.dir_vIMS_data + self.test_dir = CONST.dir_repo_vims_test + + self.orchestrator = dict( + requirements=CONST.cloudify_requirements, + blueprint=CONST.cloudify_blueprint, + inputs=CONST.cloudify_inputs + ) + + self.vnf = dict( + blueprint=CONST.clearwater_blueprint, + deployment_name=CONST.clearwater_deployment_name, + inputs=CONST.clearwater_inputs, + requirements=CONST.clearwater_requirements + ) + + # vIMS Data directory creation + if not os.path.exists(self.data_dir): + os.makedirs(self.data_dir) + + def deploy_orchestrator(self, **kwargs): + public_auth_url = os_utils.get_endpoint('identity') + + cfy = Orchestrator(self.data_dir, self.orchestrator.inputs) + self.orchestrator.object = cfy + + if 'tenant_name' in self.creds.keys(): + tenant_name = self.creds['tenant_name'] + elif 'project_name' in self.creds.keys(): + tenant_name = self.creds['project_name'] + + cfy.set_credentials(username=self.creds['username'], + password=self.creds['password'], + tenant_name=tenant_name, + auth_url=public_auth_url) + + # orchestrator VM flavor + flavor_id = self.get_flavor("m1.large", self.orchestrator.requirements) + if not flavor_id: + self.logger.info("Available flavors are: ") + self.pMsg(self.nova_client.flavor.list()) + self.step_failure("Failed to find required flavor" + "for this deployment") + cfy.set_flavor_id(flavor_id) + + # orchestrator VM image + if 'os_image' in self.orchestrator.requirements.keys(): + image_id = os_utils.get_image_id( + self.glance_client, self.orchestrator.requirements['os_image']) + if image_id == '': + self.step_failure("Failed to find required OS image" + " for cloudify manager") + else: + self.step_failure("Failed to find required OS image" + " for cloudify manager") + + cfy.set_image_id(image_id) + + ext_net = os_utils.get_external_net(self.neutron_client) + if not ext_net: + self.step_failure("Failed to get external network") + + cfy.set_external_network_name(ext_net) + + ns = ft_utils.get_resolvconf_ns() + if ns: + cfy.set_nameservers(ns) + + if 'compute' in self.nova_client.client.services_url: + cfy.set_nova_url(self.nova_client.client.services_url['compute']) + if self.neutron_client.httpclient.endpoint_url is not None: + cfy.set_neutron_url(self.neutron_client.httpclient.endpoint_url) + + self.logger.info("Prepare virtualenv for cloudify-cli") + cmd = "chmod +x " + self.case_dir + "create_venv.sh" + ft_utils.execute_command(cmd) + time.sleep(3) + cmd = self.case_dir + "create_venv.sh " + self.data_dir + ft_utils.execute_command(cmd) + + cfy.download_manager_blueprint(self.orchestrator.blueprint['url'], + self.orchestrator.blueprint['branch']) + + cfy.deploy_manager() + return {'status': 'PASS', 'result': ''} + + def deploy_vnf(self): + cw = Clearwater(self.vnf.inputs, self.orchestrator.object, self.logger) + self.vnf.object = cw + + self.logger.info("Collect flavor id for all clearwater vm") + flavor_id = self.get_flavor("m1.small", self.vnf.requirements) + if not flavor_id: + self.logger.info("Available flavors are: ") + self.pMsg(self.nova_client.flavor.list()) + self.step_failure("Failed to find required flavor" + " for this deployment") + + cw.set_flavor_id(flavor_id) + + # VMs image + if 'os_image' in self.vnf.requirements.keys(): + image_id = os_utils.get_image_id( + self.glance_client, self.vnf.requirements['os_image']) + if image_id == '': + self.step_failure("Failed to find required OS image" + " for clearwater VMs") + else: + self.step_failure("Failed to find required OS image" + " for clearwater VMs") + + cw.set_image_id(image_id) + + ext_net = os_utils.get_external_net(self.neutron_client) + if not ext_net: + self.step_failure("Failed to get external network") + + cw.set_external_network_name(ext_net) + + cw.deploy_vnf() + return {'status': 'PASS', 'result': ''} + + def test_vnf(self): + script = "source {0}venv_cloudify/bin/activate; " + script += "cd {0}; " + script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\"" + cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'" + + try: + self.logger.debug("Trying to get clearwater manager IP ... ") + mgr_ip = os.popen(cmd).read() + mgr_ip = mgr_ip.splitlines()[0] + except: + 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'] + + 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 = 20 + while rq.status_code != 201 and i > 0: + rq = requests.post(url, data=params) + i = i - 1 + time.sleep(10) + + if rq.status_code == 201: + url = ellis_url + "session" + rq = requests.post(url, data=params) + cookies = rq.cookies + + 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) + 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 + + 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") + + if vims_test_result != '': + return {'status': 'PASS', 'result': vims_test_result} + else: + return {'status': 'FAIL', 'result': ''} + + def clean(self): + self.vnf.object.undeploy_vnf() + self.orchestrator.object.undeploy_manager() + super(ImsVnf, self).clean() + + def get_flavor(self, flavor_name, requirements): + try: + flavor_id = os_utils.get_flavor_id(self.nova_client, flavor_name) + if 'ram_min' in requirements.keys(): + flavor_id = os_utils.get_flavor_id_by_ram_range( + self.nova_client, requirements['ram_min'], 7500) + + if flavor_id == '': + self.logger.error( + "Failed to find %s flavor. " + "Try with ram range default requirement !" % flavor_name) + flavor_id = os_utils.get_flavor_id_by_ram_range( + self.nova_client, + 4000, 10000) + return flavor_id + except: + self.logger.error("Flavor '%s' not found." % self.flavor_name) + self.logger.info("Available flavors are: ") + self.pMsg(self.nova_client.flavor.list()) + return None diff --git a/functest/opnfv_tests/vnf/ims/opera_ims.py b/functest/opnfv_tests/vnf/ims/opera_ims.py new file mode 100644 index 000000000..fa8f9ec98 --- /dev/null +++ b/functest/opnfv_tests/vnf/ims/opera_ims.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 requests +import subprocess +import time + +import functest.core.vnf_base as vnf_base +import functest.utils.functest_logger as ft_logger +import functest.utils.functest_utils as ft_utils +from functest.utils.constants import CONST + + +class ImsVnf(vnf_base.VnfOnBoardingBase): + + def __init__(self, project='functest', case='', repo='', cmd=''): + super(ImsVnf, self).__init__(project, case, repo, cmd) + self.logger = ft_logger.Logger("vIMS").getLogger() + self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/') + self.data_dir = CONST.dir_vIMS_data + self.test_dir = CONST.dir_repo_vims_test + + # vIMS Data directory creation + if not os.path.exists(self.data_dir): + os.makedirs(self.data_dir) + + def deploy_orchestrator(self, **kwargs): + # TODO + # deploy open-O from Functest docker located on the Jumphost + # you have admin rights on OpenStack SUT + # you can cretae a VM, spawn docker on the jumphost + # spawn docker on a VM in the SUT, ..up to you + # + # note: this step can be ignored + # if Open-O is part of the installer + self.logger.info("Deploy orchestrator: OK") + + def deploy_vnf(self): + # TODO + self.logger.info("Deploy VNF: OK") + + def test_vnf(self): + # Adaptations probably needed + # code used for cloudify_ims + # ruby client on jumphost calling the vIMS on the SUT + script = "source {0}venv_cloudify/bin/activate; " + script += "cd {0}; " + script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\"" + cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'" + + try: + self.logger.debug("Trying to get clearwater manager IP ... ") + mgr_ip = os.popen(cmd).read() + mgr_ip = mgr_ip.splitlines()[0] + except: + 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'] + + 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 = 20 + while rq.status_code != 201 and i > 0: + rq = requests.post(url, data=params) + i = i - 1 + time.sleep(10) + + if rq.status_code == 201: + url = ellis_url + "session" + rq = requests.post(url, data=params) + cookies = rq.cookies + + 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) + 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 + + 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") + + if vims_test_result != '': + return {'status': 'PASS', 'result': vims_test_result} + else: + return {'status': 'FAIL', 'result': ''} + + def clean(self): + # TODO + super(ImsVnf, self).clean() diff --git a/functest/opnfv_tests/vnf/ims/orchestra_ims.py b/functest/opnfv_tests/vnf/ims/orchestra_ims.py new file mode 100644 index 000000000..ebd6c9baf --- /dev/null +++ b/functest/opnfv_tests/vnf/ims/orchestra_ims.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 requests +import subprocess +import time + +import functest.core.vnf_base as vnf_base +import functest.utils.functest_logger as ft_logger +import functest.utils.functest_utils as ft_utils +from functest.utils.constants import CONST + + +class ImsVnf(vnf_base.VnfOnBoardingBase): + + def __init__(self, project='functest', case='', repo='', cmd=''): + super(ImsVnf, self).__init__(project, case, repo, cmd) + self.logger = ft_logger.Logger("vIMS").getLogger() + self.case_dir = os.path.join(CONST.functest_test, 'vnf/ims/') + self.data_dir = CONST.dir_vIMS_data + self.test_dir = CONST.dir_repo_vims_test + + # vIMS Data directory creation + if not os.path.exists(self.data_dir): + os.makedirs(self.data_dir) + + def deploy_orchestrator(self, **kwargs): + # TODO + # put your code here to deploy openbaton + # from the functest docker located on the jumphost + # you have admin rights on OpenStack SUT + # you can cretae a VM, spawn docker on the jumphost + # spawn docker on a VM in the SUT, ..up to you + # + # note: this step can be ignored + # if OpenBaton is part of the installer + self.logger.info("Deploy orchestrator: OK") + + def deploy_vnf(self): + # deploy the VNF + # call openbaton to deploy the vIMS + self.logger.info("Deploy VNF: OK") + + def test_vnf(self): + # Adaptations probably needed + # code used for cloudify_ims + # ruby client on jumphost calling the vIMS on the SUT + script = "source {0}venv_cloudify/bin/activate; " + script += "cd {0}; " + script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\"" + cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'" + + try: + self.logger.debug("Trying to get clearwater manager IP ... ") + mgr_ip = os.popen(cmd).read() + mgr_ip = mgr_ip.splitlines()[0] + except: + 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'] + + 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 = 20 + while rq.status_code != 201 and i > 0: + rq = requests.post(url, data=params) + i = i - 1 + time.sleep(10) + + if rq.status_code == 201: + url = ellis_url + "session" + rq = requests.post(url, data=params) + cookies = rq.cookies + + 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) + 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 + + 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") + + if vims_test_result != '': + return {'status': 'PASS', 'result': vims_test_result} + else: + return {'status': 'FAIL', 'result': ''} + + def clean(self): + # TODO + super(ImsVnf, self).clean() diff --git a/functest/opnfv_tests/vnf/ims/orchestrator.py b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py index f3838f871..f3838f871 100644 --- a/functest/opnfv_tests/vnf/ims/orchestrator.py +++ b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py diff --git a/functest/opnfv_tests/vnf/ims/vims.py b/functest/opnfv_tests/vnf/ims/vims.py deleted file mode 100755 index 15981f512..000000000 --- a/functest/opnfv_tests/vnf/ims/vims.py +++ /dev/null @@ -1,506 +0,0 @@ -#!/usr/bin/python -# coding: utf8 -####################################################################### -# -# Copyright (c) 2015 Orange -# valentin.boucher@orange.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 datetime -import json -import os -import pprint -import subprocess -import time - -import argparse -import requests - -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 orchestrator import Orchestrator -import functest.utils.functest_constants as ft_constants - -pp = pprint.PrettyPrinter(indent=4) - - -parser = argparse.ArgumentParser() -parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") -parser.add_argument("-r", "--report", - help="Create json result file", - action="store_true") -parser.add_argument("-n", "--noclean", - help="Don't clean the created resources for this test.", - action="store_true") -args = parser.parse_args() - -""" logging configuration """ -logger = ft_logger.Logger("vIMS").getLogger() - - -# Cloudify parameters -VIMS_DIR = os.path.join(ft_constants.FUNCTEST_TEST_DIR, 'vnf/ims/') -VIMS_DATA_DIR = ft_constants.VIMS_DATA_DIR -VIMS_TEST_DIR = ft_constants.VIMS_TEST_DIR -VIMS_TENANT_NAME = ft_constants.VIMS_TENANT_NAME -VIMS_TENANT_DESCRIPTION = ft_constants.VIMS_TENANT_DESCRIPTION -VIMS_IMAGES = ft_constants.VIMS_IMAGES - -CFY_MANAGER_BLUEPRINT = ft_constants.CFY_MANAGER_BLUEPRINT -CFY_MANAGER_REQUIERMENTS = ft_constants.CFY_MANAGER_REQUIERMENTS -CFY_INPUTS = ft_constants.CFY_INPUTS - -CW_BLUEPRINT = ft_constants.CW_BLUEPRINT -CW_DEPLOYMENT_NAME = ft_constants.CW_DEPLOYMENT_NAME -CW_INPUTS = ft_constants.CW_INPUTS -CW_REQUIERMENTS = ft_constants.CW_REQUIERMENTS - -CFY_DEPLOYMENT_DURATION = 0 -CW_DEPLOYMENT_DURATION = 0 - -TESTCASE_START_TIME = time.time() -RESULTS = {'orchestrator': {'duration': 0, 'result': ''}, - 'vIMS': {'duration': 0, 'result': ''}, - 'sig_test': {'duration': 0, 'result': ''}} - - -def download_and_add_image_on_glance(glance, image_name, image_url): - dest_path = os.path.join(VIMS_DATA_DIR, "tmp/") - 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): - logger.error("Failed to download image %s" % file_name) - return False - - image = os_utils.create_glance_image( - glance, image_name, dest_path + file_name) - if not image: - logger.error("Failed to upload image on glance") - return False - - return image - - -def step_failure(step_name, error_msg): - logger.error(error_msg) - set_result(step_name, 0, error_msg) - status = "FAIL" - # in case of failure starting and stoping time are not correct - stop_time = time.time() - if step_name == "sig_test": - status = "PASS" - ft_utils.push_results_to_db("functest", - "vims", - TESTCASE_START_TIME, - stop_time, - status, - RESULTS) - exit(-1) - - -def set_result(step_name, duration=0, result=""): - RESULTS[step_name] = {'duration': duration, 'result': result} - - -def test_clearwater(): - script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " - script += "cd " + VIMS_DATA_DIR + "; " - script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\"" - cmd = "/bin/bash -c '" + script + "'" - - try: - logger.debug("Trying to get clearwater manager IP ... ") - mgr_ip = os.popen(cmd).read() - mgr_ip = mgr_ip.splitlines()[0] - except: - step_failure("sig_test", "Unable to retrieve the IP of the " - "cloudify manager server !") - - api_url = "http://" + mgr_ip + "/api/v2" - dep_outputs = requests.get(api_url + "/deployments/" + - CW_DEPLOYMENT_NAME + "/outputs") - dns_ip = dep_outputs.json()['outputs']['dns_ip'] - ellis_ip = dep_outputs.json()['outputs']['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 = 20 - while rq.status_code != 201 and i > 0: - rq = requests.post(url, data=params) - i = i - 1 - time.sleep(10) - - if rq.status_code == 201: - url = ellis_url + "session" - rq = requests.post(url, data=params) - cookies = rq.cookies - - 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) - i = i - 1 - time.sleep(25) - - if rq.status_code != 200: - step_failure("sig_test", "Unable to create a number: %s" - % rq.json()['reason']) - - start_time_ts = time.time() - end_time_ts = start_time_ts - logger.info("vIMS functional test Start Time:'%s'" % ( - datetime.datetime.fromtimestamp(start_time_ts).strftime( - '%Y-%m-%d %H:%M:%S'))) - nameservers = ft_utils.get_resolvconf_ns() - resolvconf = "" - for ns in nameservers: - resolvconf += "\nnameserver " + ns - - if dns_ip != "": - script = ('echo -e "nameserver ' + dns_ip + resolvconf + - '" > /etc/resolv.conf; ') - script += 'source /etc/profile.d/rvm.sh; ' - script += 'cd ' + VIMS_TEST_DIR + '; ' - script += ('rake test[' + CW_INPUTS["public_domain"] + - '] SIGNUP_CODE="secret"') - - cmd = "/bin/bash -c '" + script + "'" - output_file = "output.txt" - f = open(output_file, 'w+') - subprocess.call(cmd, shell=True, stdout=f, - stderr=subprocess.STDOUT) - f.close() - end_time_ts = time.time() - duration = round(end_time_ts - start_time_ts, 1) - logger.info("vIMS functional test duration:'%s'" % duration) - f = open(output_file, 'r') - result = f.read() - if result != "" and logger: - logger.debug(result) - - vims_test_result = "" - tempFile = os.path.join(VIMS_TEST_DIR, "temp.json") - try: - logger.debug("Trying to load test results") - with open(tempFile) as f: - vims_test_result = json.load(f) - f.close() - except: - logger.error("Unable to retrieve test results") - - set_result("sig_test", duration, vims_test_result) - - # success criteria for vIMS (for Brahmaputra) - # - orchestrator deployed - # - VNF deployed - # TODO use test criteria defined in config file - status = "FAIL" - try: - if (RESULTS['orchestrator']['duration'] > 0 and - RESULTS['vIMS']['duration'] > 0): - status = "PASS" - except: - logger.error("Unable to set test status") - - ft_utils.push_results_to_db("functest", - "vims", - TESTCASE_START_TIME, - end_time_ts, - status, - RESULTS) - - try: - os.remove(tempFile) - except: - logger.error("Deleting file failed") - - -def main(): - - # ############### GENERAL INITIALISATION ################ - - if not os.path.exists(VIMS_DATA_DIR): - os.makedirs(VIMS_DATA_DIR) - - creds = os_utils.get_credentials() - - logger.info("Prepare OpenStack plateform (create tenant and user)") - keystone = os_utils.get_keystone_client() - - user_id = os_utils.get_user_id(keystone, creds['username']) - if user_id == '': - step_failure("init", "Error : Failed to get id of " + - creds['username']) - - tenant_id = os_utils.create_tenant( - keystone, VIMS_TENANT_NAME, VIMS_TENANT_DESCRIPTION) - if not tenant_id: - step_failure("init", "Error : Failed to create " + - VIMS_TENANT_NAME + " tenant") - - roles_name = ["admin", "Admin"] - role_id = '' - for role_name in roles_name: - if role_id == '': - role_id = os_utils.get_role_id(keystone, role_name) - - if role_id == '': - logger.error("Error : Failed to get id for %s role" % role_name) - - if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id): - logger.error("Error : Failed to add %s on tenant" % - creds['username']) - - user_id = os_utils.create_user( - keystone, VIMS_TENANT_NAME, VIMS_TENANT_NAME, None, tenant_id) - if not user_id: - logger.error("Error : Failed to create %s user" % VIMS_TENANT_NAME) - - logger.info("Update OpenStack creds informations") - creds.update({ - "username": VIMS_TENANT_NAME, - "password": VIMS_TENANT_NAME, - "tenant": VIMS_TENANT_NAME, - }) - - logger.info("Upload some OS images if it doesn't exist") - glance = os_utils.get_glance_client() - - for img in VIMS_IMAGES.keys(): - image_name = VIMS_IMAGES[img]['image_name'] - image_url = VIMS_IMAGES[img]['image_url'] - - image_id = os_utils.get_image_id(glance, image_name) - - if image_id == '': - 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, image_name, image_url) - - if image_id == '': - step_failure( - "init", - "Error : Failed to find or upload required OS " - "image for this deployment") - - logger.info("Update security group quota for this tenant") - neutron = os_utils.get_neutron_client(creds) - if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100): - step_failure( - "init", - "Failed to update security group quota for tenant " + - VIMS_TENANT_NAME) - - # ############### CLOUDIFY INITIALISATION ################ - public_auth_url = os_utils.get_endpoint('identity') - - cfy = Orchestrator(VIMS_DATA_DIR, CFY_INPUTS) - - if 'tenant_name' in creds.keys(): - tenant_name = creds['tenant_name'] - elif 'project_name' in creds.keys(): - tenant_name = creds['project_name'] - - cfy.set_credentials(username=creds['username'], - password=creds['password'], - tenant_name=tenant_name, - auth_url=public_auth_url) - - logger.info("Collect flavor id for cloudify manager server") - nova = os_utils.get_nova_client(creds) - - flavor_name = "m1.large" - flavor_id = os_utils.get_flavor_id(nova, flavor_name) - for requirement in CFY_MANAGER_REQUIERMENTS: - if requirement == 'ram_min': - flavor_id = os_utils.get_flavor_id_by_ram_range( - nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 10000) - - if flavor_id == '': - logger.error( - "Failed to find %s flavor. " - "Try with ram range default requirement !" % flavor_name) - flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196) - - if flavor_id == '': - step_failure("orchestrator", - "Failed to find required flavor for this deployment") - - cfy.set_flavor_id(flavor_id) - - image_name = "centos_7" - image_id = os_utils.get_image_id(glance, image_name) - for requirement in CFY_MANAGER_REQUIERMENTS: - if requirement == 'os_image': - image_id = os_utils.get_image_id( - glance, CFY_MANAGER_REQUIERMENTS['os_image']) - - if image_id == '': - step_failure( - "orchestrator", - "Error : Failed to find required OS image for cloudify manager") - - cfy.set_image_id(image_id) - - ext_net = os_utils.get_external_net(neutron) - if not ext_net: - step_failure("orchestrator", "Failed to get external network") - - cfy.set_external_network_name(ext_net) - - ns = ft_utils.get_resolvconf_ns() - if ns: - cfy.set_nameservers(ns) - - if 'compute' in nova.client.services_url: - cfy.set_nova_url(nova.client.services_url['compute']) - if neutron.httpclient.endpoint_url is not None: - cfy.set_neutron_url(neutron.httpclient.endpoint_url) - - logger.info("Prepare virtualenv for cloudify-cli") - cmd = "chmod +x " + VIMS_DIR + "create_venv.sh" - ft_utils.execute_command(cmd) - time.sleep(3) - cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR - ft_utils.execute_command(cmd) - - cfy.download_manager_blueprint( - CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch']) - - # ############### CLOUDIFY DEPLOYMENT ################ - start_time_ts = time.time() - end_time_ts = start_time_ts - logger.info("Cloudify deployment Start Time:'%s'" % ( - datetime.datetime.fromtimestamp(start_time_ts).strftime( - '%Y-%m-%d %H:%M:%S'))) - - error = cfy.deploy_manager() - if error: - step_failure("orchestrator", error) - - end_time_ts = time.time() - duration = round(end_time_ts - start_time_ts, 1) - logger.info("Cloudify deployment duration:'%s'" % duration) - set_result("orchestrator", duration, "") - - # ############### CLEARWATER INITIALISATION ################ - - cw = Clearwater(CW_INPUTS, cfy, logger) - - logger.info("Collect flavor id for all clearwater vm") - - flavor_name = "m1.small" - flavor_id = os_utils.get_flavor_id(nova, flavor_name) - for requirement in CW_REQUIERMENTS: - if requirement == 'ram_min' and flavor_id == '': - flavor_id = os_utils.get_flavor_id_by_ram_range( - nova, CW_REQUIERMENTS['ram_min'], 4500) - - if flavor_id == '': - logger.error( - "Failed to find %s flavor. Try with ram range " - "default requirement !" % flavor_name) - flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196) - - if flavor_id == '': - step_failure( - "vIMS", "Failed to find required flavor for this deployment") - - cw.set_flavor_id(flavor_id) - - image_name = "ubuntu_14.04" - image_id = os_utils.get_image_id(glance, image_name) - for requirement in CW_REQUIERMENTS: - if requirement == 'os_image': - image_id = os_utils.get_image_id( - glance, CW_REQUIERMENTS['os_image']) - - if image_id == '': - step_failure( - "vIMS", - "Error : Failed to find required OS image for cloudify manager") - - cw.set_image_id(image_id) - - ext_net = os_utils.get_external_net(neutron) - if not ext_net: - step_failure("vIMS", "Failed to get external network") - - cw.set_external_network_name(ext_net) - - # ############### CLEARWATER DEPLOYMENT ################ - - start_time_ts = time.time() - end_time_ts = start_time_ts - logger.info("vIMS VNF deployment Start Time:'%s'" % ( - datetime.datetime.fromtimestamp(start_time_ts).strftime( - '%Y-%m-%d %H:%M:%S'))) - - error = cw.deploy_vnf(CW_BLUEPRINT) - if error: - step_failure("vIMS", error) - - end_time_ts = time.time() - duration = round(end_time_ts - start_time_ts, 1) - logger.info("vIMS VNF deployment duration:'%s'" % duration) - set_result("vIMS", duration, "") - - # ############### CLEARWATER TEST ################ - - test_clearwater() - - # ########## CLEARWATER UNDEPLOYMENT ############ - - cw.undeploy_vnf() - - # ########### CLOUDIFY UNDEPLOYMENT ############# - - cfy.undeploy_manager() - - # ############## GENERAL CLEANUP ################ - if args.noclean: - exit(0) - - logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name']) - tenant_id = os_utils.get_tenant_id( - keystone, CFY_INPUTS['keystone_tenant_name']) - if tenant_id == '': - logger.error("Error : Failed to get id of %s tenant" % - CFY_INPUTS['keystone_tenant_name']) - else: - if not os_utils.delete_tenant(keystone, tenant_id): - logger.error("Error : Failed to remove %s tenant" % - CFY_INPUTS['keystone_tenant_name']) - - logger.info("Removing %s user .." % CFY_INPUTS['keystone_username']) - user_id = os_utils.get_user_id( - keystone, CFY_INPUTS['keystone_username']) - if user_id == '': - logger.error("Error : Failed to get id of %s user" % - CFY_INPUTS['keystone_username']) - else: - if not os_utils.delete_user(keystone, user_id): - logger.error("Error : Failed to remove %s user" % - CFY_INPUTS['keystone_username']) - - -if __name__ == '__main__': - main() diff --git a/functest/tests/unit/core/test_vnf_base.py b/functest/tests/unit/core/test_vnf_base.py new file mode 100644 index 000000000..e27f2164b --- /dev/null +++ b/functest/tests/unit/core/test_vnf_base.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# Copyright (c) 2016 Orange and others. +# +# 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 logging +import unittest + +from functest.core import vnf_base + + +class VnfBaseTesting(unittest.TestCase): + + logging.disable(logging.CRITICAL) + + def setUp(self): + self.test = vnf_base.VnfOnBoardingBase(project='functest', + case='aaa') + self.test.project = "functest" + self.test.case_name = "aaa" + self.test.start_time = "1" + self.test.stop_time = "5" + self.test.criteria = "" + self.test.details = {"orchestrator": {"status": "PASS", + "result": "", + "duration": 20}, + "vnf": {"status": "PASS", + "result": "", + "duration": 15}, + "test_vnf": {"status": "FAIL", + "result": "", + "duration": 5}} + + def test_deploy_vnf_unimplemented(self): + with self.assertRaises(Exception) as context: + self.test.deploy_vnf() + self.assertTrue('VNF not deployed' in context.exception) + + def test_test_vnf_unimplemented(self): + with self.assertRaises(Exception) as context: + self.test.test_vnf()() + self.assertTrue('VNF not tested' in context.exception) + + def test_parse_results(self): + self.assertNotEqual(self.test.parse_results(), 0) + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/functest/utils/functest_constants.py b/functest/utils/functest_constants.py index ac9d77c87..c4be07798 100644 --- a/functest/utils/functest_constants.py +++ b/functest/utils/functest_constants.py @@ -245,11 +245,6 @@ VIMS_DATA_DIR = get_value('general.dir.dir_vIMS_data', 'VIMS_DATA_DIR') VIMS_TEST_DIR = get_value('general.dir.dir_repo_vims_test', 'VIMS_TEST_DIR') -VIMS_TENANT_NAME = get_value('vIMS.general.tenant_name', - 'VIMS_TENANT_NAME') -VIMS_TENANT_DESCRIPTION = get_value('vIMS.general.tenant_description', - 'VIMS_TENANT_DESCRIPTION') -VIMS_IMAGES = get_value('vIMS.general.images', 'VIMS_IMAGES') CFY_MANAGER_BLUEPRINT = get_value('vIMS.cloudify.blueprint', 'CFY_MANAGER_BLUEPRINT') CFY_MANAGER_REQUIERMENTS = get_value('vIMS.cloudify.requierments', |