diff options
-rwxr-xr-x | core/TestCasesBaseTesting.py | 2 | ||||
-rwxr-xr-x | run_unit_tests.sh | 25 | ||||
-rw-r--r-- | setup.py | 24 | ||||
-rw-r--r-- | unit_tests/__init__.py | 0 | ||||
-rw-r--r-- | utils/openstack_tacker.py | 249 | ||||
-rwxr-xr-x | utils/openstack_utils.py | 3 |
6 files changed, 300 insertions, 3 deletions
diff --git a/core/TestCasesBaseTesting.py b/core/TestCasesBaseTesting.py index 9658e8dc4..fc9c2db60 100755 --- a/core/TestCasesBaseTesting.py +++ b/core/TestCasesBaseTesting.py @@ -4,7 +4,7 @@ import logging import mock import unittest -import TestCasesBase +from functest.core import TestCasesBase class TestCasesBaseTesting(unittest.TestCase): diff --git a/run_unit_tests.sh b/run_unit_tests.sh new file mode 100755 index 000000000..a37cd3d98 --- /dev/null +++ b/run_unit_tests.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -o errexit +set -o pipefail + +echo "Running unit tests..." +cd . + +# start vitual env +virtualenv ./functest_venv +source ./functest_venv/bin/activate + +# install python packages +easy_install -U setuptools +easy_install -U pip +pip install -r docker/requirements.pip +pip install -e . + +# unit tests +nosetests --with-xunit \ + --with-coverage \ + --cover-package=functest\ + --cover-xml \ + unit_tests + +deactivate diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..58740f4aa --- /dev/null +++ b/setup.py @@ -0,0 +1,24 @@ +############################################################################## +# 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 +############################################################################## + +from setuptools import setup, find_packages + + +setup( + name="functest", + version="master", + packages=find_packages(), + include_package_data=True, + package_data={ + }, + url="https://www.opnfv.org", + install_requires=["coverage==4.1", + "mock==1.3.0", + "nose==1.3.7"], + entry_points={ + } +) diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/unit_tests/__init__.py diff --git a/utils/openstack_tacker.py b/utils/openstack_tacker.py new file mode 100644 index 000000000..3e0c9cf45 --- /dev/null +++ b/utils/openstack_tacker.py @@ -0,0 +1,249 @@ +########################################################################### +# Copyright (c) 2016 Ericsson AB and others. +# Author: George Paraskevopoulos <geopar@intracom-telecom.com> +# +# Wrappers for trozet's python-tackerclient v1.0 +# (https://github.com/trozet/python-tackerclient) +# +# 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 +########################################################################## + + +from tackerclient.v1_0 import client as tackerclient +import functest.utils.functest_logger as ft_logger +import functest.utils.openstack_utils as os_utils +import yaml + +logger = ft_logger.Logger("tacker_utils").getLogger() + + +def get_tacker_client(): + creds_tacker = os_utils.get_credentials('tacker') + return tackerclient.Client(**creds_tacker) + + +# ********************************************* +# TACKER +# ********************************************* +def get_id_from_name(tacker_client, resource_type, resource_name): + try: + req_params = {'fields': 'id', 'name': resource_name} + endpoint = '/{0}s'.format(resource_type) + resp = tacker_client.get(endpoint, params=req_params) + return resp[endpoint[1:]][0]['id'] + except Exception, e: + logger.error("Error [get_id_from_name(tacker_client, " + "resource_type, resource_name)]: %s" % e) + return None + + +def get_vnfd_id(tacker_client, vnfd_name): + return get_id_from_name(tacker_client, 'vnfd', vnfd_name) + + +def get_vnf_id(tacker_client, vnf_name): + return get_id_from_name(tacker_client, 'vnf', vnf_name) + + +def get_sfc_id(tacker_client, sfc_name): + return get_id_from_name(tacker_client, 'sfc', sfc_name) + + +def get_sfc_classifier_id(tacker_client, sfc_clf_name): + return get_id_from_name(tacker_client, 'sfc_classifier', sfc_clf_name) + + +def list_vnfds(tacker_client, verbose=False): + try: + vnfds = tacker_client.list_vnfds(retrieve_all=True) + if not verbose: + vnfds = [vnfd['id'] for vnfd in vnfds['vnfds']] + return vnfds + except Exception, e: + logger.error("Error [list_vnfds(tacker_client)]: %s" % e) + return None + + +def create_vnfd(tacker_client, tosca_file=None): + try: + vnfd_body = {} + if tosca_file is not None: + with open(tosca_file) as tosca_fd: + vnfd_body = yaml.safe_load(tosca_fd) + return tacker_client.create_vnfd(body=vnfd_body) + except Exception, e: + logger.error("Error [create_vnfd(tacker_client, '%s')]: %s" + % (tosca_file, e)) + return None + + +def delete_vnfd(tacker_client, vnfd_id=None, vnfd_name=None): + try: + vnfd = vnfd_id + if vnfd is None: + if vnfd_name is None: + raise Exception('You need to provide VNFD id or VNFD name') + vnfd = get_vnfd_id(tacker_client, vnfd_name) + return tacker_client.delete_vnfd(vnfd) + except Exception, e: + logger.error("Error [delete_vnfd(tacker_client, '%s', '%s')]: %s" + % (vnfd_id, vnfd_name, e)) + return None + + +def list_vnfs(tacker_client, verbose=False): + try: + vnfs = tacker_client.list_vnfs(retrieve_all=True) + if not verbose: + vnfs = [vnf['id'] for vnf in vnfs['vnfs']] + return vnfs + except Exception, e: + logger.error("Error [list_vnfs(tacker_client)]: %s" % e) + return None + + +def create_vnf(tacker_client, vnf_name, vnfd_id=None, vnfd_name=None): + try: + vnf_body = { + 'vnf': { + 'attributes': {}, + 'name': vnf_name + } + } + if vnfd_id is not None: + vnf_body['vnf']['vnfd_id'] = vnfd_id + else: + if vnfd_name is None: + raise Exception('vnfd id or vnfd name is required') + vnf_body['vnf']['vnfd_id'] = get_vnfd_id(tacker_client, vnfd_name) + return tacker_client.create_vnf(body=vnf_body) + except Exception, e: + logger.error("error [create_vnf(tacker_client, '%s', '%s', '%s')]: %s" + % (vnf_name, vnfd_id, vnfd_name, e)) + return None + + +def delete_vnf(tacker_client, vnf_id=None, vnf_name=None): + try: + vnf = vnf_id + if vnf is None: + if vnf_name is None: + raise Exception('You need to provide a VNF id or name') + vnf = get_vnf_id(tacker_client, vnf_name) + return tacker_client.delete_vnf(vnf) + except Exception, e: + logger.error("Error [delete_vnf(tacker_client, '%s', '%s')]: %s" + % (vnf_id, vnf_name, e)) + return None + + +def list_sfcs(tacker_client, verbose=False): + try: + sfcs = tacker_client.list_sfcs(retrieve_all=True) + if not verbose: + sfcs = [sfc['id'] for sfc in sfcs['sfcs']] + return sfcs + except Exception, e: + logger.error("Error [list_sfcs(tacker_client)]: %s" % e) + return None + + +def create_sfc(tacker_client, sfc_name, + chain_vnf_ids=None, + chain_vnf_names=None): + try: + sfc_body = { + 'sfc': { + 'attributes': {}, + 'name': sfc_name, + 'chain': [] + } + } + if chain_vnf_ids is not None: + sfc_body['sfc']['chain'] = chain_vnf_ids + else: + if chain_vnf_names is None: + raise Exception('You need to provide a chain of VNFs') + sfc_body['sfc']['chain'] = [get_vnf_id(tacker_client, name) + for name in chain_vnf_names] + return tacker_client.create_sfc(body=sfc_body) + except Exception, e: + logger.error("error [create_sfc(tacker_client, '%s', '%s', '%s')]: %s" + % (sfc_name, chain_vnf_ids, chain_vnf_names, e)) + return None + + +def delete_sfc(tacker_client, sfc_id=None, sfc_name=None): + try: + sfc = sfc_id + if sfc is None: + if sfc_name is None: + raise Exception('You need to provide an SFC id or name') + sfc = get_sfc_id(tacker_client, sfc_name) + return tacker_client.delete_sfc(sfc) + except Exception, e: + logger.error("Error [delete_sfc(tacker_client, '%s', '%s')]: %s" + % (sfc_id, sfc_name, e)) + return None + + +def list_sfc_clasifiers(tacker_client, verbose=False): + try: + sfc_clfs = tacker_client.list_sfc_classifiers(retrieve_all=True) + if not verbose: + sfc_clfs = [sfc_clf['id'] + for sfc_clf in sfc_clfs['sfc_classifiers']] + return sfc_clfs + except Exception, e: + logger.error("Error [list_sfc_classifiers(tacker_client)]: %s" % e) + return None + + +def create_sfc_classifier(tacker_client, sfc_clf_name, sfc_id=None, + sfc_name=None, match={}): + # Example match: + # match: { + # "source_port": "0", + # "protocol": "6", + # "dest_port": "80" + # } + try: + sfc_clf_body = { + 'sfc_classifier': { + 'attributes': {}, + 'name': sfc_clf_name, + 'match': match, + 'chain': '' + } + } + if sfc_id is not None: + sfc_clf_body['sfc_classifier']['chain'] = sfc_id + else: + if sfc_name is None: + raise Exception('You need to provide an SFC id or name') + sfc_clf_body['sfc']['chain'] = get_sfc_id(tacker_client, sfc_name) + return tacker_client.create_sfc_classifier(body=sfc_clf_body) + except Exception, e: + logger.error("error [create_sfc_classifier(tacker_client, '%s', '%s', " + "'%s')]: %s" % (sfc_clf_name, sfc_id, sfc_name, match, e)) + return None + + +def delete_sfc_classifier(tacker_client, + sfc_clf_id=None, + sfc_clf_name=None): + try: + sfc_clf = sfc_clf_id + if sfc_clf is None: + if sfc_clf_name is None: + raise Exception('You need to provide an SFC' + 'classifier id or name') + sfc_clf = get_sfc_classifier_id(tacker_client, sfc_clf_name) + return tacker_client.delete_sfc_classifier(sfc_clf) + except Exception, e: + logger.error("Error [delete_sfc_classifier(tacker_client, '%s', " + "'%s')]: %s" % (sfc_clf_id, sfc_clf_name, e)) + return None diff --git a/utils/openstack_utils.py b/utils/openstack_utils.py index 39594a2a9..df6fb5d1a 100755 --- a/utils/openstack_utils.py +++ b/utils/openstack_utils.py @@ -166,11 +166,10 @@ def get_glance_client(): return glanceclient.Client(1, glance_endpoint, token=keystone_client.auth_token) + # ********************************************* # NOVA # ********************************************* - - def get_instances(nova_client): try: instances = nova_client.servers.list(search_opts={'all_tenants': 1}) |