#!/usr/bin/env python # Copyright (c) 2017 Okinawa Open Laboratory 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 """ Utility module of vrouter testcase """ import json import logging import os import pkg_resources import requests import yaml from functest.utils.constants import CONST from git import Repo from novaclient import client as novaclient from keystoneauth1.identity import v3 from keystoneauth1 import session from requests.auth import HTTPBasicAuth RESULT_SPRIT_INDEX = { "transfer": 8, "bandwidth": 6, "jitter": 4, "los_total": 2, "pkt_loss": 1 } BIT_PER_BYTE = 8 NOVA_CLIENT_API_VERSION = '2' NOVA_CILENT_NETWORK_INFO_INDEX = 0 CFY_INFO_OUTPUT_FILE = "output.txt" CIDR_NETWORK_SEGMENT_INFO_INDEX = 0 PACKET_LOST_INFO_INDEX = 0 PACKET_TOTAL_INFO_INDEX = 1 NUMBER_OF_DIGITS_FOR_AVG_TRANSFER = 0 NUMBER_OF_DIGITS_FOR_AVG_BANDWIDTH = 0 NUMBER_OF_DIGITS_FOR_AVG_JITTER = 3 NUMBER_OF_DIGITS_FOR_AVG_PKT_LOSS = 1 class Utilvnf(object): """ Utility class of vrouter testcase """ logger = logging.getLogger(__name__) def __init__(self): self.username = "" self.password = "" self.auth_url = "" self.tenant_name = "" data_dir = data_dir = CONST.__getattribute__('dir_router_data') self.vnf_data_dir = data_dir self.opnfv_vnf_data_dir = "opnfv-vnf-data/" self.command_template_dir = "command_template/" self.test_scenario_yaml = "test_scenario.yaml" test_env_config_yaml_file = "test_env_config.yaml" self.test_cmd_map_yaml_file = "test_cmd_map.yaml" self.test_env_config_yaml = os.path.join( self.vnf_data_dir, self.opnfv_vnf_data_dir, test_env_config_yaml_file) self.blueprint_dir = "opnfv-vnf-vyos-blueprint/" self.blueprint_file_name = "function-test-openstack-blueprint.yaml" if not os.path.exists(self.vnf_data_dir): os.makedirs(self.vnf_data_dir) case_dir = pkg_resources.resource_filename( 'functest', 'opnfv_tests/vnf/router') config_file_name = CONST.__getattribute__( 'vnf_{}_config'.format("vyos_vrouter")) config_file = os.path.join(case_dir, config_file_name) with open(config_file) as file_fd: vrouter_config_yaml = yaml.safe_load(file_fd) file_fd.close() test_data = vrouter_config_yaml.get("test_data") self.logger.debug("Downloading the test data.") vrouter_data_path = self.vnf_data_dir + self.opnfv_vnf_data_dir if not os.path.exists(vrouter_data_path): Repo.clone_from(test_data['url'], vrouter_data_path, branch=test_data['branch']) with open(self.test_env_config_yaml) as file_fd: test_env_config_yaml = yaml.safe_load(file_fd) file_fd.close() self.image = test_env_config_yaml.get( "general").get("images").get("vyos") self.tester_image = test_env_config_yaml.get( "general").get("images").get("tester_vm_os") self.test_result_json_file = "test_result.json" if os.path.isfile(self.test_result_json_file): os.remove(self.test_result_json_file) self.logger.debug("removed %s" % self.test_result_json_file) def get_nova_client(self): creds = self.get_nova_credentials() auth = v3.Password(auth_url=creds['auth_url'], username=creds['username'], password=creds['password'], project_name=creds['tenant_name'], user_domain_id='default', project_domain_id='default') sess = session.Session(auth=auth) nova_client = novaclient.Client(NOVA_CLIENT_API_VERSION, session=sess) return nova_client def set_credentials(self, username, password, auth_url, tenant_name): self.username = username self.password = password self.auth_url = auth_url self.tenant_name = tenant_name def get_nova_credentials(self): creds = {} creds['username'] = self.username creds['password'] = self.password creds['auth_url'] = self.auth_url creds['tenant_name'] = self.tenant_name return creds def get_address(self, server_name, network_name): nova_client = self.get_nova_client() servers_list = nova_client.servers.list() server = None for server in servers_list: if server.name == server_name: break address = server.addresses[ network_name][NOVA_CILENT_NETWORK_INFO_INDEX]["addr"] return address def get_mac_address(self, server_name, network_name): nova_client = self.get_nova_client() servers_list = nova_client.servers.list() server = None for server in servers_list: if server.name == server_name: break mac_address = server.addresses[network_name][ NOVA_CILENT_NETWORK_INFO_INDEX][ "OS-EXT-IPS-MAC:mac_addr"] return mac_address def reboot_vm(self, server_name): nova_client = self.get_nova_client() servers_list = nova_client.servers.list() server = None for server in servers_list: if server.name == server_name: break server.reboot() return def delete_vm(self, server_name): nova_client = self.get_nova_client() servers_list = nova_client.servers.list() server = None for server in servers_list: if server.name == server_name: nova_client.servers.delete(server) break return def get_blueprint_outputs(self, cfy_manager_ip, deployment_name): url = "http://%s/deployments/%s/outputs" % ( cfy_manager_ip, deployment_name) response = requests.get( url, auth=HTTPBasicAuth('admin', 'admin'), headers={'Tenant': 'default_tenant'}) resp_data = response.json() self.logger.debug(resp_data) data = resp_data["outputs"] return data def get_blueprint_outputs_vnfs(self, cfy_manager_ip, deployment_name): outputs = self.get_blueprint_outputs(cfy_manager_ip, deployment_name) vnfs = outputs["vnfs"] vnf_list = [] for vnf_name in vnfs: vnf_list.append(vnfs[vnf_name]) return vnf_list def get_blueprint_outputs_networks(self, cfy_manager_ip, deployment_name): outputs = self.get_blueprint_outputs(cfy_manager_ip, deployment_name) networks = outputs["networks"] network_list = [] for network_name in networks: network_list.append(networks[network_name]) return network_list def request_vnf_reboot(self, vnf_info_list): for vnf in vnf_info_list: self.logger.debug("reboot the " + vnf["vnf_name"]) self.reboot_vm(vnf["vnf_name"]) def request_vm_delete(self, vnf_info_list): for vnf in vnf_info_list: self.logger.debug("delete the " + vnf["vnf_name"]) self.delete_vm(vnf["vnf_name"]) def get_vnf_info_list(self, cfy_manager_ip, topology_deploy_name, target_vnf_name): network_list = self.get_blueprint_outputs_networks( cfy_manager_ip, topology_deploy_name) vnf_info_list = self.get_blueprint_outputs_vnfs(cfy_manager_ip, topology_deploy_name) for vnf in vnf_info_list: vnf_name = vnf["vnf_name"] vnf["os_type"] = self.image["os_type"] vnf["user"] = self.image["user"] vnf["pass"] = self.image["pass"] if vnf_name == target_vnf_name: vnf["target_vnf_flag"] = True else: vnf["target_vnf_flag"] = False self.logger.debug("vnf name : " + vnf_name) self.logger.debug(vnf_name + " floating ip address : " + vnf["floating_ip"]) for network in network_list: network_name = network["network_name"] ip_address = self.get_address(vnf["vnf_name"], network["network_name"]) vnf[network_name + "_ip"] = ip_address mac = self.get_mac_address(vnf["vnf_name"], network["network_name"]) vnf[network_name + "_mac"] = mac self.logger.debug(network_name + "_ip of " + vnf["vnf_name"] + " : " + vnf[network_name + "_ip"]) self.logger.debug(network_name + "_mac of " + vnf["vnf_name"] + " : " + vnf[network_name + "_mac"]) return vnf_info_list def get_target_vnf(self, vnf_info_list): for vnf in vnf_info_list: if vnf["target_vnf_flag"]: return vnf return None def get_reference_vnf_list(self, vnf_info_list): reference_vnf_list = [] for vnf in vnf_info_list: if not vnf["target_vnf_flag"]: reference_vnf_list.append(vnf) return reference_vnf_list def get_vnf_info(self, vnf_info_list, vnf_name): for vnf in vnf_info_list: if vnf["vnf_name"] == vnf_name: return vnf return None def convert_functional_test_result(self, result_data_list): result = {} for result_data in result_data_list: test_kind = result_data["test_kind"] protocol = result_data["protocol"] test_result_data = result_data["result"] if test_kind not in result: result[test_kind] = [] result[test_kind].append({protocol: test_result_data}) return {"Functional_test": result} def write_result_data(self, result_data): test_result = [] if not os.path.isfile(self.test_result_json_file): file_fd = open(self.test_result_json_file, "w") file_fd.close() else: file_fd = open(self.test_result_json_file, "r") test_result = json.load(file_fd) file_fd.close() test_result.append(result_data) file_fd = open(self.test_result_json_file, "w") json.dump(test_result, file_fd) file_fd.close() def output_test_result_json(self): if os.path.isfile(self.test_result_json_file): file_fd = open(self.test_result_json_file, "r") test_result = json.load(file_fd) file_fd.close() output_json_data = json.dumps(test_result, sort_keys=True, indent=4) self.logger.debug("test_result %s" % output_json_data) else: self.logger.debug("Not found %s" % self.test_result_json_file) def get_test_scenario(self, file_path): test_scenario_file = open(file_path, 'r') test_scenario_yaml = yaml.safe_load(test_scenario_file) test_scenario_file.close() return test_scenario_yaml["test_scenario_list"]