diff options
-rw-r--r-- | docker/smoke/testcases.yaml | 4 | ||||
-rw-r--r-- | functest/ci/config_functest.yaml | 4 | ||||
-rw-r--r-- | functest/ci/testcases.yaml | 4 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/rally/rally.py | 155 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/tempest/tempest.py | 9 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/vping/ping.sh | 10 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/vping/vping_base.py | 16 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/vping/vping_ssh.py | 92 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/vping/vping_userdata.py | 2 | ||||
-rw-r--r-- | functest/tests/unit/openstack/rally/test_rally.py | 240 | ||||
-rw-r--r-- | functest/tests/unit/utils/test_functest_utils.py | 66 | ||||
-rw-r--r-- | functest/utils/functest_utils.py | 19 | ||||
-rw-r--r-- | tox.ini | 1 |
13 files changed, 353 insertions, 269 deletions
diff --git a/docker/smoke/testcases.yaml b/docker/smoke/testcases.yaml index e2a6237c3..583cd7b72 100644 --- a/docker/smoke/testcases.yaml +++ b/docker/smoke/testcases.yaml @@ -11,7 +11,7 @@ tiers: case_name: vping_ssh project_name: functest criteria: 100 - blocking: true + blocking: false description: >- This test case verifies: 1) SSH to an instance using floating IPs over the public network. 2) Connectivity @@ -27,7 +27,7 @@ tiers: case_name: vping_userdata project_name: functest criteria: 100 - blocking: true + blocking: false description: >- This test case verifies: 1) Boot a VM with given userdata. 2) Connectivity between 2 instances over a private network. diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml index b05cca0b6..2cdec4500 100644 --- a/functest/ci/config_functest.yaml +++ b/functest/ci/config_functest.yaml @@ -93,9 +93,9 @@ vping: private_subnet_name: vping-subnet private_subnet_cidr: 192.168.130.0/24 router_name: vping-router - sg_name: vPing-sg + sg_name: vping-sg sg_desc: Security group for vPing test case - keypair_name: vPing-keypair + keypair_name: vping-keypair keypair_priv_file: /tmp/vPing-keypair keypair_pub_file: /tmp/vPing-keypair.pub vm_boot_timeout: 180 diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index f5c568d98..2b348d587 100644 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -73,7 +73,7 @@ tiers: case_name: vping_ssh project_name: functest criteria: 100 - blocking: true + blocking: false description: >- This test case verifies: 1) SSH to an instance using floating IPs over the public network. 2) Connectivity @@ -89,7 +89,7 @@ tiers: case_name: vping_userdata project_name: functest criteria: 100 - blocking: true + blocking: false description: >- This test case verifies: 1) Boot a VM with given userdata. 2) Connectivity between 2 instances over a private network. diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index 8048eddeb..8d1bfabb5 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -20,21 +20,16 @@ import subprocess import time import uuid +import os_client_config import pkg_resources import prettytable -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.openstack.create_flavor import OpenStackFlavor -from snaps.openstack.utils import deploy_utils from xtesting.core import testcase from xtesting.energy import energy import yaml -from functest.opnfv_tests.openstack.snaps import snaps_utils from functest.opnfv_tests.openstack.tempest import conf_utils from functest.utils import config +from functest.utils import functest_utils from functest.utils import env LOGGER = logging.getLogger(__name__) @@ -51,14 +46,13 @@ class RallyBase(testcase.TestCase): GLANCE_IMAGE_PATH = os.path.join(getattr( config.CONF, 'dir_functest_images'), GLANCE_IMAGE_FILENAME) GLANCE_IMAGE_FORMAT = getattr(config.CONF, 'openstack_image_disk_format') - GLANCE_IMAGE_USERNAME = getattr(config.CONF, 'openstack_image_username') GLANCE_IMAGE_EXTRA_PROPERTIES = getattr( config.CONF, 'image_properties', {}) FLAVOR_NAME = getattr(config.CONF, 'rally_flavor_name') FLAVOR_ALT_NAME = getattr(config.CONF, 'rally_flavor_alt_name') FLAVOR_RAM = 512 FLAVOR_RAM_ALT = 1024 - FLAVOR_EXTRA_SPECS = getattr(config.CONF, 'flavor_extra_specs', None) + FLAVOR_EXTRA_SPECS = getattr(config.CONF, 'flavor_extra_specs', {}) if FLAVOR_EXTRA_SPECS: FLAVOR_RAM = 1024 FLAVOR_RAM_ALT = 2048 @@ -87,15 +81,14 @@ class RallyBase(testcase.TestCase): def __init__(self, **kwargs): """Initialize RallyBase object.""" super(RallyBase, self).__init__(**kwargs) - self.os_creds = kwargs.get('os_creds') or snaps_utils.get_credentials() + self.cloud = os_client_config.make_shade() self.guid = '-' + str(uuid.uuid4()) self.creators = [] self.mode = '' self.summary = [] self.scenario_dir = '' self.image_name = None - self.ext_net_name = None - self.priv_net_id = None + self.ext_net = None self.flavor_name = None self.flavor_alt_name = None self.smoke = None @@ -104,6 +97,12 @@ class RallyBase(testcase.TestCase): self.result = None self.details = None self.compute_cnt = 0 + self.image = None + self.flavor = None + self.flavor_alt = None + self.network = None + self.subnet = None + self.router = None def _build_task_args(self, test_file_name): """Build arguments for the Rally task.""" @@ -122,15 +121,13 @@ class RallyBase(testcase.TestCase): task_args['concurrency'] = self.CONCURRENCY task_args['smoke'] = self.smoke - ext_net = self.ext_net_name - if ext_net: - task_args['floating_network'] = str(ext_net) + if self.ext_net: + task_args['floating_network'] = str(self.ext_net.name) else: task_args['floating_network'] = '' - net_id = self.priv_net_id - if net_id: - task_args['netid'] = str(net_id) + if self.network: + task_args['netid'] = str(self.network.id) else: task_args['netid'] = '' @@ -421,6 +418,7 @@ class RallyBase(testcase.TestCase): def _prepare_env(self): """Create resources needed by test scenarios.""" + assert self.cloud LOGGER.debug('Validating the test name...') if self.test_name not in self.TESTS: raise Exception("Test name '%s' is invalid" % self.test_name) @@ -431,73 +429,69 @@ class RallyBase(testcase.TestCase): self.image_name = self.GLANCE_IMAGE_NAME + self.guid self.flavor_name = self.FLAVOR_NAME + self.guid self.flavor_alt_name = self.FLAVOR_ALT_NAME + self.guid - self.ext_net_name = snaps_utils.get_ext_net_name(self.os_creds) - self.compute_cnt = snaps_utils.get_active_compute_cnt(self.os_creds) + self.compute_cnt = len(self.cloud.list_hypervisors()) + self.ext_net = functest_utils.get_external_network(self.cloud) + if self.ext_net is None: + raise Exception("No external network found") LOGGER.debug("Creating image '%s'...", self.image_name) - image_creator = deploy_utils.create_image( - self.os_creds, ImageConfig( - name=self.image_name, - image_file=self.GLANCE_IMAGE_PATH, - img_format=self.GLANCE_IMAGE_FORMAT, - image_user=self.GLANCE_IMAGE_USERNAME, - public=True, - extra_properties=self.GLANCE_IMAGE_EXTRA_PROPERTIES)) - if image_creator is None: + self.image = self.cloud.create_image( + self.image_name, + filename=self.GLANCE_IMAGE_PATH, + disk_format=self.GLANCE_IMAGE_FORMAT, + meta=self.GLANCE_IMAGE_EXTRA_PROPERTIES, + is_public=True) + if self.image is None: raise Exception("Failed to create image") - self.creators.append(image_creator) LOGGER.debug("Creating network '%s'...", network_name) - - rally_network_type = getattr(config.CONF, 'rally_network_type', None) - rally_physical_network = getattr( - config.CONF, 'rally_physical_network', None) - rally_segmentation_id = getattr( - config.CONF, 'rally_segmentation_id', None) - - network_creator = deploy_utils.create_network( - self.os_creds, NetworkConfig( - name=network_name, - shared=True, - network_type=rally_network_type, - physical_network=rally_physical_network, - segmentation_id=rally_segmentation_id, - subnet_settings=[SubnetConfig( - name=subnet_name, - cidr=self.RALLY_PRIVATE_SUBNET_CIDR, - dns_nameservers=[env.get('NAMESERVER')])])) - if network_creator is None: + provider = {} + if hasattr(config.CONF, 'rally_network_type'): + provider["network_type"] = getattr( + config.CONF, 'rally_network_type') + if hasattr(config.CONF, 'rally_physical_network'): + provider["physical_network"] = getattr( + config.CONF, 'rally_physical_network') + if hasattr(config.CONF, 'rally_segmentation_id'): + provider["segmentation_id"] = getattr( + config.CONF, 'rally_segmentation_id') + + self.network = self.cloud.create_network( + network_name, shared=True, provider=provider) + if self.network is None: raise Exception("Failed to create private network") - self.priv_net_id = network_creator.get_network().id - self.creators.append(network_creator) + + self.subnet = self.cloud.create_subnet( + self.network.id, + subnet_name=subnet_name, + cidr=self.RALLY_PRIVATE_SUBNET_CIDR, + enable_dhcp=True, + dns_nameservers=[env.get('NAMESERVER')]) + if self.subnet is None: + raise Exception("Failed to create private subnet") LOGGER.debug("Creating router '%s'...", router_name) - router_creator = deploy_utils.create_router( - self.os_creds, RouterConfig( - name=router_name, - external_gateway=self.ext_net_name, - internal_subnets=[subnet_name])) - if router_creator is None: + self.router = self.cloud.create_router( + router_name, ext_gateway_net_id=self.ext_net.id) + if self.router is None: raise Exception("Failed to create router") - self.creators.append(router_creator) + self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id) LOGGER.debug("Creating flavor '%s'...", self.flavor_name) - flavor_creator = OpenStackFlavor( - self.os_creds, FlavorConfig( - name=self.flavor_name, ram=self.FLAVOR_RAM, disk=1, vcpus=1, - metadata=self.FLAVOR_EXTRA_SPECS)) - if flavor_creator is None or flavor_creator.create() is None: + self.flavor = self.cloud.create_flavor( + self.flavor_name, self.FLAVOR_RAM, 1, 1) + if self.flavor is None: raise Exception("Failed to create flavor") - self.creators.append(flavor_creator) + self.cloud.set_flavor_specs( + self.flavor.id, self.FLAVOR_EXTRA_SPECS) LOGGER.debug("Creating flavor '%s'...", self.flavor_alt_name) - flavor_alt_creator = OpenStackFlavor( - self.os_creds, FlavorConfig( - name=self.flavor_alt_name, ram=self.FLAVOR_RAM_ALT, disk=1, - vcpus=1, metadata=self.FLAVOR_EXTRA_SPECS)) - if flavor_alt_creator is None or flavor_alt_creator.create() is None: + self.flavor_alt = self.cloud.create_flavor( + self.flavor_alt_name, self.FLAVOR_RAM_ALT, 1, 1) + if self.flavor_alt is None: raise Exception("Failed to create flavor") - self.creators.append(flavor_alt_creator) + self.cloud.set_flavor_specs( + self.flavor_alt.id, self.FLAVOR_EXTRA_SPECS) def _run_tests(self): """Execute tests.""" @@ -563,12 +557,21 @@ class RallyBase(testcase.TestCase): self.details = payload def _clean_up(self): - """Cleanup all OpenStack objects. Should be called on completion.""" - for creator in reversed(self.creators): - try: - creator.clean() - except Exception as exc: # pylint: disable=broad-except - LOGGER.error('Unexpected error cleaning - %s', exc) + """Cleanup of OpenStack resources. Should be called on completion.""" + if self.flavor_alt: + self.cloud.delete_flavor(self.flavor_alt.id) + if self.flavor: + self.cloud.delete_flavor(self.flavor.id) + if self.router and self.subnet: + self.cloud.remove_router_interface(self.router, self.subnet.id) + if self.router: + self.cloud.delete_router(self.router.id) + if self.subnet: + self.cloud.delete_subnet(self.subnet.id) + if self.network: + self.cloud.delete_network(self.network.id) + if self.image: + self.cloud.delete_image(self.image.id) @energy.enable_recording def run(self, **kwargs): diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 13391ca82..d02c114a6 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -217,13 +217,16 @@ class TempestCommon(testcase.TestCase): output = logfile.read() success_testcases = [] - for match in re.findall(r'.*\{0\} (.*?)[. ]*success ', output): + for match in re.findall(r'.*\{\d{1,2}\} (.*?) \.{3} success ', + output): success_testcases.append(match) failed_testcases = [] - for match in re.findall(r'.*\{0\} (.*?)[. ]*fail', output): + for match in re.findall(r'.*\{\d{1,2}\} (.*?) \.{3} fail', + output): failed_testcases.append(match) skipped_testcases = [] - for match in re.findall(r'.*\{0\} (.*?)[. ]*skip:', output): + for match in re.findall(r'.*\{\d{1,2}\} (.*?) \.{3} skip:', + output): skipped_testcases.append(match) self.details = {"tests_number": stat['num_tests'], diff --git a/functest/opnfv_tests/openstack/vping/ping.sh b/functest/opnfv_tests/openstack/vping/ping.sh deleted file mode 100644 index 15f5e84e1..000000000 --- a/functest/opnfv_tests/openstack/vping/ping.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - - -ping -c 1 $1 2>&1 >/dev/null -RES=$? -if [ "Z$RES" = "Z0" ] ; then - echo 'vPing OK' -else - echo 'vPing KO' -fi diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py index 13ee67ddb..2d1f856d7 100644 --- a/functest/opnfv_tests/openstack/vping/vping_base.py +++ b/functest/opnfv_tests/openstack/vping/vping_base.py @@ -20,6 +20,7 @@ from xtesting.core import testcase from functest.utils import config from functest.utils import env +from functest.utils import functest_utils class VPingBase(testcase.TestCase): @@ -35,7 +36,7 @@ class VPingBase(testcase.TestCase): super(VPingBase, self).__init__(**kwargs) self.logger = logging.getLogger(__name__) self.cloud = os_client_config.make_shade() - self.ext_net = self.cloud.get_network("ext-net") + self.ext_net = functest_utils.get_external_network(self.cloud) self.logger.debug("ext_net: %s", self.ext_net) self.guid = '-' + str(uuid.uuid4()) self.network = None @@ -44,6 +45,7 @@ class VPingBase(testcase.TestCase): self.image = None self.flavor = None self.vm1 = None + self.sec1 = None def run(self, **kwargs): # pylint: disable=too-many-locals """ @@ -117,6 +119,12 @@ class VPingBase(testcase.TestCase): self.cloud.set_flavor_specs( self.flavor.id, getattr(config.CONF, 'flavor_extra_specs', {})) + self.sec1 = self.cloud.create_security_group( + getattr(config.CONF, 'vping_sg_name') + self.guid, + getattr(config.CONF, 'vping_sg_desc')) + self.cloud.create_security_group_rule( + self.sec1.id, protocol='icmp', direction='ingress') + vm1_name = getattr(config.CONF, 'vping_vm_name_1') + self.guid self.logger.info( "Creating VM 1 instance with name: '%s'", vm1_name) @@ -125,9 +133,12 @@ class VPingBase(testcase.TestCase): flavor=self.flavor.id, auto_ip=False, wait=True, timeout=getattr(config.CONF, 'vping_vm_boot_timeout'), - network=self.network.id) + network=self.network.id, + security_groups=[self.sec1.id]) self.logger.debug("vm1: %s", self.vm1) self.vm1 = self.cloud.wait_for_server(self.vm1, auto_ip=False) + p_console = self.cloud.get_server_console(self.vm1.id) + self.logger.debug("vm1 console: \n%s", p_console) def _execute(self): """ @@ -150,6 +161,7 @@ class VPingBase(testcase.TestCase): """ assert self.cloud self.cloud.delete_server(self.vm1, wait=True) + self.cloud.delete_security_group(self.sec1.id) self.cloud.delete_image(self.image) self.cloud.remove_router_interface(self.router, self.subnet.id) self.cloud.delete_router(self.router.id) diff --git a/functest/opnfv_tests/openstack/vping/vping_ssh.py b/functest/opnfv_tests/openstack/vping/vping_ssh.py index 21a433884..8cc251d1d 100644 --- a/functest/opnfv_tests/openstack/vping/vping_ssh.py +++ b/functest/opnfv_tests/openstack/vping/vping_ssh.py @@ -15,8 +15,6 @@ import tempfile import time import paramiko -import pkg_resources -from scp import SCPClient from xtesting.core import testcase from xtesting.energy import energy @@ -39,7 +37,7 @@ class VPingSSH(vping_base.VPingBase): super(VPingSSH, self).__init__(**kwargs) self.logger = logging.getLogger(__name__) self.vm2 = None - self.sec = None + self.sec2 = None self.fip = None self.keypair = None self.ssh = paramiko.SSHClient() @@ -66,14 +64,14 @@ class VPingSSH(vping_base.VPingBase): with open(self.key_filename, 'w') as private_key_file: private_key_file.write(self.keypair.private_key) - self.sec = self.cloud.create_security_group( + self.sec2 = self.cloud.create_security_group( getattr(config.CONF, 'vping_sg_name') + self.guid, getattr(config.CONF, 'vping_sg_desc')) self.cloud.create_security_group_rule( - self.sec.id, port_range_min='22', port_range_max='22', + self.sec2.id, port_range_min='22', port_range_max='22', protocol='tcp', direction='ingress') self.cloud.create_security_group_rule( - self.sec.id, protocol='icmp', direction='ingress') + self.sec2.id, protocol='icmp', direction='ingress') vm2_name = "{}-{}-{}".format( getattr(config.CONF, 'vping_vm_name_2'), "ssh", self.guid) @@ -85,24 +83,20 @@ class VPingSSH(vping_base.VPingBase): auto_ip=False, wait=True, timeout=getattr(config.CONF, 'vping_vm_boot_timeout'), network=self.network.id, - security_groups=[self.sec.id]) + security_groups=[self.sec2.id]) self.logger.debug("vm2: %s", self.vm2) self.fip = self.cloud.create_floating_ip( network=self.ext_net.id, server=self.vm2) self.logger.debug("floating_ip2: %s", self.fip) self.vm2 = self.cloud.wait_for_server(self.vm2, auto_ip=False) - + p_console = self.cloud.get_server_console(self.vm2.id) + self.logger.debug("vm2 console: \n%s", p_console) return self._execute() except Exception: # pylint: disable=broad-except self.logger.exception('Unexpected error running vping_ssh') return testcase.TestCase.EX_RUN_ERROR def _do_vping(self): - """ - Execute ping command. - - Override from super - """ time.sleep(10) self.ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) self.ssh.connect( @@ -111,72 +105,10 @@ class VPingSSH(vping_base.VPingBase): key_filename=self.key_filename, timeout=getattr(config.CONF, 'vping_vm_ssh_connect_timeout')) self.logger.debug("ssh: %s", self.ssh) - if not self._transfer_ping_script(): - return testcase.TestCase.EX_RUN_ERROR - return self._do_vping_ssh() - - def _transfer_ping_script(self): - """ - Transfert vping script to VM. - - Uses SCP to copy the ping script via the SSH client - :param ssh: the SSH client - :return: - """ - self.logger.info("Trying to transfer ping.sh") - scp = SCPClient(self.ssh.get_transport()) - ping_script = pkg_resources.resource_filename( - 'functest.opnfv_tests.openstack.vping', 'ping.sh') - try: - scp.put(ping_script, "~/") - except Exception: # pylint: disable=broad-except - self.logger.error("Cannot SCP the file '%s'", ping_script) - return False - - cmd = 'chmod 755 ~/ping.sh' - (_, stdout, _) = self.ssh.exec_command(cmd) - for line in stdout.readlines(): - print line - - return True - - def _do_vping_ssh(self): - """ - Execute ping command via SSH. - - Pings the test_ip via the SSH client - :param ssh: the SSH client used to issue the ping command - :param test_ip: the IP for the ping command to use - :return: exit_code (int) - """ - exit_code = testcase.TestCase.EX_TESTCASE_FAILED - self.logger.info("Waiting for ping...") - - sec = 0 - cmd = '~/ping.sh ' + self.vm1.private_v4 - flag = False - - while True: - time.sleep(1) - (_, stdout, _) = self.ssh.exec_command(cmd) - output = stdout.readlines() - - for line in output: - if "vPing OK" in line: - self.logger.info("vPing detected!") - exit_code = testcase.TestCase.EX_OK - flag = True - break - elif sec == getattr(config.CONF, 'vping_ping_timeout'): - self.logger.info("Timeout reached.") - flag = True - break - if flag: - break - log = "Pinging %s. Waiting for response..." % self.vm1.private_v4 - self.logger.debug(log) - sec += 1 - return exit_code + (_, stdout, _) = self.ssh.exec_command( + 'ping -c 1 ' + self.vm1.private_v4) + self.logger.debug("ping output: %s", stdout) + return stdout.channel.recv_exit_status() def clean(self): assert self.cloud @@ -184,7 +116,7 @@ class VPingSSH(vping_base.VPingBase): self.cloud.delete_server( self.vm2, wait=True, timeout=getattr(config.CONF, 'vping_vm_delete_timeout')) - self.cloud.delete_security_group(self.sec.id) + self.cloud.delete_security_group(self.sec2.id) self.cloud.delete_keypair(self.keypair.id) self.cloud.delete_floating_ip(self.fip.id) super(VPingSSH, self).clean() diff --git a/functest/opnfv_tests/openstack/vping/vping_userdata.py b/functest/opnfv_tests/openstack/vping/vping_userdata.py index 9551c4b5d..056598d71 100644 --- a/functest/opnfv_tests/openstack/vping/vping_userdata.py +++ b/functest/opnfv_tests/openstack/vping/vping_userdata.py @@ -52,6 +52,8 @@ class VPingUserdata(vping_base.VPingBase): userdata=self._get_userdata()) self.logger.debug("vm2: %s", self.vm2) self.vm2 = self.cloud.wait_for_server(self.vm2, auto_ip=False) + p_console = self.cloud.get_server_console(self.vm1.id) + self.logger.debug("vm2 console: \n%s", p_console) return self._execute() except Exception: # pylint: disable=broad-except diff --git a/functest/tests/unit/openstack/rally/test_rally.py b/functest/tests/unit/openstack/rally/test_rally.py index 989ade090..970e5c4f4 100644 --- a/functest/tests/unit/openstack/rally/test_rally.py +++ b/functest/tests/unit/openstack/rally/test_rally.py @@ -13,7 +13,6 @@ import os import unittest import mock -from snaps.openstack.os_credentials import OSCreds from xtesting.core import testcase from functest.opnfv_tests.openstack.rally import rally @@ -22,14 +21,9 @@ from functest.opnfv_tests.openstack.rally import rally class OSRallyTesting(unittest.TestCase): # pylint: disable=too-many-public-methods def setUp(self): - os_creds = OSCreds( - username='user', password='pass', - auth_url='http://foo.com:5000/v3', project_name='bar') - with mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_credentials', - return_value=os_creds) as mock_get_creds: + with mock.patch('os_client_config.make_shade') as mock_make_shade: self.rally_base = rally.RallyBase() - self.assertTrue(mock_get_creds.called) + self.assertTrue(mock_make_shade.called) def test_build_task_args_missing_floating_network(self): os.environ['OS_AUTH_URL'] = '' @@ -270,94 +264,138 @@ class OSRallyTesting(unittest.TestCase): with self.assertRaises(Exception): self.rally_base._prepare_env() - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_active_compute_cnt') - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_ext_net_name', return_value='test_net_name') - @mock.patch('snaps.openstack.utils.deploy_utils.create_image', - return_value=None) - def test_prepare_env_image_missing( - self, mock_get_img, mock_get_net, mock_get_comp_cnt): + @mock.patch('functest.utils.functest_utils.get_external_network') + def test_prepare_env_image_missing(self, *args): + # pylint: disable=unused-argument self.rally_base.TESTS = ['test1', 'test2'] self.rally_base.test_name = 'test1' - with self.assertRaises(Exception): - self.rally_base._prepare_env() - mock_get_img.assert_called() - mock_get_net.assert_called() - mock_get_comp_cnt.assert_called() - - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_active_compute_cnt') - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_ext_net_name', return_value='test_net_name') - @mock.patch('snaps.openstack.utils.deploy_utils.create_image') - @mock.patch('snaps.openstack.utils.deploy_utils.create_network', - return_value=None) - def test_prepare_env_network_creation_failed( - self, mock_create_net, mock_get_img, mock_get_net, - mock_get_comp_cnt): + with mock.patch.object(self.rally_base.cloud, 'list_hypervisors'), \ + mock.patch.object(self.rally_base.cloud, 'create_image', + return_value=None): + with self.assertRaises(Exception): + self.rally_base._prepare_env() + + @mock.patch('functest.utils.functest_utils.get_external_network') + def test_prepare_env_network_creation_failed(self, *args): + # pylint: disable=unused-argument self.rally_base.TESTS = ['test1', 'test2'] self.rally_base.test_name = 'test1' - with self.assertRaises(Exception): - self.rally_base._prepare_env() - mock_create_net.assert_called() - mock_get_img.assert_called() - mock_get_net.assert_called() - mock_get_comp_cnt.assert_called() - - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_active_compute_cnt') - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_ext_net_name', return_value='test_net_name') - @mock.patch('snaps.openstack.utils.deploy_utils.create_image') - @mock.patch('snaps.openstack.utils.deploy_utils.create_network') - @mock.patch('snaps.openstack.utils.deploy_utils.create_router', - return_value=None) + with mock.patch.object(self.rally_base.cloud, + 'list_hypervisors') as mock_list_hyperv, \ + mock.patch.object(self.rally_base.cloud, + 'create_image') as mock_create_img, \ + mock.patch.object(self.rally_base.cloud, 'create_network', + return_value=None) as mock_create_net: + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_net.assert_called() + mock_create_img.assert_called() + mock_list_hyperv.assert_called() + + @mock.patch('functest.utils.functest_utils.get_external_network') + def test_prepare_env_subnet_creation_failed(self, *args): + # pylint: disable=unused-argument + self.rally_base.TESTS = ['test1', 'test2'] + self.rally_base.test_name = 'test1' + with mock.patch.object(self.rally_base.cloud, + 'list_hypervisors') as mock_list_hyperv, \ + mock.patch.object(self.rally_base.cloud, + 'create_image') as mock_create_img, \ + mock.patch.object(self.rally_base.cloud, + 'create_network') as mock_create_net, \ + mock.patch.object(self.rally_base.cloud, 'create_subnet', + return_value=None) as mock_create_subnet: + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_subnet.assert_called() + mock_create_net.assert_called() + mock_create_img.assert_called() + mock_list_hyperv.assert_called() + + @mock.patch('functest.utils.functest_utils.get_external_network') def test_prepare_env_router_creation_failed(self, *args): + # pylint: disable=unused-argument self.rally_base.TESTS = ['test1', 'test2'] self.rally_base.test_name = 'test1' - with self.assertRaises(Exception): - self.rally_base._prepare_env() - for func in args: - func.assert_called() - - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_active_compute_cnt') - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_ext_net_name', return_value='test_net_name') - @mock.patch('snaps.openstack.utils.deploy_utils.create_image') - @mock.patch('snaps.openstack.utils.deploy_utils.create_network') - @mock.patch('snaps.openstack.utils.deploy_utils.create_router') - @mock.patch('snaps.openstack.create_flavor.OpenStackFlavor.create', - return_value=None) - def test_prepare_env_flavor_creation_failed(self, mock_create_flavor, - *args): + with mock.patch.object(self.rally_base.cloud, + 'list_hypervisors') as mock_list_hyperv, \ + mock.patch.object(self.rally_base.cloud, + 'create_image') as mock_create_img, \ + mock.patch.object(self.rally_base.cloud, + 'create_network') as mock_create_net, \ + mock.patch.object(self.rally_base.cloud, + 'create_subnet') as mock_create_subnet, \ + mock.patch.object(self.rally_base.cloud, 'create_router', + return_value=None) as mock_create_router: + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_router.assert_called() + mock_create_subnet.assert_called() + mock_create_net.assert_called() + mock_create_img.assert_called() + mock_list_hyperv.assert_called() + + @mock.patch('functest.utils.functest_utils.get_external_network') + def test_prepare_env_flavor_creation_failed(self, *args): + # pylint: disable=unused-argument self.rally_base.TESTS = ['test1', 'test2'] self.rally_base.test_name = 'test1' - with self.assertRaises(Exception): - self.rally_base._prepare_env() - for func in args: - func.assert_called() - mock_create_flavor.assert_called_once() - - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_active_compute_cnt') - @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.' - 'get_ext_net_name', return_value='test_net_name') - @mock.patch('snaps.openstack.utils.deploy_utils.create_image') - @mock.patch('snaps.openstack.utils.deploy_utils.create_network') - @mock.patch('snaps.openstack.utils.deploy_utils.create_router') - @mock.patch('snaps.openstack.create_flavor.OpenStackFlavor.create', - side_effect=[mock.Mock, None]) - def test_prepare_env_flavor_alt_creation_failed(self, mock_create_flavor, - *args): + with mock.patch.object(self.rally_base.cloud, + 'list_hypervisors') as mock_list_hyperv, \ + mock.patch.object(self.rally_base.cloud, + 'create_image') as mock_create_img, \ + mock.patch.object(self.rally_base.cloud, + 'create_network') as mock_create_net, \ + mock.patch.object(self.rally_base.cloud, + 'create_subnet') as mock_create_subnet, \ + mock.patch.object(self.rally_base.cloud, + 'add_router_interface') as mock_add_router_if, \ + mock.patch.object(self.rally_base.cloud, + 'create_router') as mock_create_router, \ + mock.patch.object(self.rally_base.cloud, 'create_flavor', + return_value=None) as mock_create_flavor: + with self.assertRaises(Exception): + self.rally_base._prepare_env() + mock_create_flavor.assert_called_once() + mock_add_router_if.assert_called() + mock_create_router.assert_called() + mock_create_subnet.assert_called() + mock_create_net.assert_called() + mock_create_img.assert_called() + mock_list_hyperv.assert_called() + + @mock.patch('functest.utils.functest_utils.get_external_network') + def test_prepare_env_flavor_alt_creation_failed(self, *args): + # pylint: disable=unused-argument self.rally_base.TESTS = ['test1', 'test2'] self.rally_base.test_name = 'test1' - with self.assertRaises(Exception): - self.rally_base._prepare_env() - for func in args: - func.assert_called() - self.assertEqual(mock_create_flavor.call_count, 2) + with mock.patch.object(self.rally_base.cloud, + 'list_hypervisors') as mock_list_hyperv, \ + mock.patch.object(self.rally_base.cloud, + 'create_image') as mock_create_img, \ + mock.patch.object(self.rally_base.cloud, + 'create_network') as mock_create_net, \ + mock.patch.object(self.rally_base.cloud, + 'create_subnet') as mock_create_subnet, \ + mock.patch.object(self.rally_base.cloud, + 'add_router_interface') as mock_add_router_if, \ + mock.patch.object(self.rally_base.cloud, + 'create_router') as mock_create_router, \ + mock.patch.object(self.rally_base.cloud, + 'set_flavor_specs') as mock_set_flavor_specs, \ + mock.patch.object(self.rally_base.cloud, 'create_flavor', + side_effect=[mock.Mock(), None]) \ + as mock_create_flavor: + with self.assertRaises(Exception): + self.rally_base._prepare_env() + self.assertEqual(mock_create_flavor.call_count, 2) + mock_set_flavor_specs.assert_called_once() + mock_add_router_if.assert_called() + mock_create_router.assert_called() + mock_create_subnet.assert_called() + mock_create_net.assert_called() + mock_create_img.assert_called() + mock_list_hyperv.assert_called() @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.' '_run_task') @@ -377,12 +415,32 @@ class OSRallyTesting(unittest.TestCase): mock_run_task.assert_any_call('test1') def test_clean_up_default(self): - creator1 = mock.Mock() - creator2 = mock.Mock() - self.rally_base.creators = [creator1, creator2] - self.rally_base._clean_up() - self.assertTrue(creator1.clean.called) - self.assertTrue(creator2.clean.called) + with mock.patch.object(self.rally_base.cloud, + 'delete_flavor') as mock_delete_flavor, \ + mock.patch.object(self.rally_base.cloud, + 'remove_router_interface') \ + as mock_remove_router_if, \ + mock.patch.object(self.rally_base.cloud, + 'delete_router') as mock_delete_router, \ + mock.patch.object(self.rally_base.cloud, + 'delete_subnet') as mock_delete_subnet, \ + mock.patch.object(self.rally_base.cloud, + 'delete_network') as mock_delete_net, \ + mock.patch.object(self.rally_base.cloud, + 'delete_image') as mock_delete_img: + self.rally_base.flavor_alt = mock.Mock() + self.rally_base.flavor = mock.Mock() + self.rally_base.router = mock.Mock() + self.rally_base.subnet = mock.Mock() + self.rally_base.network = mock.Mock() + self.rally_base.image = mock.Mock() + self.rally_base._clean_up() + self.assertEqual(mock_delete_flavor.call_count, 2) + mock_remove_router_if.assert_called() + mock_delete_router.assert_called() + mock_delete_subnet.assert_called() + mock_delete_net.assert_called() + mock_delete_img.assert_called() @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.' 'create_rally_deployment') diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py index d35ed8ced..7debcc1df 100644 --- a/functest/tests/unit/utils/test_functest_utils.py +++ b/functest/tests/unit/utils/test_functest_utils.py @@ -11,9 +11,11 @@ import logging import time +import os import unittest import mock +import munch import pkg_resources from functest.utils import functest_utils @@ -218,6 +220,70 @@ class FunctestUtilsTesting(unittest.TestCase): self.test_file), 'test_image_name') + def test_get_extnetwork_nocloud(self): + with self.assertRaises(AssertionError): + functest_utils.get_external_network(None) + + def test_get_extnetwork_env_ok1(self): + cloud = mock.Mock() + cloud.get_network.return_value = munch.Munch(name="dummy") + os.environ["EXTERNAL_NETWORK"] = 'dummy' + self.assertEqual( + functest_utils.get_external_network(cloud), + cloud.get_network.return_value) + cloud.get_network.assert_called_once_with( + 'dummy', {'router:external': True}) + cloud.list_networks.assert_not_called() + + def test_get_extnetwork_env_ok2(self): + cloud = mock.Mock() + cloud.get_network.return_value = None + cloud.list_networks.return_value = None + os.environ["EXTERNAL_NETWORK"] = 'dummy' + self.assertEqual(functest_utils.get_external_network(cloud), None) + cloud.get_network.assert_called_once_with( + 'dummy', {'router:external': True}) + cloud.list_networks.assert_called_once_with( + {'router:external': True}) + + def test_get_extnetwork_env_ko(self): + cloud = mock.Mock() + cloud.get_network.return_value = None + cloud.list_networks.return_value = [munch.Munch(name="dummy")] + os.environ["EXTERNAL_NETWORK"] = 'dummy' + self.assertEqual( + functest_utils.get_external_network(cloud), + cloud.list_networks.return_value[0]) + cloud.get_network.assert_called_once_with( + 'dummy', {'router:external': True}) + cloud.list_networks.assert_called_once_with( + {'router:external': True}) + + def test_get_extnetwork_noenv_ko(self): + try: + del os.environ["EXTERNAL_NETWORK"] + except Exception: # pylint: disable=broad-except + pass + cloud = mock.Mock() + cloud.list_networks.return_value = None + self.assertEqual(functest_utils.get_external_network(cloud), None) + cloud.get_network.assert_not_called() + cloud.list_networks.assert_called_once_with( + {'router:external': True}) + + def test_get_extnetwork_noenv_ok(self): + try: + del os.environ["EXTERNAL_NETWORK"] + except Exception: # pylint: disable=broad-except + pass + cloud = mock.Mock() + cloud.list_networks.return_value = [munch.Munch(name="dummy")] + self.assertEqual( + functest_utils.get_external_network(cloud), + cloud.list_networks.return_value[0]) + cloud.get_network.assert_not_called() + cloud.list_networks.assert_called_once_with( + {'router:external': True}) if __name__ == "__main__": logging.disable(logging.CRITICAL) diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py index b614af321..b860828f1 100644 --- a/functest/utils/functest_utils.py +++ b/functest/utils/functest_utils.py @@ -15,6 +15,8 @@ import subprocess import sys import yaml +from functest.utils import env + LOGGER = logging.getLogger(__name__) @@ -72,3 +74,20 @@ def get_parameter_from_yaml(parameter, yfile): raise ValueError("The parameter %s is not defined in" " %s" % (parameter, yfile)) return value + + +def get_external_network(cloud): + """ + Returns the configured external network name or + the first retrieved external network name + """ + assert cloud + if env.get("EXTERNAL_NETWORK"): + network = cloud.get_network( + env.get("EXTERNAL_NETWORK"), {"router:external": True}) + if network: + return network + networks = cloud.list_networks({"router:external": True}) + if networks: + return networks[0] + return None @@ -107,7 +107,6 @@ commands = nosetests {[testenv:py35]dirs} basepython = python2.7 files = functest/opnfv_tests/openstack/rally/scenario/support/instance_dd_test.sh - functest/opnfv_tests/openstack/vping/ping.sh functest/ci/download_images.sh build.sh commands = bashate {[testenv:bashate]files} |