diff options
Diffstat (limited to 'functest/opnfv_tests/openstack')
20 files changed, 545 insertions, 191 deletions
diff --git a/functest/opnfv_tests/openstack/api/connection_check.py b/functest/opnfv_tests/openstack/api/connection_check.py index 7a320b5e4..f3b35e9d9 100644 --- a/functest/opnfv_tests/openstack/api/connection_check.py +++ b/functest/opnfv_tests/openstack/api/connection_check.py @@ -17,6 +17,7 @@ import shade from xtesting.core import testcase from functest.utils import env +from functest.utils import functest_utils class ConnectionCheck(testcase.TestCase): @@ -28,12 +29,14 @@ class ConnectionCheck(testcase.TestCase): "list_endpoints", "list_floating_ip_pools", "list_floating_ips", "list_hypervisors", "list_keypairs", "list_networks", "list_ports", "list_role_assignments", "list_roles", "list_routers", "list_servers", - "list_services", "list_subnets"] + "list_subnets"] def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = 'connection_check' super(ConnectionCheck, self).__init__(**kwargs) + self.output_log_name = 'functest.log' + self.output_debug_log_name = 'functest.debug.log' try: cloud_config = os_client_config.get_config() self.cloud = shade.OpenStackCloud(cloud_config=cloud_config) @@ -47,11 +50,12 @@ class ConnectionCheck(testcase.TestCase): try: assert self.cloud self.start_time = time.time() - if env.get('PUBLIC_ENDPOINT_ONLY').lower() == 'true': - self.__logger.warning( - "Listing services is skipped " - "because the admin endpoints are unreachable") - self.func_list.remove("list_services") + self.__logger.debug( + "list_services: %s", functest_utils.list_services(self.cloud)) + if env.get('NO_TENANT_NETWORK').lower() == 'true': + self.func_list.remove("list_floating_ip_pools") + self.func_list.remove("list_floating_ips") + self.func_list.remove("list_routers") for func in self.func_list: self.__logger.debug( "%s: %s", func, getattr(self.cloud, func)()) @@ -59,6 +63,7 @@ class ConnectionCheck(testcase.TestCase): self.__logger.debug( "list_service_providers: %s", self.cloud._get_and_munchify('service_providers', data)) + functest_utils.get_openstack_version(self.cloud) self.result = 100 status = testcase.TestCase.EX_OK except Exception: # pylint: disable=broad-except diff --git a/functest/opnfv_tests/openstack/cinder/cinder_test.py b/functest/opnfv_tests/openstack/cinder/cinder_test.py index bbed9a64f..d81bb100a 100644 --- a/functest/opnfv_tests/openstack/cinder/cinder_test.py +++ b/functest/opnfv_tests/openstack/cinder/cinder_test.py @@ -77,8 +77,10 @@ class CinderCheck(singlevm.SingleVm2): self.logger.debug("ssh: %s", self.ssh) (_, stdout, stderr) = self.ssh.exec_command( "sh ~/write_data.sh {}".format(env.get('VOLUME_DEVICE_NAME'))) - self.logger.debug("volume_write stdout: %s", stdout.read()) - self.logger.debug("volume_write stderr: %s", stderr.read()) + self.logger.debug( + "volume_write stdout: %s", stdout.read().decode("utf-8")) + self.logger.debug( + "volume_write stderr: %s", stderr.read().decode("utf-8")) # Detach volume from VM 1 self.logger.info("Detach volume from VM 1") self.cloud.detach_volume( @@ -103,8 +105,10 @@ class CinderCheck(singlevm.SingleVm2): self.logger.debug("ssh: %s", self.ssh2) (_, stdout, stderr) = self.ssh2.exec_command( "sh ~/read_data.sh {}".format(env.get('VOLUME_DEVICE_NAME'))) - self.logger.debug("read volume stdout: %s", stdout.read()) - self.logger.debug("read volume stderr: %s", stderr.read()) + self.logger.debug( + "read volume stdout: %s", stdout.read().decode("utf-8")) + self.logger.debug( + "read volume stderr: %s", stderr.read().decode("utf-8")) self.logger.info("Detach volume from VM 2") self.cloud.detach_volume( self.vm2, self.volume, timeout=self.volume_timeout) diff --git a/functest/opnfv_tests/openstack/rally/blacklist.yaml b/functest/opnfv_tests/openstack/rally/blacklist.yaml index 382e239f8..18727f73c 100644 --- a/functest/opnfv_tests/openstack/rally/blacklist.yaml +++ b/functest/opnfv_tests/openstack/rally/blacklist.yaml @@ -1,13 +1,5 @@ --- scenario: - - - scenarios: - - '^os-' # all scenarios - tests: - # Following test occasionally fails due to race condition issue on - # quota manipulation in nova. - # Ref: https://bugs.launchpad.net/nova/+bug/1552622 - - 'Quotas.nova_update_and_delete' functionality: - @@ -34,7 +26,14 @@ functionality: tests: - HeatStacks.create_and_delete_stack - NovaServers.boot_and_associate_floating_ip + - NovaServers.boot_server_and_list_interfaces - NovaServers.boot_server_associate_and_dissociate_floating_ip - NeutronNetworks.create_and_delete_floating_ips - NeutronNetworks.create_and_list_floating_ips - NeutronNetworks.associate_and_dissociate_floating_ips + - NeutronNetworks.create_and_delete_routers + - NeutronNetworks.create_and_list_routers + - NeutronNetworks.create_and_show_routers + - NeutronNetworks.create_and_update_routers + - NeutronNetworks.set_and_clear_router_gateway + - Quotas.neutron_update diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index b450580c7..592809b76 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -22,10 +22,10 @@ import shutil import subprocess import time -from threading import Timer import pkg_resources import prettytable from ruamel.yaml import YAML +import six from six.moves import configparser from xtesting.core import testcase import yaml @@ -33,6 +33,7 @@ import yaml from functest.core import singlevm from functest.utils import config from functest.utils import env +from functest.utils import functest_utils LOGGER = logging.getLogger(__name__) @@ -42,7 +43,7 @@ class RallyBase(singlevm.VmReady2): # pylint: disable=too-many-instance-attributes, too-many-public-methods stests = ['authenticate', 'glance', 'cinder', 'gnocchi', 'heat', - 'keystone', 'neutron', 'nova', 'quotas'] + 'keystone', 'neutron', 'nova', 'quotas', 'swift'] rally_conf_path = "/etc/rally/rally.conf" rally_aar4_patch_path = pkg_resources.resource_filename( @@ -67,7 +68,6 @@ class RallyBase(singlevm.VmReady2): visibility = 'public' shared_network = True - allow_no_fip = True task_timeout = 3600 def __init__(self, **kwargs): @@ -94,14 +94,12 @@ class RallyBase(singlevm.VmReady2): self.smoke = None self.start_time = None self.result = None - self.details = None self.compute_cnt = 0 self.flavor_alt = None self.tests = [] self.run_cmd = '' self.network_extensions = [] self.services = [] - self.task_aborted = False def _build_task_args(self, test_file_name): """Build arguments for the Rally task.""" @@ -131,7 +129,14 @@ class RallyBase(singlevm.VmReady2): if self.network: task_args['netid'] = str(self.network.id) else: - task_args['netid'] = '' + LOGGER.warning( + 'No tenant network created. ' + 'Trying EXTERNAL_NETWORK as a fallback') + if env.get("EXTERNAL_NETWORK"): + network = self.cloud.get_network(env.get("EXTERNAL_NETWORK")) + task_args['netid'] = str(network.id) if network else '' + else: + task_args['netid'] = '' return task_args @@ -234,20 +239,17 @@ class RallyBase(singlevm.VmReady2): rconfig.write(config_file) @staticmethod - def get_task_id(cmd_raw): + def get_task_id(tag): """ Get task id from command rally result. - :param cmd_raw: + :param tag: :return: task_id as string """ - taskid_re = re.compile('^Task +(.*): started$') - for line in cmd_raw.splitlines(True): - line = line.strip() - match = taskid_re.match(line.decode("utf-8")) - if match: - return match.group(1) - return None + cmd = ["rally", "task", "list", "--tag", tag, "--uuids-only"] + output = subprocess.check_output(cmd).decode("utf-8").rstrip() + LOGGER.info("%s: %s", " ".join(cmd), output) + return output @staticmethod def task_succeed(json_raw): @@ -425,30 +427,22 @@ class RallyBase(singlevm.VmReady2): else: LOGGER.info('Test scenario: "%s" Failed.', test_name) - def kill_task(self, proc): - """ Kill a task.""" - proc.kill() - self.task_aborted = True - def run_task(self, test_name): """Run a task.""" LOGGER.info('Starting test scenario "%s" ...', test_name) LOGGER.debug('running command: %s', self.run_cmd) - proc = subprocess.Popen(self.run_cmd, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - self.task_aborted = False - timer = Timer(self.task_timeout, self.kill_task, [proc]) - timer.start() - output = proc.communicate()[0] - if self.task_aborted: - LOGGER.error("Failed to complete task") - raise Exception("Failed to complete task") - timer.cancel() - task_id = self.get_task_id(output) + if six.PY3: + # pylint: disable=no-member + subprocess.call( + self.run_cmd, timeout=self.task_timeout, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + else: + with open(os.devnull, 'wb') as devnull: + subprocess.call(self.run_cmd, stdout=devnull, stderr=devnull) + task_id = self.get_task_id(test_name) LOGGER.debug('task_id : %s', task_id) - if task_id is None: + if not task_id: LOGGER.error("Failed to retrieve task_id") - LOGGER.error("Result:\n%s", output.decode("utf-8")) raise Exception("Failed to retrieve task id") self._save_results(test_name, task_id) @@ -524,11 +518,11 @@ class RallyBase(singlevm.VmReady2): shutil.copytree(task_macro, macro_dir) self.update_keystone_default_role() - self.compute_cnt = len(self.cloud.list_hypervisors()) + self.compute_cnt = self.count_hypervisors() self.network_extensions = self.cloud.get_network_extensions() self.flavor_alt = self.create_flavor_alt() self.services = [service.name for service in - self.cloud.list_services()] + functest_utils.list_services(self.cloud)] LOGGER.debug("flavor: %s", self.flavor_alt) @@ -538,7 +532,8 @@ class RallyBase(singlevm.VmReady2): if self.file_is_empty(file_name): LOGGER.info('No tests for scenario "%s"', test_name) return False - self.run_cmd = (["rally", "task", "start", "--abort-on-sla-failure", + self.run_cmd = (["rally", "task", "start", "--tag", test_name, + "--abort-on-sla-failure", "--task", self.task_file, "--task-args", str(self._build_task_args(test_name))]) return True @@ -605,10 +600,10 @@ class RallyBase(singlevm.VmReady2): LOGGER.info("Rally '%s' success_rate is %s%% in %s/%s modules", self.case_name, success_rate, nb_modules, len(self.summary)) - payload.append({'summary': {'duration': total_duration, - 'nb tests': total_nb_tests, - 'nb success': success_rate}}) - self.details = payload + self.details['summary'] = {'duration': total_duration, + 'nb tests': total_nb_tests, + 'nb success': success_rate} + self.details["modules"] = payload @staticmethod def export_task(file_name, export_type="html"): @@ -810,26 +805,10 @@ class RallyJobs(RallyBase): with open(result_file_name, 'w') as fname: template.dump(cases, fname) - @staticmethod - def _remove_plugins_extra(): - inst_dir = getattr(config.CONF, 'dir_rally_inst') - try: - shutil.rmtree(os.path.join(inst_dir, 'plugins')) - shutil.rmtree(os.path.join(inst_dir, 'extra')) - except Exception: # pylint: disable=broad-except - pass - def prepare_task(self, test_name): """Prepare resources for test run.""" - self._remove_plugins_extra() jobs_dir = os.path.join( getattr(config.CONF, 'dir_rally_data'), test_name, 'rally-jobs') - inst_dir = getattr(config.CONF, 'dir_rally_inst') - shutil.copytree(os.path.join(jobs_dir, 'plugins'), - os.path.join(inst_dir, 'plugins')) - shutil.copytree(os.path.join(jobs_dir, 'extra'), - os.path.join(inst_dir, 'extra')) - task_name = self.task_yaml.get(test_name).get("task") task = os.path.join(jobs_dir, task_name) if not os.path.exists(task): @@ -840,9 +819,6 @@ class RallyJobs(RallyBase): os.makedirs(self.temp_dir) task_file_name = os.path.join(self.temp_dir, task_name) self.apply_blacklist(task, task_file_name) - self.run_cmd = (["rally", "task", "start", "--task", task_file_name]) + self.run_cmd = (["rally", "task", "start", "--tag", test_name, + "--task", task_file_name]) return True - - def clean(self): - self._remove_plugins_extra() - super(RallyJobs, self).clean() diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml index dfc1fc156..993b83ff7 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-glance.yaml @@ -36,8 +36,9 @@ flavor: name: {{ flavor_name }} number_instances: 2 - nics: - - net-id: {{ netid }} + boot_server_kwargs: + nics: + - net-id: {{ netid }} context: {{ user_context(tenants_amount, users_amount, use_existing_users) }} quotas: diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml index b8b1b9b6b..b2248d499 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-neutron.yaml @@ -150,8 +150,6 @@ subnets_per_network: 1 context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - router: {} quotas: neutron: network: -1 diff --git a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml index 8ef5b6cdc..187f2cfd2 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/full/opnfv-nova.yaml @@ -39,9 +39,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -59,9 +56,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -80,9 +74,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -104,9 +95,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -124,9 +112,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -216,7 +201,7 @@ - args: {{ vm_params(image_name, flavor_name) }} - size: 10 + size: 1 block_migration: {{ block_migration }} boot_server_kwargs: nics: @@ -251,14 +236,11 @@ - args: {{ vm_params(image_name, flavor_name) }} - server_kwargs: + boot_server_kwargs: nics: - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova(keypairs=true) }} @@ -277,9 +259,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_volumes() }} {{ unlimited_neutron() }} @@ -301,9 +280,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml index 3f0cf0840..dcb007c50 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-quotas.yaml @@ -35,17 +35,6 @@ sla: {{ no_failures_sla() }} - Quotas.nova_update_and_delete: - - - args: - max_quota: 1024 - context: - {{ user_context(tenants_amount, users_amount, use_existing_users) }} - runner: - {{ constant_runner(concurrency=concurrency, times=iterations, is_smoke=smoke) }} - sla: - {{ no_failures_sla() }} - Quotas.nova_update: - args: diff --git a/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml b/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml new file mode 100644 index 000000000..66d7cd24d --- /dev/null +++ b/functest/opnfv_tests/openstack/rally/scenario/opnfv-swift.yaml @@ -0,0 +1,71 @@ + SwiftObjects.create_container_and_object_then_list_objects: + - + args: + objects_per_container: 2 + object_size: 5120 + runner: + {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }} + context: + {{ user_context(tenants_amount, users_amount, use_existing_users) }} + roles: + - "admin" + sla: + {{ no_failures_sla() }} + + SwiftObjects.list_objects_in_containers: + - + runner: + {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }} + context: + {{ user_context(tenants_amount, users_amount, use_existing_users) }} + roles: + - "admin" + swift_objects: + containers_per_tenant: 1 + objects_per_container: 10 + object_size: 1024 + sla: + {{ no_failures_sla() }} + + SwiftObjects.create_container_and_object_then_download_object: + - + args: + objects_per_container: 5 + object_size: 1024 + runner: + {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }} + context: + {{ user_context(tenants_amount, users_amount, use_existing_users) }} + roles: + - "admin" + sla: + {{ no_failures_sla() }} + + SwiftObjects.create_container_and_object_then_delete_all: + - + args: + objects_per_container: 5 + object_size: 102400 + runner: + {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }} + context: + {{ user_context(tenants_amount, users_amount, use_existing_users) }} + roles: + - "admin" + sla: + {{ no_failures_sla() }} + + SwiftObjects.list_and_download_objects_in_containers: + - + runner: + {{ constant_runner(concurrency=1, times=iterations, is_smoke=smoke) }} + context: + {{ user_context(tenants_amount, users_amount, use_existing_users) }} + roles: + - "admin" + swift_objects: + containers_per_tenant: 1 + objects_per_container: 5 + object_size: 10240 + sla: + {{ no_failures_sla() }} diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml index 1b61762f9..279e81439 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-glance.yaml @@ -36,8 +36,9 @@ flavor: name: {{ flavor_name }} number_instances: 2 - nics: - - net-id: {{ netid }} + boot_server_kwargs: + nics: + - net-id: {{ netid }} context: {{ user_context(tenants_amount, users_amount, use_existing_users) }} quotas: diff --git a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml index 935f3841a..cba5c921f 100644 --- a/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml +++ b/functest/opnfv_tests/openstack/rally/scenario/sanity/opnfv-nova.yaml @@ -15,7 +15,7 @@ - args: {{ vm_params(image_name, flavor_name) }} - size: 10 + size: 1 block_migration: {{ block_migration }} boot_server_kwargs: nics: @@ -50,14 +50,11 @@ - args: {{ vm_params(image_name, flavor_name) }} - server_kwargs: + boot_server_kwargs: nics: - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova(keypairs=true) }} @@ -76,9 +73,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_volumes() }} {{ unlimited_neutron() }} @@ -100,9 +94,6 @@ - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} - network: - networks_per_tenant: 1 - start_cidr: "100.1.0.0/25" quotas: {{ unlimited_neutron() }} {{ unlimited_nova() }} @@ -128,7 +119,8 @@ - args: {{ vm_params(image_name, flavor_name) }} - auto_assign_nic: true + nics: + - net-id: {{ netid }} context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} network: {} diff --git a/functest/opnfv_tests/openstack/rally/task.yaml b/functest/opnfv_tests/openstack/rally/task.yaml index 181fdb42e..3e692891a 100644 --- a/functest/opnfv_tests/openstack/rally/task.yaml +++ b/functest/opnfv_tests/openstack/rally/task.yaml @@ -42,3 +42,7 @@ {% if "heat" in service_list %} {%- include "var/opnfv-heat.yaml"-%} {% endif %} + +{% if "swift" in service_list %} +{%- include "var/opnfv-swift.yaml"-%} +{% endif %} diff --git a/functest/opnfv_tests/openstack/shaker/shaker.py b/functest/opnfv_tests/openstack/shaker/shaker.py index fd31ea689..917c65980 100644 --- a/functest/opnfv_tests/openstack/shaker/shaker.py +++ b/functest/opnfv_tests/openstack/shaker/shaker.py @@ -19,6 +19,7 @@ and list of tests to execute. import logging import os +import json import scp from functest.core import singlevm @@ -31,23 +32,26 @@ class Shaker(singlevm.SingleVm2): __logger = logging.getLogger(__name__) - filename = '/home/opnfv/functest/images/shaker-image.qcow2' + filename = '/home/opnfv/functest/images/shaker-image-1.3.0+stretch.qcow2' flavor_ram = 512 flavor_vcpus = 1 flavor_disk = 3 - username = 'ubuntu' + username = 'debian' port = 9000 ssh_connect_loops = 12 create_server_timeout = 300 + check_console_loop = 12 shaker_timeout = '3600' quota_instances = -1 + quota_cores = -1 + check_console_loop = 12 def __init__(self, **kwargs): super(Shaker, self).__init__(**kwargs) self.role = None def check_requirements(self): - if len(self.orig_cloud.list_hypervisors()) < 2: + if self.count_hypervisors() < 2: self.__logger.warning("Shaker requires at least 2 hypervisors") self.is_skipped = True self.project.clean() @@ -85,7 +89,8 @@ class Shaker(singlevm.SingleVm2): domain=self.project.domain.id) self.orig_cloud.set_compute_quotas( self.project.project.name, - instances=self.quota_instances) + instances=self.quota_instances, + cores=self.quota_cores) scpc = scp.SCPClient(self.ssh.get_transport()) scpc.put('/home/opnfv/functest/conf/env_file', remote_path='~/') if os.environ.get('OS_CACERT'): @@ -100,10 +105,10 @@ class Shaker(singlevm.SingleVm2): 'unset OS_TENANT_NAME && ' 'unset OS_TENANT_ID && ' 'unset OS_ENDPOINT_TYPE && ' - 'export OS_PASSWORD={} && ' + 'export OS_PASSWORD="{}" && ' '{}' 'env && ' - 'timeout {} shaker --image-name {} --flavor-name {} ' + 'timeout {} shaker --debug --image-name {} --flavor-name {} ' '--server-endpoint {}:9000 --external-net {} --dns-nameservers {} ' '--scenario openstack/full_l2,' 'openstack/full_l3_east_west,' @@ -127,6 +132,13 @@ class Shaker(singlevm.SingleVm2): except scp.SCPException: self.__logger.exception("cannot get report files") return 1 + with open(os.path.join(self.res_dir, 'report.json')) as json_file: + data = json.load(json_file) + for value in data["records"].values(): + if value["status"] != "ok": + self.__logger.error( + "%s failed\n%s", value["scenario"], value["stderr"]) + return 1 return stdout.channel.recv_exit_status() def clean(self): diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml index 8d7d6eca9..e559f619a 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml @@ -4,10 +4,9 @@ - os-ovn-nofeature-ha - os-ovn-nofeature-noha tests: - - neutron_tempest_plugin.api.admin.test_agent_management - neutron_tempest_plugin.api.admin.test_dhcp_agent_scheduler + - neutron_tempest_plugin.api.test_trunk.TrunkTestInheritJSONBase.test_add_subport - patrole_tempest_plugin.tests.api.network.test_agents_rbac - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_network_type - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_segmentation_id - - tempest.api.network.admin.test_agent_management - tempest.api.network.admin.test_dhcp_agent_scheduler diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml new file mode 100644 index 000000000..e53b577b2 --- /dev/null +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml @@ -0,0 +1,15 @@ +--- +- + scenarios: + - os-* + tests: + - neutron_tempest_plugin.api.admin.test_floating_ips_admin_actions.FloatingIPAdminTestJSON.test_associate_floating_ip_with_port_from_another_project + - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_detail_quotas + - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_quotas + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_floatingip_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_network_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_port_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_router_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_rule_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_subnet_when_quotas_is_full diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml index ab0bfa98e..758547359 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml @@ -2,25 +2,93 @@ compute: max_microversion: 2.65 compute-feature-enabled: - shelve: false - vnc_console: false - cold_migration: false - block_migration_for_live_migration: true + attach_encrypted_volume: false + block_migration_for_live_migration: false + block_migrate_cinder_iscsi: false + change_password: false + cold_migration: true + config_drive: true + console_output: true + disk_config: true + enable_instance_password: true + interface_attach: true + live_migration: true + live_migrate_back_and_forth: false + metadata_service: true + pause: true + personality: false + rdp_console: false + rescue: true + resize: true + scheduler_available_filters: "RetryFilter,AvailabilityZoneFilter,\ + ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,\ + ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,\ + DifferentHostFilter" + serial_console: false + shelve: true + snapshot: true + spice_console: false + suspend: true + swap_volume: false + vnc_console: true + volume_backed_live_migration: false + volume_multiattach: false identity: + auth_version: v3 user_unique_last_password_count: 2 user_lockout_duration: 10 user_lockout_failure_attempts: 2 identity-feature-enabled: + trust: true api_v2: false api_v2_admin: false security_compliance: true + federation: false + external_idp: false + project_tags: true + application_credentials: true image-feature-enabled: api_v2: true api_v1: false +network-feature-enabled: + port_admin_state_change: true + port_security: true placement: - max_microversion: 1.30 + max_microversion: "1.30" +validation: + image_ssh_user: cirros + ssh_timeout: 196 + ip_version_for_ssh: 4 + run_validation: true volume: max_microversion: 3.55 - storage_protocol: iSCSI + storage_protocol: ceph + manage_volume_ref: source-name,volume-%s + manage_snapshot_ref: source-name,snapshot-%s volume-feature-enabled: + multi_backend: false backup: true + snapshot: true + clone: true + manage_snapshot: true + manage_volume: true + extend_attached_volume: false + consistency_group: false + volume_revert: true +neutron_plugin_options: + agent_availability_zone: nova + available_type_drivers: flat,geneve,vlan,gre,local,vxlan + provider_vlans: foo, +object-storage-feature-enabled: + discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\ + tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo" + object_versioning: true + discoverability: true +heat_plugin: + skip_functional_test_list: EncryptionVolTypeTest + skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\ + VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\ + LoadBalancerTest" + auth_version: 3 +heat_features_enabled: + multi_cloud: false diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml new file mode 100644 index 000000000..37aa2810b --- /dev/null +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml @@ -0,0 +1,94 @@ +--- +compute: + max_microversion: 2.65 +compute-feature-enabled: + attach_encrypted_volume: false + block_migration_for_live_migration: false + block_migrate_cinder_iscsi: false + change_password: false + cold_migration: true + config_drive: true + console_output: true + disk_config: true + enable_instance_password: true + interface_attach: true + live_migration: true + live_migrate_back_and_forth: false + metadata_service: true + pause: true + personality: false + rdp_console: false + rescue: true + resize: true + scheduler_available_filters: "RetryFilter,AvailabilityZoneFilter,\ + ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,\ + ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,\ + DifferentHostFilter" + serial_console: false + shelve: true + snapshot: true + spice_console: false + suspend: true + swap_volume: false + vnc_console: true + volume_backed_live_migration: false + volume_multiattach: false +identity: + auth_version: v3 + user_unique_last_password_count: 2 + user_lockout_duration: 10 + user_lockout_failure_attempts: 2 +identity-feature-enabled: + trust: true + api_v2: false + api_v2_admin: false + security_compliance: true + federation: false + external_idp: false + project_tags: true + application_credentials: true +image-feature-enabled: + api_v2: true + api_v1: false +network-feature-enabled: + port_admin_state_change: true + port_security: true +placement: + max_microversion: "1.30" +validation: + image_ssh_user: cirros + ssh_timeout: 196 + ip_version_for_ssh: 4 + run_validation: true +volume: + max_microversion: 3.55 + storage_protocol: ceph + manage_volume_ref: source-name,volume-%s + manage_snapshot_ref: source-name,snapshot-%s +volume-feature-enabled: + multi_backend: false + backup: true + snapshot: true + clone: true + manage_snapshot: true + manage_volume: true + extend_attached_volume: false + consistency_group: false + volume_revert: true +neutron_plugin_options: + agent_availability_zone: nova + available_type_drivers: flat,geneve,vlan,local + provider_vlans: public, +object-storage-feature-enabled: + discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\ + tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo" + object_versioning: true + discoverability: true +heat_plugin: + skip_functional_test_list: EncryptionVolTypeTest + skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\ + VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\ + LoadBalancerTest" + auth_version: 3 +heat_features_enabled: + multi_cloud: false diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index faf2ab5ca..48c673673 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -21,6 +21,7 @@ import subprocess import time import pkg_resources +import six from six.moves import configparser from xtesting.core import testcase import yaml @@ -50,6 +51,9 @@ class TempestCommon(singlevm.VmReady2): tempest_blacklist = pkg_resources.resource_filename( 'functest', 'opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml') + tempest_public_blacklist = pkg_resources.resource_filename( + 'functest', + 'opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml') def __init__(self, **kwargs): if "case_name" not in kwargs: @@ -95,6 +99,7 @@ class TempestCommon(singlevm.VmReady2): except Exception: # pylint: disable=broad-except pass self.deny_skipping = kwargs.get("deny_skipping", False) + self.tests_count = kwargs.get("tests_count", 0) def check_services(self): """Check the mandatory services.""" @@ -195,9 +200,16 @@ class TempestCommon(singlevm.VmReady2): cmd = ("rally verify list-verifiers | awk '/" + getattr(config.CONF, 'tempest_verifier_name') + "/ {print $2}'") - proc = subprocess.Popen(cmd, shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + if six.PY3: + # pylint: disable=no-member + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + else: + with open(os.devnull, 'wb') as devnull: + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, + stderr=devnull) verifier_uuid = proc.stdout.readline().rstrip() return verifier_uuid.decode("utf-8") @@ -266,27 +278,8 @@ class TempestCommon(singlevm.VmReady2): # enable multinode tests rconfig.set('compute', 'min_compute_nodes', compute_cnt) rconfig.set('compute-feature-enabled', 'live_migration', True) - filters = ['RetryFilter', 'AvailabilityZoneFilter', 'ComputeFilter', - 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', - 'ServerGroupAntiAffinityFilter', - 'ServerGroupAffinityFilter'] - rconfig.set( - 'compute-feature-enabled', 'scheduler_available_filters', - functest_utils.convert_list_to_ini(filters)) if os.environ.get('OS_REGION_NAME'): rconfig.set('identity', 'region', os.environ.get('OS_REGION_NAME')) - if env.get("NEW_USER_ROLE").lower() != "member": - rconfig.set( - 'auth', 'tempest_roles', - functest_utils.convert_list_to_ini([env.get("NEW_USER_ROLE")])) - if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()): - rconfig.set('auth', 'use_dynamic_credentials', False) - account_file = os.path.join( - getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml') - assert os.path.exists( - account_file), "{} doesn't exist".format(account_file) - rconfig.set('auth', 'test_accounts_file', account_file) - rconfig.set('identity', 'auth_version', 'v3') rconfig.set('identity', 'admin_role', admin_role_name) rconfig.set('identity', 'default_domain_id', domain_id) if not rconfig.has_section('network'): @@ -350,7 +343,7 @@ class TempestCommon(singlevm.VmReady2): LOGGER.info("%s\n%s", cmd, output.decode("utf-8")) os.remove('/etc/tempest.conf') - def apply_tempest_blacklist(self): + def apply_tempest_blacklist(self, black_list): """Exclude blacklisted test cases.""" LOGGER.debug("Applying tempest blacklist...") if os.path.exists(self.raw_list): @@ -363,7 +356,7 @@ class TempestCommon(singlevm.VmReady2): deploy_scenario = env.get('DEPLOY_SCENARIO') if bool(deploy_scenario): # if DEPLOY_SCENARIO is set we read the file - black_list_file = open(self.tempest_blacklist) + black_list_file = open(black_list) black_list_yaml = yaml.safe_load(black_list_file) black_list_file.close() for item in black_list_yaml: @@ -500,14 +493,47 @@ class TempestCommon(singlevm.VmReady2): with open(rally_conf, 'w') as config_file: rconfig.write(config_file) + def update_auth_section(self): + """Update auth section in tempest.conf""" + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section("auth"): + rconfig.add_section("auth") + if env.get("NEW_USER_ROLE").lower() != "member": + tempest_roles = [] + if rconfig.has_option("auth", "tempest_roles"): + tempest_roles = functest_utils.convert_ini_to_list( + rconfig.get("auth", "tempest_roles")) + rconfig.set( + 'auth', 'tempest_roles', + functest_utils.convert_list_to_ini( + [env.get("NEW_USER_ROLE")] + tempest_roles)) + if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()): + rconfig.set('auth', 'use_dynamic_credentials', False) + account_file = os.path.join( + getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml') + assert os.path.exists( + account_file), "{} doesn't exist".format(account_file) + rconfig.set('auth', 'test_accounts_file', account_file) + if env.get('NO_TENANT_NETWORK').lower() == 'true': + rconfig.set('auth', 'create_isolated_networks', False) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + def update_network_section(self): """Update network section in tempest.conf""" rconfig = configparser.RawConfigParser() rconfig.read(self.conf_file) - if not rconfig.has_section('network'): - rconfig.add_section('network') - rconfig.set('network', 'public_network_id', self.ext_net.id) - rconfig.set('network', 'floating_network_name', self.ext_net.name) + if self.ext_net: + if not rconfig.has_section('network'): + rconfig.add_section('network') + rconfig.set('network', 'public_network_id', self.ext_net.id) + rconfig.set('network', 'floating_network_name', self.ext_net.name) + rconfig.set('network-feature-enabled', 'floating_ips', True) + else: + if not rconfig.has_section('network-feature-enabled'): + rconfig.add_section('network-feature-enabled') + rconfig.set('network-feature-enabled', 'floating_ips', False) with open(self.conf_file, 'w') as config_file: rconfig.write(config_file) @@ -517,7 +543,24 @@ class TempestCommon(singlevm.VmReady2): rconfig.read(self.conf_file) if not rconfig.has_section('compute'): rconfig.add_section('compute') - rconfig.set('compute', 'fixed_network_name', self.network.name) + rconfig.set( + 'compute', 'fixed_network_name', + self.network.name if self.network else env.get("EXTERNAL_NETWORK")) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + + def update_validation_section(self): + """Update validation section in tempest.conf""" + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('validation'): + rconfig.add_section('validation') + rconfig.set( + 'validation', 'connect_method', + 'floating' if self.ext_net else 'fixed') + rconfig.set( + 'validation', 'network_for_ssh', + self.network.name if self.network else env.get("EXTERNAL_NETWORK")) with open(self.conf_file, 'w') as config_file: rconfig.write(config_file) @@ -567,8 +610,8 @@ class TempestCommon(singlevm.VmReady2): self.deployment_dir = self.get_verifier_deployment_dir( self.verifier_id, self.deployment_id) - compute_cnt = len(self.orig_cloud.list_hypervisors()) - + compute_cnt = self.count_hypervisors() if self.count_hypervisors( + ) <= 10 else 10 self.image_alt = self.publish_image_alt() self.flavor_alt = self.create_flavor_alt() LOGGER.debug("flavor: %s", self.flavor_alt) @@ -585,8 +628,10 @@ class TempestCommon(singlevm.VmReady2): flavor_alt_id=self.flavor_alt.id, admin_role_name=self.role_name, cidr=self.cidr, domain_id=self.project.domain.id) + self.update_auth_section() self.update_network_section() self.update_compute_section() + self.update_validation_section() self.update_scenario_section() self.backup_tempest_config(self.conf_file, self.res_dir) @@ -603,7 +648,10 @@ class TempestCommon(singlevm.VmReady2): shutil.copy("/etc/rally/rally.conf", self.res_dir) self.configure(**kwargs) self.generate_test_list(**kwargs) - self.apply_tempest_blacklist() + self.apply_tempest_blacklist(TempestCommon.tempest_blacklist) + if env.get('PUBLIC_ENDPOINT_ONLY').lower() == 'true': + self.apply_tempest_blacklist( + TempestCommon.tempest_public_blacklist) self.run_verifier_tests(**kwargs) self.parse_verifier_result() rally.RallyBase.verify_report( @@ -637,16 +685,105 @@ class TempestCommon(singlevm.VmReady2): skips = self.details.get("skipped_number", 0) if skips > 0 and self.deny_skipping: return testcase.TestCase.EX_TESTCASE_FAILED + if self.tests_count and ( + self.details.get("tests_number", 0) != self.tests_count): + return testcase.TestCase.EX_TESTCASE_FAILED return super(TempestCommon, self).is_successful() -class TempestScenario(TempestCommon): - """Tempest scenario testcase implementation class.""" +class TempestHorizon(TempestCommon): + """Tempest Horizon testcase implementation class.""" - quota_instances = -1 + def configure(self, **kwargs): + super(TempestHorizon, self).configure(**kwargs) + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('dashboard'): + rconfig.add_section('dashboard') + rconfig.set('dashboard', 'dashboard_url', env.get('DASHBOARD_URL')) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + self.backup_tempest_config(self.conf_file, self.res_dir) - def run(self, **kwargs): - self.orig_cloud.set_compute_quotas( - self.project.project.name, - instances=self.quota_instances) - return super(TempestScenario, self).run(**kwargs) + +class TempestHeat(TempestCommon): + """Tempest Heat testcase implementation class.""" + + filename_alt = ('/home/opnfv/functest/images/' + 'Fedora-Cloud-Base-30-1.2.x86_64.qcow2') + flavor_alt_ram = 512 + flavor_alt_vcpus = 1 + flavor_alt_disk = 4 + + def __init__(self, **kwargs): + super(TempestHeat, self).__init__(**kwargs) + self.user2 = self.orig_cloud.create_user( + name='{}-user2_{}'.format(self.case_name, self.project.guid), + password=self.project.password, + domain_id=self.project.domain.id) + self.orig_cloud.grant_role( + self.role_name, user=self.user2.id, + project=self.project.project.id, domain=self.project.domain.id) + if not self.orig_cloud.get_role("heat_stack_owner"): + self.role = self.orig_cloud.create_role("heat_stack_owner") + self.orig_cloud.grant_role( + "heat_stack_owner", user=self.user2.id, + project=self.project.project.id, + domain=self.project.domain.id) + + def configure(self, **kwargs): + assert self.user2 + super(TempestHeat, self).configure(**kwargs) + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('heat_plugin'): + rconfig.add_section('heat_plugin') + # It fails if region and domain ids are unset + rconfig.set( + 'heat_plugin', 'region', + os.environ.get('OS_REGION_NAME', 'RegionOne')) + rconfig.set('heat_plugin', 'auth_url', os.environ["OS_AUTH_URL"]) + rconfig.set('heat_plugin', 'project_domain_id', self.project.domain.id) + rconfig.set('heat_plugin', 'user_domain_id', self.project.domain.id) + rconfig.set( + 'heat_plugin', 'project_domain_name', self.project.domain.name) + rconfig.set( + 'heat_plugin', 'user_domain_name', self.project.domain.name) + rconfig.set('heat_plugin', 'username', self.user2.name) + rconfig.set('heat_plugin', 'password', self.project.password) + rconfig.set('heat_plugin', 'project_name', self.project.project.name) + rconfig.set('heat_plugin', 'admin_username', self.project.user.name) + rconfig.set('heat_plugin', 'admin_password', self.project.password) + rconfig.set( + 'heat_plugin', 'admin_project_name', self.project.project.name) + rconfig.set('heat_plugin', 'image_ref', self.image_alt.id) + rconfig.set('heat_plugin', 'instance_type', self.flavor_alt.id) + rconfig.set('heat_plugin', 'minimal_image_ref', self.image.id) + rconfig.set('heat_plugin', 'minimal_instance_type', self.flavor.id) + if self.ext_net: + rconfig.set( + 'heat_plugin', 'floating_network_name', self.ext_net.name) + if self.network: + rconfig.set('heat_plugin', 'fixed_network_name', self.network.name) + rconfig.set('heat_plugin', 'fixed_subnet_name', self.subnet.name) + rconfig.set('heat_plugin', 'network_for_ssh', self.network.name) + else: + LOGGER.warning( + 'No tenant network created. ' + 'Trying EXTERNAL_NETWORK as a fallback') + rconfig.set( + 'heat_plugin', 'fixed_network_name', + env.get("EXTERNAL_NETWORK")) + rconfig.set( + 'heat_plugin', 'network_for_ssh', env.get("EXTERNAL_NETWORK")) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + self.backup_tempest_config(self.conf_file, self.res_dir) + + def clean(self): + """ + Cleanup all OpenStack objects. Should be called on completion. + """ + super(TempestHeat, self).clean() + if self.user2: + self.orig_cloud.delete_user(self.user2.id) diff --git a/functest/opnfv_tests/openstack/vmtp/vmtp.py b/functest/opnfv_tests/openstack/vmtp/vmtp.py index 2fd4e089c..cfbd134c7 100644 --- a/functest/opnfv_tests/openstack/vmtp/vmtp.py +++ b/functest/opnfv_tests/openstack/vmtp/vmtp.py @@ -33,6 +33,7 @@ from xtesting.core import testcase from functest.core import singlevm from functest.utils import env +from functest.utils import functest_utils class Vmtp(singlevm.VmReady2): @@ -50,6 +51,7 @@ class Vmtp(singlevm.VmReady2): flavor_vcpus = 1 flavor_disk = 0 create_server_timeout = 300 + ssh_retry_timeout = 240 def __init__(self, **kwargs): if "case_name" not in kwargs: @@ -60,7 +62,7 @@ class Vmtp(singlevm.VmReady2): (_, self.pubkey_filename) = tempfile.mkstemp() def check_requirements(self): - if len(self.orig_cloud.list_hypervisors()) < 2: + if self.count_hypervisors() < 2: self.__logger.warning("Vmtp requires at least 2 hypervisors") self.is_skipped = True self.project.clean() @@ -122,6 +124,7 @@ class Vmtp(singlevm.VmReady2): self.guid) vmtp_conf["dns_nameservers"] = [env.get('NAMESERVER')] vmtp_conf["generic_retry_count"] = self.create_server_timeout // 2 + vmtp_conf["ssh_retry_count"] = self.ssh_retry_timeout // 2 conf.write(yaml.dump(vmtp_conf)) def run_vmtp(self): @@ -135,6 +138,8 @@ class Vmtp(singlevm.VmReady2): OS_USERNAME=self.project.user.name, OS_PROJECT_NAME=self.project.project.name, OS_PROJECT_ID=self.project.project.id, + OS_PROJECT_DOMAIN_NAME=self.project.domain.name, + OS_USER_DOMAIN_NAME=self.project.domain.name, OS_PASSWORD=self.project.password) if not new_env["OS_AUTH_URL"].endswith(('v3', 'v3/')): new_env["OS_AUTH_URL"] = "{}/v3".format(new_env["OS_AUTH_URL"]) @@ -145,6 +150,12 @@ class Vmtp(singlevm.VmReady2): pass cmd = ['vmtp', '-d', '--json', '{}/vmtp.json'.format(self.res_dir), '-c', self.config] + if env.get("VMTP_HYPERVISORS"): + hypervisors = functest_utils.convert_ini_to_list( + env.get("VMTP_HYPERVISORS")) + for hypervisor in hypervisors: + cmd.extend(["--hypervisor", hypervisor]) + self.__logger.debug("cmd: %s", cmd) output = subprocess.check_output( cmd, stderr=subprocess.STDOUT, env=new_env).decode("utf-8") self.__logger.info("%s\n%s", " ".join(cmd), output) diff --git a/functest/opnfv_tests/openstack/vping/vping_ssh.py b/functest/opnfv_tests/openstack/vping/vping_ssh.py index 6420013a0..a7bbfc23c 100644 --- a/functest/opnfv_tests/openstack/vping/vping_ssh.py +++ b/functest/opnfv_tests/openstack/vping/vping_ssh.py @@ -44,12 +44,14 @@ class VPingSSH(singlevm.SingleVm2): Returns: ping exit codes """ assert self.ssh + if not self.check_regex_in_console(self.vm2.name): + return 1 (_, stdout, stderr) = self.ssh.exec_command( 'ping -c 1 {}'.format( self.vm2.private_v4 or self.vm2.addresses[ self.network.name][0].addr)) - self.__logger.info("output:\n%s", stdout.read()) - self.__logger.info("error:\n%s", stderr.read()) + self.__logger.info("output:\n%s", stdout.read().decode("utf-8")) + self.__logger.info("error:\n%s", stderr.read().decode("utf-8")) return stdout.channel.recv_exit_status() def clean(self): |