diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py index 5188191cc7..fc0a7307a5 100644 --- a/tempest/scenario/manager.py +++ b/tempest/scenario/manager.py @@ -47,7 +47,7 @@ LATEST_MICROVERSION = 'latest' class ScenarioTest(tempest.test.BaseTestCase): """Base class for scenario tests. Uses tempest own clients. """ - credentials = ['primary'] + credentials = ['primary', 'admin'] compute_min_microversion = None compute_max_microversion = LATEST_MICROVERSION @@ -115,8 +115,6 @@ class ScenarioTest(tempest.test.BaseTestCase): """This setup the service clients for the tests""" super(ScenarioTest, cls).setup_clients() cls.flavors_client = cls.os_primary.flavors_client - cls.compute_floating_ips_client = ( - cls.os_primary.compute_floating_ips_client) if CONF.service_available.glance: # Check if glance v1 is available to determine which client to use. if CONF.image_feature_enabled.api_v1: @@ -962,20 +960,98 @@ class ScenarioTest(tempest.test.BaseTestCase): LOG.exception(extra_msg) raise - def create_floating_ip(self, server, pool_name=None, **kwargs): - """Create a floating IP and associates to a server on Nova""" + def get_server_port_id_and_ip4(self, server, ip_addr=None, **kwargs): - if not pool_name: - pool_name = CONF.network.floating_network_name + if ip_addr and not kwargs.get('fixed_ips'): + kwargs['fixed_ips'] = 'ip_address=%s' % ip_addr + ports = self.os_admin.ports_client.list_ports( + device_id=server['id'], **kwargs)['ports'] + + # A port can have more than one IP address in some cases. + # If the network is dual-stack (IPv4 + IPv6), this port is associated + # with 2 subnets + + def _is_active(port): + # NOTE(vsaienko) With Ironic, instances live on separate hardware + # servers. Neutron does not bind ports for Ironic instances, as a + # result the port remains in the DOWN state. This has been fixed + # with the introduction of the networking-baremetal plugin but + # it's not mandatory (and is not used on all stable branches). + return (port['status'] == 'ACTIVE' or + port.get('binding:vnic_type') == 'baremetal') + + port_map = [(p["id"], fxip["ip_address"]) + for p in ports + for fxip in p["fixed_ips"] + if (netutils.is_valid_ipv4(fxip["ip_address"]) and + _is_active(p))] + inactive = [p for p in ports if p['status'] != 'ACTIVE'] + if inactive: + LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) + + self.assertNotEmpty(port_map, + "No IPv4 addresses found in: %s" % ports) + self.assertEqual(len(port_map), 1, + "Found multiple IPv4 addresses: %s. " + "Unable to determine which port to target." + % port_map) + return port_map[0] + + def create_floating_ip(self, server, external_network_id=None, + port_id=None, client=None, **kwargs): + """Create a floating IP and associates to a resource/port on Neutron""" + + if not external_network_id: + external_network_id = CONF.network.public_network_id + if not client: + client = self.floating_ips_client + if not port_id: + port_id, ip4 = self.get_server_port_id_and_ip4(server) + else: + ip4 = None + + floatingip_kwargs = { + 'floating_network_id': external_network_id, + 'port_id': port_id, + 'tenant_id': server.get('project_id') or server['tenant_id'], + 'fixed_ip_address': ip4, + } + if CONF.network.subnet_id: + floatingip_kwargs['subnet_id'] = CONF.network.subnet_id + + floatingip_kwargs.update(kwargs) + result = client.create_floatingip(**floatingip_kwargs) + floating_ip = result['floatingip'] - floating_ip = (self.compute_floating_ips_client. - create_floating_ip(pool=pool_name, - **kwargs)['floating_ip']) self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.compute_floating_ips_client.delete_floating_ip, + client.delete_floatingip, floating_ip['id']) - self.compute_floating_ips_client.associate_floating_ip_to_server( - floating_ip['ip'], server['id']) + return floating_ip + + def associate_floating_ip(self, floating_ip, server): + """Associate floating ip to server + + This wrapper utility attaches the floating_ip for + the respective port_id of server + """ + port_id, _ = self.get_server_port_id_and_ip4(server) + kwargs = dict(port_id=port_id) + floating_ip = self.floating_ips_client.update_floatingip( + floating_ip['id'], **kwargs)['floatingip'] + self.assertEqual(port_id, floating_ip['port_id']) + return floating_ip + + def disassociate_floating_ip(self, floating_ip): + """Disassociates floating ip + + This wrapper utility disassociates given floating ip. + :param floating_ip: a dict which is a return value of + floating_ips_client.create_floatingip method + """ + kwargs = dict(port_id=None) + floating_ip = self.floating_ips_client.update_floatingip( + floating_ip['id'], **kwargs)['floatingip'] + self.assertIsNone(floating_ip['port_id']) return floating_ip def create_timestamp(self, ip_address, dev_name=None, mount_path='/mnt', @@ -1046,7 +1122,8 @@ class ScenarioTest(tempest.test.BaseTestCase): # The tests calling this method don't have a floating IP # and can't make use of the validation resources. So the # method is creating the floating IP there. - return self.create_floating_ip(server, **kwargs)['ip'] + return self.create_floating_ip( + server, **kwargs)['floating_ip_address'] elif CONF.validation.connect_method == 'fixed': # Determine the network name to look for based on config or creds # provider network resources. @@ -1138,8 +1215,6 @@ class NetworkScenarioTest(ScenarioTest): """ - credentials = ['primary', 'admin'] - @classmethod def skip_checks(cls): super(NetworkScenarioTest, cls).skip_checks() @@ -1274,43 +1349,6 @@ class NetworkScenarioTest(ScenarioTest): return subnet - def get_server_port_id_and_ip4(self, server, ip_addr=None, **kwargs): - - if ip_addr and not kwargs.get('fixed_ips'): - kwargs['fixed_ips'] = 'ip_address=%s' % ip_addr - ports = self.os_admin.ports_client.list_ports( - device_id=server['id'], **kwargs)['ports'] - - # A port can have more than one IP address in some cases. - # If the network is dual-stack (IPv4 + IPv6), this port is associated - # with 2 subnets - - def _is_active(port): - # NOTE(vsaienko) With Ironic, instances live on separate hardware - # servers. Neutron does not bind ports for Ironic instances, as a - # result the port remains in the DOWN state. This has been fixed - # with the introduction of the networking-baremetal plugin but - # it's not mandatory (and is not used on all stable branches). - return (port['status'] == 'ACTIVE' or - port.get('binding:vnic_type') == 'baremetal') - - port_map = [(p["id"], fxip["ip_address"]) - for p in ports - for fxip in p["fixed_ips"] - if (netutils.is_valid_ipv4(fxip["ip_address"]) and - _is_active(p))] - inactive = [p for p in ports if p['status'] != 'ACTIVE'] - if inactive: - LOG.warning("Instance has ports that are not ACTIVE: %s", inactive) - - self.assertNotEmpty(port_map, - "No IPv4 addresses found in: %s" % ports) - self.assertEqual(len(port_map), 1, - "Found multiple IPv4 addresses: %s. " - "Unable to determine which port to target." - % port_map) - return port_map[0] - def get_network_by_name(self, network_name): net = self.os_admin.networks_client.list_networks( name=network_name)['networks'] @@ -1318,63 +1356,6 @@ class NetworkScenarioTest(ScenarioTest): "Unable to get network by name: %s" % network_name) return net[0] - def create_floating_ip(self, server, external_network_id=None, - port_id=None, client=None, **kwargs): - """Create a floating IP and associates to a resource/port on Neutron""" - - if not external_network_id: - external_network_id = CONF.network.public_network_id - if not client: - client = self.floating_ips_client - if not port_id: - port_id, ip4 = self.get_server_port_id_and_ip4(server) - else: - ip4 = None - - floatingip_kwargs = { - 'floating_network_id': external_network_id, - 'port_id': port_id, - 'tenant_id': server.get('project_id') or server['tenant_id'], - 'fixed_ip_address': ip4, - } - if CONF.network.subnet_id: - floatingip_kwargs['subnet_id'] = CONF.network.subnet_id - - floatingip_kwargs.update(kwargs) - result = client.create_floatingip(**floatingip_kwargs) - floating_ip = result['floatingip'] - - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - client.delete_floatingip, - floating_ip['id']) - return floating_ip - - def associate_floating_ip(self, floating_ip, server): - """Associate floating ip - - This wrapper utility attaches the floating_ip for - the respective port_id of server - """ - port_id, _ = self.get_server_port_id_and_ip4(server) - kwargs = dict(port_id=port_id) - floating_ip = self.floating_ips_client.update_floatingip( - floating_ip['id'], **kwargs)['floatingip'] - self.assertEqual(port_id, floating_ip['port_id']) - return floating_ip - - def disassociate_floating_ip(self, floating_ip): - """Disassociates floating ip - - This wrapper utility disassociates given floating ip. - :param floating_ip: a dict which is a return value of - floating_ips_client.create_floatingip method - """ - kwargs = dict(port_id=None) - floating_ip = self.floating_ips_client.update_floatingip( - floating_ip['id'], **kwargs)['floatingip'] - self.assertIsNone(floating_ip['port_id']) - return floating_ip - def check_floating_ip_status(self, floating_ip, status): """Verifies floatingip reaches the given status @@ -1575,8 +1556,6 @@ class NetworkScenarioTest(ScenarioTest): class EncryptionScenarioTest(ScenarioTest): """Base class for encryption scenario tests""" - credentials = ['primary', 'admin'] - @classmethod def setup_clients(cls): super(EncryptionScenarioTest, cls).setup_clients() @@ -1618,6 +1597,8 @@ class ObjectStorageScenarioTest(ScenarioTest): class. """ + credentials = ['primary'] + @classmethod def skip_checks(cls): super(ObjectStorageScenarioTest, cls).skip_checks() diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py index 5201315672..2c981c8777 100644 --- a/tempest/scenario/test_minimum_basic.py +++ b/tempest/scenario/test_minimum_basic.py @@ -100,7 +100,7 @@ class TestMinimumBasicScenario(manager.ScenarioTest): for addresses in server['addresses'].values(): for address in addresses: if (address['OS-EXT-IPS:type'] == 'floating' and - address['addr'] == floating_ip['ip']): + address['addr'] == floating_ip['floating_ip_address']): return address @decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8') @@ -129,7 +129,9 @@ class TestMinimumBasicScenario(manager.ScenarioTest): server = self.servers_client.show_server(server['id'])['server'] if (CONF.network_feature_enabled.floating_ips and CONF.network.floating_network_name): - floating_ip = self.create_floating_ip(server) + fip = self.create_floating_ip(server) + floating_ip = self.associate_floating_ip( + fip, server) # fetch the server again to make sure the addresses were refreshed # after associating the floating IP server = self.servers_client.show_server(server['id'])['server'] @@ -138,8 +140,8 @@ class TestMinimumBasicScenario(manager.ScenarioTest): self.assertIsNotNone( address, "Failed to find floating IP '%s' in server addresses: %s" % - (floating_ip['ip'], server['addresses'])) - ssh_ip = floating_ip['ip'] + (floating_ip['floating_ip_address'], server['addresses'])) + ssh_ip = floating_ip['floating_ip_address'] else: ssh_ip = self.get_server_ip(server) @@ -162,8 +164,7 @@ class TestMinimumBasicScenario(manager.ScenarioTest): if floating_ip: # delete the floating IP, this should refresh the server addresses - self.compute_floating_ips_client.delete_floating_ip( - floating_ip['id']) + self.disassociate_floating_ip(floating_ip) def is_floating_ip_detached_from_server(): server_info = self.servers_client.show_server( @@ -177,5 +178,6 @@ class TestMinimumBasicScenario(manager.ScenarioTest): CONF.compute.build_timeout, CONF.compute.build_interval): msg = ("Floating IP '%s' should not be in server addresses: %s" - % (floating_ip['ip'], server['addresses'])) + % (floating_ip['floating_ip_address'], + server['addresses'])) raise exceptions.TimeoutException(msg) diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py index 4c82d84c88..2a15470ad0 100644 --- a/tempest/scenario/test_server_basic_ops.py +++ b/tempest/scenario/test_server_basic_ops.py @@ -52,7 +52,9 @@ class TestServerBasicOps(manager.ScenarioTest): # Obtain a floating IP if floating_ips is enabled if (CONF.network_feature_enabled.floating_ips and CONF.network.floating_network_name): - self.ip = self.create_floating_ip(self.instance)['ip'] + fip = self.create_floating_ip(self.instance) + self.ip = self.associate_floating_ip( + fip, self.instance)['floating_ip_address'] else: server = self.servers_client.show_server( self.instance['id'])['server'] diff --git a/tempest/scenario/test_volume_backup_restore.py b/tempest/scenario/test_volume_backup_restore.py index 71e6b537ba..d0885cfa18 100644 --- a/tempest/scenario/test_volume_backup_restore.py +++ b/tempest/scenario/test_volume_backup_restore.py @@ -84,11 +84,11 @@ class TestVolumeBackupRestore(manager.ScenarioTest): security_groups=[ {'name': security_group['name']}]) - # Create a floating ip - floating_ip = self.create_floating_ip(server) - + # Create a floating ip and associate it to server. + fip = self.create_floating_ip(server) + floating_ip = self.associate_floating_ip(fip, server) # Check server connectivity - self.check_vm_connectivity(floating_ip['ip'], + self.check_vm_connectivity(floating_ip['floating_ip_address'], username=CONF.validation.image_ssh_user, private_key=keypair['private_key'], should_connect=True)