diff options
Diffstat (limited to 'functest')
-rwxr-xr-x | functest/ci/check_os.sh | 63 | ||||
-rw-r--r-- | functest/ci/installer_params.yaml | 16 | ||||
-rwxr-xr-x | functest/ci/prepare_env.py | 31 | ||||
-rwxr-xr-x | functest/ci/testcases.yaml | 8 | ||||
-rw-r--r-- | functest/core/vnf_base.py | 25 | ||||
-rwxr-xr-x | functest/opnfv_tests/features/security_scan.py | 2 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/tempest/conf_utils.py | 45 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/tempest/tempest.py | 6 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/cloudify_ims.py | 30 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/cloudify_ims.yaml | 4 | ||||
-rw-r--r-- | functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py | 7 | ||||
-rwxr-xr-x | functest/utils/functest_logger.py | 2 | ||||
-rw-r--r-- | functest/utils/openstack_tacker.py | 67 |
13 files changed, 207 insertions, 99 deletions
diff --git a/functest/ci/check_os.sh b/functest/ci/check_os.sh index b875a173..2c5c021c 100755 --- a/functest/ci/check_os.sh +++ b/functest/ci/check_os.sh @@ -6,6 +6,16 @@ # jose.lausuch@ericsson.com # +declare -A service_cmd_array +service_cmd_array['nova']='openstack server list' +service_cmd_array['neutron']='openstack network list' +service_cmd_array['keystone']='openstack endpoint list' +service_cmd_array['cinder']='openstack volume list' +service_cmd_array['glance']='openstack image list' + +MANDATORY_SERVICES='nova neutron keystone glance' +OPTIONAL_SERVICES='cinder' + verify_connectivity() { for i in $(seq 0 9); do if echo "test" | nc -v -w 10 $1 $2 &>/dev/null; then @@ -16,6 +26,34 @@ verify_connectivity() { return 1 } +check_service() { + local service cmd + service=$1 + cmd=${service_cmd_array[$service]} + if [ -z "$2" ]; then + required='false' + else + required=$2 + fi + echo ">>Checking ${service} service..." + if ! openstack service list | grep -i ${service} > /dev/null; then + if [ "$required" == 'false' ]; then + echo "WARN: Optional Service ${service} is not enabled!" + return + else + echo "ERROR: Required Service ${service} is not enabled!" + exit 1 + fi + fi + $cmd &>/dev/null + result=$? + if [ $result -ne 0 ]; then + echo "ERROR: Failed execution $cmd. The $service does not seem to be working." + exit 1 + else + echo " ...OK" + fi +} if [ -z $OS_AUTH_URL ];then echo "ERROR: OS_AUTH_URL environment variable missing... Have you sourced the OpenStack credentials?" @@ -56,25 +94,16 @@ fi echo " ...OK" -echo "Checking OpenStack basic services:" -commands=('openstack endpoint list' 'openstack server list' 'openstack network list' \ - 'openstack image list' 'openstack volume list') -for cmd in "${commands[@]}" -do - service=$(echo $cmd | awk '{print $1, $2}') - echo ">>Checking $service service..." - $cmd &>/dev/null - result=$? - if [ $result -ne 0 ]; - then - echo "ERROR: Failed execution $cmd. The $service does not seem to be working." - exit 1 - else - echo " ...OK" - fi +echo "Checking Required OpenStack services:" +for service in $MANDATORY_SERVICES; do + check_service $service "true" done +echo "Required OpenStack services are OK." -echo "OpenStack services are OK." +echo "Checking Optional OpenStack services:" +for service in $OPTIONAL_SERVICES; do + check_service $service +done echo "Checking External network..." networks=($(neutron net-list -F id | tail -n +4 | head -n -1 | awk '{print $2}')) diff --git a/functest/ci/installer_params.yaml b/functest/ci/installer_params.yaml new file mode 100644 index 00000000..bffa894e --- /dev/null +++ b/functest/ci/installer_params.yaml @@ -0,0 +1,16 @@ +apex: + ip: '' + user: 'stack' + pkey: '/root/.ssh/id_rsa' +#compass: +# ip: '' +# user: 'root' +# password: 'root' +fuel: + ip: '10.20.0.2' + user: 'root' + password: 'r00tme' +#joid: +# ip: '' +# user: '' +# password: '' diff --git a/functest/ci/prepare_env.py b/functest/ci/prepare_env.py index 6b24fe08..80bcfc7d 100755 --- a/functest/ci/prepare_env.py +++ b/functest/ci/prepare_env.py @@ -21,13 +21,15 @@ import subprocess import sys import yaml -from opnfv.utils import constants as opnfv_constants 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 functest.utils.constants import CONST +from opnfv.utils import constants as opnfv_constants +from opnfv.deployment import factory + actions = ['start', 'check'] """ logging configuration """ @@ -278,6 +280,32 @@ def check_environment(): logger.info("Functest environment is installed.") +def print_deployment_info(): + installer_params_yaml = os.path.join(CONST.dir_repo_functest, + 'functest/ci/installer_params.yaml') + if (CONST.INSTALLER_IP and CONST.INSTALLER_TYPE and + CONST.INSTALLER_TYPE in opnfv_constants.INSTALLERS): + installer_params = ft_utils.get_parameter_from_yaml( + CONST.INSTALLER_TYPE, installer_params_yaml) + + user = installer_params.get('user', None) + password = installer_params.get('password', None) + pkey = installer_params.get('pkey', None) + + try: + handler = factory.Factory.get_handler( + installer=CONST.INSTALLER_TYPE, + installer_ip=CONST.INSTALLER_IP, + installer_user=user, + installer_pwd=password, + pkey_file=pkey) + if handler: + logger.info('\n\nDeployment information:\n%s' % + handler.get_deployment_info()) + except Exception as e: + logger.debug("Cannot get deployment information. %s" % e) + + def main(**kwargs): try: if not (kwargs['action'] in actions): @@ -296,6 +324,7 @@ def main(**kwargs): with open(CONST.env_active, "w") as env_file: env_file.write("1") check_environment() + print_deployment_info() elif kwargs['action'] == "check": check_environment() except Exception as e: diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index b93b01ee..a2633fcf 100755 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -402,7 +402,7 @@ tiers: - name: vnf order: 4 - ci_loop: '(daily)|(weekly)' + ci_loop: 'weekly' description : >- Collection of VNF test cases. testcases: @@ -415,7 +415,7 @@ tiers: using the Cloudify orchestrator. It also runs some signaling traffic. dependencies: installer: '' - scenario: 'nosdn-nofeature' + scenario: '(ocl)|(nosdn)|^(os-odl)((?!bgpvpn).)*$' run: module: 'functest.opnfv_tests.vnf.ims.cloudify_ims' class: 'ImsVnf' @@ -426,8 +426,8 @@ tiers: description: >- Test suite from Parser project. dependencies: - installer: 'unknown' - scenario: 'unknown' + installer: '' + scenario: '' run: module: 'functest.opnfv_tests.vnf.aaa.aaa' class: 'AaaVnf' diff --git a/functest/core/vnf_base.py b/functest/core/vnf_base.py index 8e98d8ed..9438dca1 100644 --- a/functest/core/vnf_base.py +++ b/functest/core/vnf_base.py @@ -111,9 +111,9 @@ class VnfOnBoardingBase(base.TestcaseBase): 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 == '': + admin_user_id = os_utils.get_user_id(self.keystone_client, + self.creds['username']) + if admin_user_id == '': self.step_failure("Failed to get id of " + self.creds['username']) @@ -133,7 +133,7 @@ class VnfOnBoardingBase(base.TestcaseBase): 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, + if not os_utils.add_role_user(self.keystone_client, admin_user_id, role_id, tenant_id): self.logger.error("Failed to add %s on tenant" % self.creds['username']) @@ -149,13 +149,22 @@ class VnfOnBoardingBase(base.TestcaseBase): self.logger.error("Failed to create %s user" % self.tenant_name) self.step_failure("Failed to create user ") + 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.tenant_name) + self.step_failure("Failed to add %s on tenant" % + self.tenant_name) + self.logger.info("Update OpenStack creds informations") - self.creds.update({ - "tenant": self.tenant_name, + self.admin_creds = self.creds.copy() + self.admin_creds.update({ + "tenant": self.tenant_name }) - self.neutron_client = os_utils.get_neutron_client(self.creds) - self.nova_client = os_utils.get_nova_client(self.creds) + self.neutron_client = os_utils.get_neutron_client(self.admin_creds) + self.nova_client = os_utils.get_nova_client(self.admin_creds) self.creds.update({ + "tenant": self.tenant_name, "username": self.tenant_name, "password": self.tenant_name, }) diff --git a/functest/opnfv_tests/features/security_scan.py b/functest/opnfv_tests/features/security_scan.py index bcae516b..2db44175 100755 --- a/functest/opnfv_tests/features/security_scan.py +++ b/functest/opnfv_tests/features/security_scan.py @@ -14,7 +14,7 @@ from functest.utils.constants import CONST class SecurityScan(base.FeatureBase): def __init__(self): - super(SecurityScan, self).__init__(project='security_scan', + super(SecurityScan, self).__init__(project='securityscanning', case='security_scan', repo='dir_repo_securityscan') self.cmd = ('bash {0} && ' diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py index 028b085c..893fff8c 100644 --- a/functest/opnfv_tests/openstack/tempest/conf_utils.py +++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py @@ -106,7 +106,19 @@ def get_verifier_deployment_dir(verifier_id, deployment_id): 'for-deployment-{}'.format(deployment_id)) -def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None): +def backup_tempest_config(conf_file): + """ + Copy config file to tempest results directory + """ + if not os.path.exists(TEMPEST_RESULTS_DIR): + os.makedirs(TEMPEST_RESULTS_DIR) + + shutil.copyfile(conf_file, + os.path.join(TEMPEST_RESULTS_DIR, 'tempest.conf')) + + +def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None, + MODE=None): """ Calls rally verify and updates the generated tempest.conf with given parameters @@ -114,6 +126,8 @@ def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None): conf_file = configure_verifier(deployment_dir) configure_tempest_update_params(conf_file, IMAGE_ID, FLAVOR_ID) + if MODE == 'feature_multisite': + configure_tempest_multisite_params(conf_file) def configure_tempest_update_params(tempest_conf_file, @@ -164,12 +178,7 @@ def configure_tempest_update_params(tempest_conf_file, with open(tempest_conf_file, 'wb') as config_file: config.write(config_file) - # Copy tempest.conf to /home/opnfv/functest/results/tempest/ - if not os.path.exists(TEMPEST_RESULTS_DIR): - os.makedirs(TEMPEST_RESULTS_DIR) - - shutil.copyfile(tempest_conf_file, - os.path.join(TEMPEST_RESULTS_DIR, 'tempest.conf')) + backup_tempest_config(tempest_conf_file) def configure_verifier(deployment_dir): @@ -196,25 +205,11 @@ def configure_verifier(deployment_dir): return tempest_conf_file -def configure_tempest_multisite(deployment_dir): +def configure_tempest_multisite_params(tempest_conf_file): """ - Add/update needed parameters into tempest.conf file generated by Rally + Add/update multisite parameters into tempest.conf file generated by Rally """ - logger.debug("configure the tempest") - configure_tempest(deployment_dir) - - logger.debug("Finding tempest.conf file...") - tempest_conf_old = os.path.join(deployment_dir, 'tempest.conf') - if not os.path.isfile(tempest_conf_old): - raise Exception("Tempest configuration file %s NOT found." - % tempest_conf_old) - - # Copy tempest.conf to /home/opnfv/functest/results/tempest/ - cur_path = os.path.split(os.path.realpath(__file__))[0] - tempest_conf_file = os.path.join(cur_path, 'tempest_multisite.conf') - shutil.copyfile(tempest_conf_old, tempest_conf_file) - - logger.debug("Updating selected tempest.conf parameters...") + logger.debug("Updating multisite tempest.conf parameters...") config = ConfigParser.RawConfigParser() config.read(tempest_conf_file) @@ -279,3 +274,5 @@ def configure_tempest_multisite(deployment_dir): config.set('kingbird', 'api_version', kingbird_api_version) with open(tempest_conf_file, 'wb') as config_file: config.write(config_file) + + backup_tempest_config(tempest_conf_file) diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 13d9e4e6..f925336d 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -113,7 +113,7 @@ class TempestCommon(testcase_base.TestcaseBase): if self.MODE == 'smoke': testr_mode = "smoke" elif self.MODE == 'feature_multisite': - testr_mode = " | grep -i kingbird " + testr_mode = "'[Kk]ingbird'" elif self.MODE == 'full': testr_mode = "" else: @@ -272,7 +272,8 @@ class TempestCommon(testcase_base.TestcaseBase): self.create_tempest_resources() conf_utils.configure_tempest(self.DEPLOYMENT_DIR, self.IMAGE_ID, - self.FLAVOR_ID) + self.FLAVOR_ID, + self.MODE) self.generate_test_list(self.VERIFIER_REPO_DIR) self.apply_tempest_blacklist() self.run_verifier_tests() @@ -319,7 +320,6 @@ class TempestMultisite(TempestCommon): self.case_name = "multisite" self.MODE = "feature_multisite" self.OPTION = "--concurrency 1" - conf_utils.configure_tempest_multisite(self.DEPLOYMENT_DIR) class TempestCustom(TempestCommon): diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py index efde44a0..584d780a 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py @@ -68,10 +68,10 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): def deploy_orchestrator(self, **kwargs): self.logger.info("Additional pre-configuration steps") - self.neutron_client = os_utils.get_neutron_client(self.creds) - self.glance_client = os_utils.get_glance_client(self.creds) - self.keystone_client = os_utils.get_keystone_client(self.creds) - self.nova_client = os_utils.get_nova_client(self.creds) + self.neutron_client = os_utils.get_neutron_client(self.admin_creds) + self.glance_client = os_utils.get_glance_client(self.admin_creds) + self.keystone_client = os_utils.get_keystone_client(self.admin_creds) + self.nova_client = os_utils.get_nova_client(self.admin_creds) # needs some images self.logger.info("Upload some OS images if it doesn't exist") @@ -130,8 +130,8 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): flavor_exist, flavor_id = os_utils.get_or_create_flavor( "m1.large", self.orchestrator['requirements']['ram_min'], - '1', - '1', + '50', + '2', public=True) self.logger.debug("Flavor id: %s" % flavor_id) @@ -187,8 +187,12 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): self.orchestrator['blueprint']['url'], self.orchestrator['blueprint']['branch']) - cfy.deploy_manager() - return {'status': 'PASS', 'result': ''} + error = cfy.deploy_manager() + if error: + self.logger.error(error) + return {'status': 'FAIL', 'result': error} + else: + return {'status': 'PASS', 'result': ''} def deploy_vnf(self): cw = Clearwater(self.vnf.inputs, self.orchestrator.object, self.logger) @@ -198,7 +202,7 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): flavor_exist, flavor_id = os_utils.get_or_create_flavor( "m1.small", self.vnf['requirements']['ram_min'], - '1', + '20', '1', public=True) self.logger.debug("Flavor id: %s" % flavor_id) @@ -229,8 +233,12 @@ class ImsVnf(vnf_base.VnfOnBoardingBase): cw.set_external_network_name(ext_net) - cw.deploy_vnf() - return {'status': 'PASS', 'result': ''} + error = cw.deploy_vnf() + if error: + self.logger.error(error) + return {'status': 'FAIL', 'result': error} + else: + return {'status': 'PASS', 'result': ''} def test_vnf(self): script = "source {0}venv_cloudify/bin/activate; " diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml index c5918087..775685fa 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml @@ -6,7 +6,7 @@ cloudify: url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git branch: '3.3.1-build' requirements: - ram_min: 3000 + ram_min: 4000 os_image: centos_7 inputs: keystone_username: "" @@ -29,7 +29,7 @@ clearwater: branch: stable deployment_name: clearwater-opnfv requirements: - ram_min: 1700 + ram_min: 2000 os_image: ubuntu_14.04 inputs: image_id: '' diff --git a/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py index f3838f87..775b71c8 100644 --- a/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py +++ b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py @@ -114,6 +114,7 @@ class Orchestrator: cmd = "/bin/bash -c '" + script + "'" error = execute_command(cmd, self.logger) if error: + self.logger.error("Failed to deploy cloudify-manager") return error self.logger.info("Cloudify-manager server is UP !") @@ -171,6 +172,7 @@ class Orchestrator: cmd = "/bin/bash -c '" + script + "'" error = execute_command(cmd, self.logger, 2000) if error: + self.logger.error("Failed to deploy blueprint") return error self.logger.info("The deployment of {0} is ended".format(dep_name)) @@ -228,7 +230,4 @@ def execute_command(cmd, logger, timeout=1800): logger.error("Error when executing command %s" % cmd) f = open(output_file, 'r') lines = f.readlines() - result = lines[len(lines) - 3] - result += lines[len(lines) - 2] - result += lines[len(lines) - 1] - return result + return lines[-5:] diff --git a/functest/utils/functest_logger.py b/functest/utils/functest_logger.py index 0cba8c52..6dc46ef2 100755 --- a/functest/utils/functest_logger.py +++ b/functest/utils/functest_logger.py @@ -30,9 +30,11 @@ from functest.utils.constants import CONST class Logger: + def __init__(self, logger_name): self.setup_logging() self.logger = logging.getLogger(logger_name) + logging.getLogger("paramiko").setLevel(logging.WARNING) def getLogger(self): return self.logger diff --git a/functest/utils/openstack_tacker.py b/functest/utils/openstack_tacker.py index f3597965..07acc8b3 100644 --- a/functest/utils/openstack_tacker.py +++ b/functest/utils/openstack_tacker.py @@ -45,8 +45,16 @@ 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_vnf_id(tacker_client, vnf_name, timeout=5): + vnf_id = None + while vnf_id is None and timeout >= 0: + vnf_id = get_id_from_name(tacker_client, 'vnf', vnf_name) + if vnf_id is None: + logger.info("Could not retrieve ID for vnf with name [%s]." + " Retrying." % vnf_name) + time.sleep(1) + timeout -= 1 + return vnf_id def get_sfc_id(tacker_client, sfc_name): @@ -118,6 +126,7 @@ def create_vnf(tacker_client, vnf_name, vnfd_id=None, } } if param_file is not None: + params = None with open(param_file) as f: params = f.read() vnf_body['vnf']['attributes']['param_values'] = params @@ -135,32 +144,39 @@ def create_vnf(tacker_client, vnf_name, vnfd_id=None, return None -def wait_for_vnf(tacker_client, vnf_id=None, vnf_name=None): +def get_vnf(tacker_client, vnf_id=None, vnf_name=None): try: - _id = None - if vnf_id is not None: - _id = vnf_id - elif vnf_name is not None: - while _id is None: - try: - _id = get_vnf_id(tacker_client, vnf_name) - except: - logger.error("Bazinga") - else: + if vnf_id is None and vnf_name is None: raise Exception('You must specify vnf_id or vnf_name') - while True: - vnf = [v for v in list_vnfs(tacker_client, verbose=True)['vnfs'] - if v['id'] == _id] - vnf = vnf[0] - logger.info('Waiting for vnf {0}'.format(str(vnf))) + + _id = get_vnf_id(tacker_client, vnf_name) if vnf_id is None else vnf_id + + if _id is not None: + all_vnfs = list_vnfs(tacker_client, verbose=True)['vnfs'] + return next((vnf for vnf in all_vnfs if vnf['id'] == _id), None) + else: + raise Exception('Could not retrieve ID from name [%s]' % vnf_name) + + except Exception, e: + logger.error("Could not retrieve VNF [vnf_id=%s, vnf_name=%s] - %s" + % (vnf_id, vnf_name, e)) + return None + + +def wait_for_vnf(tacker_client, vnf_id=None, vnf_name=None, timeout=60): + try: + vnf = get_vnf(tacker_client, vnf_id, vnf_name) + if vnf is None: + raise Exception("Could not retrieve VNF - id='%s', name='%s'" + % vnf_id, vnf_name) + logger.info('Waiting for vnf {0}'.format(str(vnf))) + while vnf['status'] != 'ACTIVE' and timeout >= 0: if vnf['status'] == 'ERROR': - raise Exception('Error when booting vnf %s' % _id) + raise Exception('Error when booting vnf %s' % vnf['id']) elif vnf['status'] == 'PENDING_CREATE': time.sleep(3) - continue - else: - break - return _id + timeout -= 3 + return vnf['id'] except Exception, e: logger.error("error [wait_for_vnf(tacker_client, '%s', '%s')]: %s" % (vnf_id, vnf_name, e)) @@ -194,7 +210,8 @@ def list_sfcs(tacker_client, verbose=False): def create_sfc(tacker_client, sfc_name, chain_vnf_ids=None, - chain_vnf_names=None): + chain_vnf_names=None, + symmetrical=False): try: sfc_body = { 'sfc': { @@ -203,6 +220,8 @@ def create_sfc(tacker_client, sfc_name, 'chain': [] } } + if symmetrical: + sfc_body['sfc']['symmetrical'] = True if chain_vnf_ids is not None: sfc_body['sfc']['chain'] = chain_vnf_ids else: |