X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=functest%2Fopnfv_tests%2Fvnf%2Fepc%2Fjuju_epc.py;h=1cf240b80810ce5ea90e97de0a3ba7b8a8632bd7;hb=4fdbdd34fb5fea55571a18b2438ececa953928ff;hp=9e5f8d33b39e9dfd2d242aa3193a7169d2a13c9b;hpb=2185f7ba88abae4c5b575a98cffd1fe9cfcfb42d;p=functest.git diff --git a/functest/opnfv_tests/vnf/epc/juju_epc.py b/functest/opnfv_tests/vnf/epc/juju_epc.py index 9e5f8d33b..1cf240b80 100644 --- a/functest/opnfv_tests/vnf/epc/juju_epc.py +++ b/functest/opnfv_tests/vnf/epc/juju_epc.py @@ -13,33 +13,17 @@ import logging import os import time import json +import re import sys -import uuid + from copy import deepcopy -from urlparse import urljoin import pkg_resources -import yaml +import scp -from functest.core import vnf -from functest.opnfv_tests.openstack.snaps import snaps_utils +from functest.core import singlevm from functest.utils import config from functest.utils import env - -from snaps.config.flavor import FlavorConfig -from snaps.config.image import ImageConfig -from snaps.config.network import NetworkConfig, SubnetConfig -from snaps.config.router import RouterConfig -from snaps.config.security_group import ( - Direction, Protocol, SecurityGroupConfig, SecurityGroupRuleConfig) -from snaps.config.user import UserConfig -from snaps.openstack.create_flavor import OpenStackFlavor -from snaps.openstack.create_image import OpenStackImage -from snaps.openstack.create_network import OpenStackNetwork -from snaps.openstack.create_router import OpenStackRouter -from snaps.openstack.create_security_group import OpenStackSecurityGroup -from snaps.openstack.create_user import OpenStackUser -from snaps.openstack.utils import keystone_utils -from snaps.openstack.utils import nova_utils +from functest.utils import functest_utils __author__ = "Amarendra Meher " __author__ = "Soumaya K Nayek " @@ -58,180 +42,186 @@ CREDS_TEMPLATE2 = """credentials: default-credential: abot-epc abot-epc: auth-type: userpass - password: {pass} + password: '{pass}' project-domain-name: {project_domain_n} tenant-name: {tenant_n}""" -CREDS_TEMPLATE3 = """credentials: +CREDS_TEMPLATE = """credentials: abot-epc: default-credential: abot-epc abot-epc: auth-type: userpass - password: {pass} + password: '{pass}' project-domain-name: {project_domain_n} tenant-name: {tenant_n} user-domain-name: {user_domain_n} username: {user_n}""" -class JujuEpc(vnf.VnfOnBoarding): +class JujuEpc(singlevm.SingleVm2): # pylint:disable=too-many-instance-attributes """Abot EPC deployed with JUJU Orchestrator Case""" __logger = logging.getLogger(__name__) + cidr = '192.168.120.0/24' + + filename = ('/home/opnfv/functest/images/' + 'ubuntu-16.04-server-cloudimg-amd64-disk1.img') + filename_alt = ('/home/opnfv/functest/images/' + 'ubuntu-14.04-server-cloudimg-amd64-disk1.img') + + flavor_ram = 2048 + flavor_vcpus = 1 + flavor_disk = 10 + flavor_alt_ram = 4096 + flavor_alt_vcpus = 1 + flavor_alt_disk = 10 + username = 'ubuntu' + juju_timeout = '4800' + def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "juju_epc" - super(JujuEpc, self).__init__(**kwargs) + super().__init__(**kwargs) # Retrieve the configuration self.case_dir = pkg_resources.resource_filename( 'functest', 'opnfv_tests/vnf/epc') try: self.config = getattr( - config.CONF, 'vnf_{}_config'.format(self.case_name)) - except Exception: - raise Exception("VNF config file not found") + config.CONF, f'vnf_{self.case_name}_config') + except Exception as exc: + raise Exception("VNF config file not found") from exc self.config_file = os.path.join(self.case_dir, self.config) - self.orchestrator = dict(requirements=get_config( - "orchestrator.requirements", self.config_file)) + self.orchestrator = dict( + requirements=functest_utils.get_parameter_from_yaml( + "orchestrator.requirements", self.config_file)) self.created_object = [] self.details['orchestrator'] = dict( - name=get_config("orchestrator.name", self.config_file), - version=get_config("orchestrator.version", self.config_file), + name=functest_utils.get_parameter_from_yaml( + "orchestrator.name", self.config_file), + version=functest_utils.get_parameter_from_yaml( + "orchestrator.version", self.config_file), status='ERROR', result='' ) self.vnf = dict( - descriptor=get_config("vnf.descriptor", self.config_file), - requirements=get_config("vnf.requirements", self.config_file) + descriptor=functest_utils.get_parameter_from_yaml( + "vnf.descriptor", self.config_file), + requirements=functest_utils.get_parameter_from_yaml( + "vnf.requirements", self.config_file) ) self.details['vnf'] = dict( descriptor_version=self.vnf['descriptor']['version'], - name=get_config("vnf.name", self.config_file), - version=get_config("vnf.version", self.config_file), + name=functest_utils.get_parameter_from_yaml( + "vnf.name", self.config_file), + version=functest_utils.get_parameter_from_yaml( + "vnf.version", self.config_file), ) self.__logger.debug("VNF configuration: %s", self.vnf) self.details['test_vnf'] = dict( - name=get_config("vnf_test_suite.name", self.config_file), - version=get_config("vnf_test_suite.version", self.config_file), - tag_name=get_config("vnf_test_suite.tag_name", self.config_file) + name=functest_utils.get_parameter_from_yaml( + "vnf_test_suite.name", self.config_file), + version=functest_utils.get_parameter_from_yaml( + "vnf_test_suite.version", self.config_file), + tag_name=functest_utils.get_parameter_from_yaml( + "vnf_test_suite.tag_name", self.config_file) ) - self.public_auth_url = None self.res_dir = os.path.join( getattr(config.CONF, 'dir_results'), self.case_name) - def _bypass_juju_network_discovery_bug(self, name): - user_creator = OpenStackUser( - self.snaps_creds, - UserConfig( - name=name, - password=str(uuid.uuid4()), - project_name=self.tenant_name, - domain=self.snaps_creds.user_domain_name, - roles={'_member_': self.tenant_name})) - user_creator.create() - self.created_object.append(user_creator) - return user_creator + try: + self.public_auth_url = self.get_public_auth_url(self.orig_cloud) + if not self.public_auth_url.endswith(('v3', 'v3/')): + self.public_auth_url = f"{self.public_auth_url}/v3" + except Exception: # pylint: disable=broad-except + self.public_auth_url = None + self.sec = None + self.image_alt = None + self.flavor_alt = None + + def _install_juju(self): + (_, stdout, stderr) = self.ssh.exec_command( + 'sudo snap install juju --channel=2.3/stable --classic') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() + + def _install_juju_wait(self): + (_, stdout, stderr) = self.ssh.exec_command( + 'sudo apt-get update && sudo apt-get install python3-pip -y && ' + 'sudo pip3 install juju_wait===2.6.4') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() def _register_cloud(self): + assert self.public_auth_url self.__logger.info("Creating Cloud for Abot-epc .....") clouds_yaml = os.path.join(self.res_dir, "clouds.yaml") - # It allows gating APEX and ensures this testcase is working till - # https://jira.opnfv.org/browse/APEX-570 is fixed in APEX. - # It must be removed as soon as possible to disable per installer - # processing in Functest. - region = self.snaps_creds.region_name - if not region and env.get('INSTALLER_TYPE') == 'apex': - region = "regionOne" cloud_data = { 'url': self.public_auth_url, - 'region': region} - with open(clouds_yaml, 'w') as yfile: + 'region': self.cloud.region_name if self.cloud.region_name else ( + 'RegionOne')} + with open(clouds_yaml, 'w', encoding='utf-8') as yfile: yfile.write(CLOUD_TEMPLATE.format(**cloud_data)) - if os.system( - 'juju add-cloud abot-epc -f {} --replace'.format(clouds_yaml)): - raise vnf.VnfPreparationException - - def _register_credentials_v2(self): - self.__logger.info("Creating Credentials for Abot-epc .....") - user_creator = self._bypass_juju_network_discovery_bug( - 'juju_network_discovery_bug') - snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name) - self.__logger.debug("snaps creds: %s", snaps_creds) - credentials_yaml = os.path.join(self.res_dir, "credentials.yaml") - creds_data = { - 'pass': snaps_creds.password, - 'tenant_n': snaps_creds.project_name, - 'user_n': snaps_creds.username} - with open(credentials_yaml, 'w') as yfile: - yfile.write(CREDS_TEMPLATE2.format(**creds_data)) - if os.system( - 'juju add-credential abot-epc -f {} --replace'.format( - credentials_yaml)): - raise vnf.VnfPreparationException - - def _register_credentials_v3(self): + scpc = scp.SCPClient(self.ssh.get_transport()) + scpc.put(clouds_yaml, remote_path='~/') + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju add-cloud abot-epc -f clouds.yaml --replace') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() + + def _register_credentials(self): self.__logger.info("Creating Credentials for Abot-epc .....") - user_creator = self._bypass_juju_network_discovery_bug( - 'juju_network_discovery_bug') - snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name) - self.__logger.debug("snaps creds: %s", snaps_creds) credentials_yaml = os.path.join(self.res_dir, "credentials.yaml") creds_data = { - 'pass': snaps_creds.password, - 'tenant_n': snaps_creds.project_name, - 'user_n': snaps_creds.username, - 'project_domain_n': snaps_creds.project_domain_name, - 'user_domain_n': snaps_creds.user_domain_name} - with open(credentials_yaml, 'w') as yfile: - yfile.write(CREDS_TEMPLATE3.format(**creds_data)) - if os.system( - 'juju add-credential abot-epc -f {} --replace'.format( - credentials_yaml)): - raise vnf.VnfPreparationException - - def _add_custom_rule(self, sec_grp_name): - """ To add custom rule for SCTP Traffic """ - sec_grp_rules = list() - sec_grp_rules.append( - SecurityGroupRuleConfig( - sec_grp_name=sec_grp_name, direction=Direction.ingress, - protocol=Protocol.sctp)) - security_group = OpenStackSecurityGroup( - self.snaps_creds, - SecurityGroupConfig( - name=sec_grp_name, - rule_settings=sec_grp_rules)) - security_group.create() - self.created_object.append(security_group) - - def prepare(self): - """Prepare testcase (Additional pre-configuration steps).""" - self.__logger.info("Additional pre-configuration steps") - super(JujuEpc, self).prepare() - try: - os.makedirs(self.res_dir) - except OSError as ex: - if ex.errno != errno.EEXIST: - self.__logger.exception("Cannot create %s", self.res_dir) - raise vnf.VnfPreparationException - self.public_auth_url = keystone_utils.get_endpoint( - self.snaps_creds, 'identity') - # it enforces a versioned public identity endpoint as juju simply - # adds /auth/tokens wich fails vs an unversioned endpoint. - if not self.public_auth_url.endswith(('v3', 'v3/', 'v2.0', 'v2.0/')): - self.public_auth_url = urljoin(self.public_auth_url, 'v3') - self._register_cloud() - if self.snaps_creds.identity_api_version == 3: - self._register_credentials_v3() - else: - self._register_credentials_v2() + 'pass': self.project.password, + 'tenant_n': self.project.project.name, + 'user_n': self.project.user.name, + 'project_domain_n': self.cloud.auth.get( + "project_domain_name", "Default"), + 'user_domain_n': self.cloud.auth.get( + "user_domain_name", "Default")} + with open(credentials_yaml, 'w', encoding='utf-8') as yfile: + yfile.write(CREDS_TEMPLATE.format(**creds_data)) + scpc = scp.SCPClient(self.ssh.get_transport()) + scpc.put(credentials_yaml, remote_path='~/') + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju add-credential abot-epc -f credentials.yaml ' + ' --replace --debug') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() + + def _publish_image(self): + region_name = self.cloud.region_name if self.cloud.region_name else ( + 'RegionOne') + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju metadata generate-image -d /home/ubuntu ' + f'-i {self.image.id} -s xenial -r {region_name} ' + f'-u {self.public_auth_url}') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() + + def publish_image_alt(self, name=None): + image_alt = super().publish_image_alt(name) + region_name = self.cloud.region_name if self.cloud.region_name else ( + 'RegionOne') + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju metadata generate-image -d /home/ubuntu ' + f'-i {image_alt.id} -s trusty -r {region_name} ' + f'-u {self.public_auth_url}') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return image_alt def deploy_orchestrator(self): # pylint: disable=too-many-locals """ @@ -239,204 +229,181 @@ class JujuEpc(vnf.VnfOnBoarding): Bootstrap juju """ - self.__logger.info("Deployed Orchestrator") - private_net_name = getattr( - config.CONF, 'vnf_{}_private_net_name'.format(self.case_name)) - private_subnet_name = '{}-{}'.format( - getattr(config.CONF, - 'vnf_{}_private_subnet_name'.format(self.case_name)), - self.uuid) - private_subnet_cidr = getattr( - config.CONF, 'vnf_{}_private_subnet_cidr'.format(self.case_name)) - abot_router = '{}-{}'.format( - getattr(config.CONF, - 'vnf_{}_external_router'.format(self.case_name)), - self.uuid) - self.__logger.info("Creating full network ...") - subnet_settings = SubnetConfig( - name=private_subnet_name, cidr=private_subnet_cidr) - network_settings = NetworkConfig( - name=private_net_name, subnet_settings=[subnet_settings]) - network_creator = OpenStackNetwork(self.snaps_creds, network_settings) - net_id = network_creator.create().id - self.created_object.append(network_creator) - - ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds) - self.__logger.info("Creating network Router ....") - router_creator = OpenStackRouter( - self.snaps_creds, RouterConfig( - name=abot_router, - external_gateway=ext_net_name, - internal_subnets=[subnet_settings.name])) - router_creator.create() - self.created_object.append(router_creator) - self.__logger.info("Creating Flavor ....") - flavor_settings = FlavorConfig( - name=self.orchestrator['requirements']['flavor']['name'], - ram=self.orchestrator['requirements']['flavor']['ram_min'], - disk=10, vcpus=1) - flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings) - flavor_creator.create() - self.created_object.append(flavor_creator) - self.__logger.info("Upload some OS images if it doesn't exist") - images = get_config("tenant_images", self.config_file) - self.__logger.info("Images needed for vEPC: %s", images) - for image_name, image_file in images.iteritems(): - self.__logger.info("image: %s, file: %s", image_name, image_file) - if image_file and image_name: - image_creator = OpenStackImage(self.snaps_creds, ImageConfig( - name=image_name, image_user='cloud', img_format='qcow2', - image_file=image_file)) - image_id = image_creator.create().id - # It allows gating APEX and ensures this testcase is working - # till https://jira.opnfv.org/browse/APEX-570 is fixed in APEX. - # It must be removed as soon as possible to disable per - # installer processing in Functest. - region = self.snaps_creds.region_name - if not region and env.get('INSTALLER_TYPE') == 'apex': - region = "regionOne" - os.system( - 'juju metadata generate-image -d ~ -i {} -s {} -r ' - '{} -u {}'.format( - image_id, image_name, region, - self.public_auth_url)) - self.created_object.append(image_creator) - self.__logger.info("Network ID : %s", net_id) - juju_bootstrap_command = ( - 'juju bootstrap abot-epc abot-controller --config network={} ' - '--metadata-source ~ --config ssl-hostname-verification=false ' + self._publish_image() + self.image_alt = self.publish_image_alt() + self.flavor_alt = self.create_flavor_alt() + self.__logger.info("Starting Juju Bootstrap process...") + region_name = self.cloud.region_name if self.cloud.region_name else ( + 'RegionOne') + (_, stdout, stderr) = self.ssh.exec_command( + f'timeout {JujuEpc.juju_timeout} ' + f'/snap/bin/juju bootstrap abot-epc/{region_name} abot-controller ' + '--agent-version 2.3.9 --metadata-source /home/ubuntu ' '--constraints mem=2G --bootstrap-series xenial ' - '--config use-floating-ip=true --debug ' - '--config use-default-secgroup=true'.format(net_id)) - os.system(juju_bootstrap_command) + f'--config network={self.network.id} ' + '--config ssl-hostname-verification=false ' + f'--config external-network={self.ext_net.id} ' + '--config use-floating-ip=true ' + '--config use-default-secgroup=true ' + '--debug') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() + + def check_app(self, name='abot-epc-basic', status='active'): + """Check application status.""" + for i in range(10): + (_, stdout, stderr) = self.ssh.exec_command( + f'/snap/bin/juju status --format short {name}') + output = stdout.read().decode("utf-8") + self.__logger.debug("stdout:\n%s", output) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + continue + ret = re.search( + rf'(?=workload:({status})\))', output) + if ret: + self.__logger.info("%s workload is %s", name, status) + break + self.__logger.info( + "loop %d: %s workload differs from %s", i + 1, name, status) + time.sleep(60) + else: + self.__logger.error("%s workload differs from %s", name, status) + return False return True def deploy_vnf(self): """Deploy ABOT-OAI-EPC.""" self.__logger.info("Upload VNFD") - descriptor = self.vnf['descriptor'] - self.__logger.info("Get or create flavor for all Abot-EPC") - flavor_settings = FlavorConfig( - name=self.vnf['requirements']['flavor']['name'], - ram=self.vnf['requirements']['flavor']['ram_min'], - disk=10, - vcpus=1) - flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings) - flavor_creator.create() - self.created_object.append(flavor_creator) + scpc = scp.SCPClient(self.ssh.get_transport()) + scpc.put( + '/src/epc-requirements/abot_charm', remote_path='~/', + recursive=True) self.__logger.info("Deploying Abot-epc bundle file ...") - os.system('juju deploy {}'.format('/' + descriptor.get('file_name'))) - self.__logger.info("Waiting for instances .....") - status = os.system('juju-wait') - self.__logger.info("juju wait completed: %s", status) - self.__logger.info("Deployed Abot-epc on Openstack") - nova_client = nova_utils.nova_client(self.snaps_creds) - if status == 0: - instances = get_instances(nova_client) - self.__logger.info("List of Instance: %s", instances) - for items in instances: - metadata = get_instance_metadata(nova_client, items) - if 'juju-units-deployed' in metadata: - sec_group = ('juju-' + - metadata['juju-controller-uuid'] + - '-' + metadata['juju-model-uuid']) - self.__logger.info("Instance: %s", sec_group) - break - self.__logger.info("Adding Security group rule....") - # This will add sctp rule to a common Security Group Created - # by juju and shared to all deployed units. - self._add_custom_rule(sec_group) - self.__logger.info("Copying the feature files to Abot_node ") - os.system('juju scp -- -r {}/featureFiles abot-' - 'epc-basic/0:~/'.format(self.case_dir)) - self.__logger.info("Copying the feature files in Abot_node ") - os.system("juju ssh abot-epc-basic/0 'sudo rsync -azvv " - "~/featureFiles /etc/rebaca-test-suite" - "/featureFiles'") - count = 0 - while count < 10: - epcstatus = os.system('juju status oai-epc | ' - 'grep {} | grep {} | grep {}' - .format('EPC', 'is', 'running')) - if epcstatus == 0: - break - else: - time.sleep(60) - count = count + 1 - os.system('juju-wait') - return True - return False + (_, stdout, stderr) = self.ssh.exec_command( + 'sudo mkdir -p /src/epc-requirements && ' + 'sudo mv abot_charm /src/epc-requirements/abot_charm && ' + '/snap/bin/juju deploy ' + '/src/epc-requirements/abot_charm/functest-abot-epc-bundle/' + 'bundle.yaml') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() + (_, stdout, stderr) = self.ssh.exec_command( + 'PATH=/snap/bin/:$PATH ' + f'timeout {JujuEpc.juju_timeout} juju-wait') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() + self.__logger.info("Checking status of ABot and EPC units ...") + (_, stdout, stderr) = self.ssh.exec_command('/snap/bin/juju status') + output = stdout.read().decode("utf-8") + self.__logger.debug("stdout:\n%s", output) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() + for app in ['abot-epc-basic', 'oai-epc', 'oai-hss']: + if not self.check_app(app): + return False + scpc = scp.SCPClient(self.ssh.get_transport()) + scpc.put( + f'{self.case_dir}/featureFiles', remote_path='~/', + recursive=True) + (_, stdout, stderr) = self.ssh.exec_command( + f'timeout {JujuEpc.juju_timeout} /snap/bin/juju scp -- -r -v ' + '~/featureFiles abot-epc-basic/0:/etc/rebaca-test-suite/') + output = stdout.read().decode("utf-8") + self.__logger.debug("stdout:\n%s", output) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + return not stdout.channel.recv_exit_status() def test_vnf(self): """Run test on ABoT.""" start_time = time.time() - self.__logger.info("Running VNF Test cases....") - os.system('juju run-action abot-epc-basic/0 run ' - 'tagnames={}'.format(self.details['test_vnf']['tag_name'])) - os.system('juju-wait') + (_, stdout, stderr) = self.ssh.exec_command( + "/snap/bin/juju run-action abot-epc-basic/0 " + f"run tagnames={self.details['test_vnf']['tag_name']}") + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() + (_, stdout, stderr) = self.ssh.exec_command( + 'PATH=/snap/bin/:$PATH ' + f'timeout {JujuEpc.juju_timeout} juju-wait') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() duration = time.time() - start_time self.__logger.info("Getting results from Abot node....") - os.system('juju scp abot-epc-basic/0:/var/lib/abot-' - 'epc-basic/artifacts/TestResults.json {}/.' - .format(self.case_dir)) + (_, stdout, stderr) = self.ssh.exec_command( + f'timeout {JujuEpc.juju_timeout} /snap/bin/juju scp ' + '-- -v abot-epc-basic/0:' + '/var/lib/abot-epc-basic/artifacts/TestResults.json .') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + if stdout.channel.recv_exit_status(): + return not stdout.channel.recv_exit_status() + scpc = scp.SCPClient(self.ssh.get_transport()) + scpc.get('TestResults.json', self.res_dir) self.__logger.info("Parsing the Test results...") - res = (process_abot_test_result('{}/TestResults.' - 'json'.format(self.case_dir))) + res = process_abot_test_result(f'{self.res_dir}/TestResults.json') short_result = sig_test_format(res) self.__logger.info(short_result) - self.details['test_vnf'].update(status='PASS', - result=short_result, - full_result=res, - duration=duration) - - self.__logger.info("Test VNF result: Passed: %d, Failed:" - "%d, Skipped: %d", short_result['passed'], - short_result['failures'], short_result['skipped']) + self.details['test_vnf'].update( + status='PASS', result=short_result, full_result=res, + duration=duration) + self.__logger.info( + "Test VNF result: Passed: %d, Failed:%d, Skipped: %d", + short_result['passed'], + short_result['failures'], short_result['skipped']) return True - def clean(self): - """Clean created objects/functions.""" + def execute(self): + """Prepare testcase (Additional pre-configuration steps).""" + assert self.public_auth_url + self.__logger.info("Additional pre-configuration steps") + try: + os.makedirs(self.res_dir) + except OSError as ex: + if ex.errno != errno.EEXIST: + self.__logger.exception("Cannot create %s", self.res_dir) + raise Exception from ex + self.__logger.info("ENV:\n%s", env.string()) try: - if not self.orchestrator['requirements']['preserve_setup']: - self.__logger.info("Removing deployment files...") - testresult = os.path.join(self.case_dir, 'TestResults.json') - if os.path.exists(testresult): - os.remove(testresult) - self.__logger.info("Destroying Orchestrator...") - os.system('juju destroy-controller -y abot-controller ' - '--destroy-all-models') + assert self._install_juju() + assert self._install_juju_wait() + assert self._register_cloud() + assert self._register_credentials() + assert self.deploy_orchestrator() + assert self.deploy_vnf() + assert self.test_vnf() except Exception: # pylint: disable=broad-except - self.__logger.warn("Some issue during the undeployment ..") - self.__logger.warn("Tenant clean continue ..") + self.__logger.exception("juju_epc failed") + return 1 + return 0 - if not self.orchestrator['requirements']['preserve_setup']: - self.__logger.info('Remove the Abot_epc OS object ..') - super(JujuEpc, self).clean() - - return True - - -# ---------------------------------------------------------- -# -# YAML UTILS -# -# ----------------------------------------------------------- -def get_config(parameter, file_path): - """ - Returns the value of a given parameter in file.yaml - parameter must be given in string format with dots - Example: general.openstack.image_name - """ - with open(file_path) as config_file: - file_yaml = yaml.safe_load(config_file) - config_file.close() - value = file_yaml - for element in parameter.split("."): - value = value.get(element) - if value is None: - raise ValueError("The parameter %s is not defined in" - " reporting.yaml" % parameter) - return value + def clean(self): + """Clean created objects/functions.""" + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju debug-log --replay --no-tail') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + (_, stdout, stderr) = self.ssh.exec_command( + '/snap/bin/juju destroy-controller -y abot-controller ' + '--destroy-all-models') + self.__logger.debug("stdout:\n%s", stdout.read().decode("utf-8")) + self.__logger.debug("stderr:\n%s", stderr.read().decode("utf-8")) + for fip in self.cloud.list_floating_ips(): + self.cloud.delete_floating_ip(fip.id) + if self.image_alt: + self.cloud.delete_image(self.image_alt) + if self.flavor_alt: + self.orig_cloud.delete_flavor(self.flavor_alt.id) + super().clean() def sig_test_format(sig_test): @@ -462,7 +429,7 @@ def sig_test_format(sig_test): def process_abot_test_result(file_path): """ Process ABoT Result """ - with open(file_path) as test_result: + with open(file_path, encoding='utf-8') as test_result: data = json.load(test_result) res = [] for tests in data: @@ -472,7 +439,7 @@ def process_abot_test_result(file_path): for steps in flatten_steps: steps['result'] = steps['step_status'] res.append(steps) - except: + except Exception: # pylint: disable=broad-except logging.error("Could not post data to ElasticSearch host") raise return res @@ -514,23 +481,3 @@ def update_data(obj): raise return obj - - -def get_instances(nova_client): - """ To get all vm info of a project """ - try: - instances = nova_client.servers.list() - return instances - except Exception as exc: # pylint: disable=broad-except - logging.error("Error [get_instances(nova_client)]: %s", exc) - return None - - -def get_instance_metadata(nova_client, instance): - """ Get instance Metadata - Instance ID """ - try: - instance = nova_client.servers.get(instance.id) - return instance.metadata - except Exception as exc: # pylint: disable=broad-except - logging.error("Error [get_instance_status(nova_client)]: %s", exc) - return None