def delete_trunk(cls, trunk, client=None): """Delete network trunk :param trunk: dictionary containing trunk ID (trunk['id']) :param client: client to be used for connecting to networking service """ client = client or trunk.get('client') or cls.client trunk.update(client.show_trunk(trunk['id'])['trunk']) if not trunk['admin_state_up']: # Cannot touch trunk before admin_state_up is True client.update_trunk(trunk['id'], admin_state_up=True) if trunk['sub_ports']: # Removes trunk ports before deleting it cls._try_delete_resource(client.remove_subports, trunk['id'], trunk['sub_ports']) # we have to detach the interface from the server before # the trunk can be deleted. parent_port = {'id': trunk['port_id']} def is_parent_port_detached(): parent_port.update(client.show_port(parent_port['id'])['port']) return not parent_port['device_id'] if not is_parent_port_detached(): # this could probably happen when trunk is deleted and parent port # has been assigned to a VM that is still running. Here we are # assuming that device_id points to such VM. cls.os_primary.compute.InterfacesClient().delete_interface( parent_port['device_id'], parent_port['id']) utils.wait_until_true(is_parent_port_detached) client.delete_trunk(trunk['id'])
def test_qos(self): """This is a basic test that check that a QoS policy with a bandwidth limit rule is applied correctly by sending a file from the instance to the test node. Then calculating the bandwidth every ~1 sec by the number of bits received / elapsed time. """ self._test_basic_resources() policy_id = self._create_qos_policy() ssh_client = self._create_ssh_client() self.os_admin.network_client.create_bandwidth_limit_rule( policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND) port = self.client.list_ports(network_id=self.network['id'], device_id=self.server[ 'server']['id'])['ports'][0] self.os_admin.network_client.update_port(port['id'], qos_policy_id=policy_id) self._create_file_for_bw_tests(ssh_client) utils.wait_until_true(lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=120, sleep=1)
def _wait_until_port_ready(self, router_id, device_owner): common_utils.wait_until_true( functools.partial( self._is_port_active, router_id, device_owner), timeout=300, sleep=5)
def test_router_interface_status(self): network = self.create_network() subnet = self.create_subnet(network) # Add router interface with subnet id router = self._create_router(data_utils.rand_name('router'), True) intf = self.create_router_interface(router['id'], subnet['id']) def _status_active(): return self.client.show_port( intf['port_id'])['port']['status'] == 'ACTIVE' utils.wait_until_true(_status_active, exception=AssertionError)
def test_floating_ip_update(self): """Test updating FIP with another port. The test creates two servers and attaches floating ip to first server. Then it checks server is accesible using the FIP. FIP is then associated with the second server and connectivity is checked again. """ ports = [ self.create_port(self.network, security_groups=[self.secgroup['id']]) for i in range(2) ] servers = [] for port in ports: name = data_utils.rand_name("server-%s" % port['id'][:8]) server = self.create_server(name=name, flavor_ref=CONF.compute.flavor_ref, key_name=self.keypair['name'], image_ref=CONF.compute.image_ref, networks=[{ 'port': port['id'] }])['server'] server['name'] = name servers.append(server) for server in servers: self.wait_for_server_active(server) self.fip = self.create_floatingip(port=ports[0]) self.check_connectivity(self.fip['floating_ip_address'], CONF.validation.image_ssh_user, self.keypair['private_key'], servers=servers) self.client.update_floatingip(self.fip['id'], port_id=ports[1]['id']) def _wait_for_fip_associated(): try: self.check_servers_hostnames(servers[-1:], log_errors=False) except (AssertionError, exceptions.SSHTimeout): return False return True # The FIP is now associated with the port of the second server. try: common_utils.wait_until_true(_wait_for_fip_associated, timeout=15, sleep=3) except common_utils.WaitTimeout: self._log_console_output(servers[-1:]) self.fail("Server %s is not accessible via its floating ip %s" % (servers[-1]['id'], self.fip['id']))
def ensure_nc_listen(self, ssh_client, port, protocol, echo_msg=None, servers=None): """Ensure that nc server listening on the given TCP/UDP port is up. Listener is created always on remote host. """ def spawn_and_check_process(): self.nc_listen(ssh_client, port, protocol, echo_msg, servers) return utils.process_is_running(ssh_client, "nc") utils.wait_until_true(spawn_and_check_process)
def test_nova_qos(self): """Test QOS when using NOVA flavor """ self._test_basic_resources() ssh_client = self._create_ssh_client() if hasattr(self, 'FILE_SIZE'): # Queens & Rocky: create file self._create_file_for_bw_tests(ssh_client) limit_bytes_sec = self.LIMIT_KBPS * 1024 * self.TOLERANCE_FACTOR # Check bw limited common_utils.wait_until_true( lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=limit_bytes_sec), timeout=200, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=limit_bytes_sec), timeout=200, sleep=1) # Migrate original_host = self.os_primary.servers_client.show_server( self.server['server']['id'])['server']['hostId'] # Set Nova API to latest for better api support base_compute_client.COMPUTE_MICROVERSION = 'latest' self.os_admin.servers_client.live_migrate_server( self.server['server']['id'], block_migration='auto', host=None) base_compute_client.COMPUTE_MICROVERSION = None self.wait_for_server_active(self.server['server']) new_host = self.os_primary.servers_client.show_server( self.server['server']['id'])['server']['hostId'] self.assertNotEqual(original_host, new_host, "Migration did not happen") # Check bw limited common_utils.wait_until_true( lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=limit_bytes_sec), timeout=200, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=limit_bytes_sec), timeout=200, sleep=1)
def _test_ipv6_address_configured(self, ssh_client, vm, ipv6_port): ipv6_address = ipv6_port['fixed_ips'][0]['ip_address'] ip_command = ip.IPCommand(ssh_client) def guest_has_address(expected_address): ip_addresses = [a.address for a in ip_command.list_addresses()] for ip_address in ip_addresses: if expected_address in ip_address: return True return False # Set NIC with IPv6 to be UP and wait until IPv6 address # will be configured on this NIC turn_nic6_on(ssh_client, ipv6_port, False) # And check if IPv6 address will be properly configured # on this NIC try: utils.wait_until_true( lambda: guest_has_address(ipv6_address), timeout=60) except utils.WaitTimeout: LOG.debug('Timeout without NM configuration') except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e: LOG.debug(ssh_e) self._log_console_output([vm]) self._log_local_network_status() raise if not guest_has_address(ipv6_address): try: # Set NIC with IPv6 to be UP and wait until IPv6 address # will be configured on this NIC turn_nic6_on(ssh_client, ipv6_port) # And check if IPv6 address will be properly configured # on this NIC utils.wait_until_true( lambda: guest_has_address(ipv6_address), timeout=90, exception=RuntimeError( "Timed out waiting for IP address {!r} to be " "configured in the VM {!r}.".format(ipv6_address, vm['id']))) except (lib_exc.SSHTimeout, ssh_exc.AuthenticationException) as ssh_e: LOG.debug(ssh_e) self._log_console_output([vm]) self._log_local_network_status() raise
def _delete_floating_ip(self, fip_address): ip_address = fip_address['floating_ip_address'] def _fip_is_free(): fips = self.os_admin.network_client.list_floatingips() for fip in fips['floatingips']: if ip_address == fip['floating_ip_address']: return False return True self.delete_floatingip(fip_address) try: common_utils.wait_until_true(_fip_is_free, timeout=30, sleep=5) except common_utils.WaitTimeout: self.fail("Can't reuse IP address %s because it is not free" % ip_address)
def test_qos(self): """Test floating IP is binding to a QoS policy with ingress and egress bandwidth limit rules. And it applied correctly by sending a file from the instance to the test node. Then calculating the bandwidth every ~1 sec by the number of bits received / elapsed time. """ self._test_basic_resources() policy_id = self._create_qos_policy() ssh_client = self._create_ssh_client() self.os_admin.network_client.create_bandwidth_limit_rule( policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BYTES, direction=lib_constants.INGRESS_DIRECTION) self.os_admin.network_client.create_bandwidth_limit_rule( policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BYTES, direction=lib_constants.EGRESS_DIRECTION) rules = self.os_admin.network_client.list_bandwidth_limit_rules( policy_id) self.assertEqual(2, len(rules['bandwidth_limit_rules'])) fip = self.os_admin.network_client.get_floatingip( self.fip['id'])['floatingip'] self.assertEqual(self.port['id'], fip['port_id']) self.os_admin.network_client.update_floatingip( self.fip['id'], qos_policy_id=policy_id) fip = self.os_admin.network_client.get_floatingip( self.fip['id'])['floatingip'] self.assertEqual(policy_id, fip['qos_policy_id']) self._create_file_for_bw_tests(ssh_client) common_utils.wait_until_true(lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=120, sleep=1)
def _wait_for_router_ha_active(cls, router_id): router = cls.os_admin.network_client.show_router(router_id)['router'] if not router.get('ha'): return def _router_active_on_l3_agent(): agents = cls.os_admin.network_client.list_l3_agents_hosting_router( router_id)['agents'] return "active" in [agent['ha_state'] for agent in agents] error_msg = ("Router %s is not active on any of the L3 agents" % router_id) # NOTE(slaweq): timeout here should be lower for sure, but due to # the bug https://launchpad.net/bugs/1923633 let's wait even 10 # minutes until router will be active on some of the L3 agents utils.wait_until_true(_router_active_on_l3_agent, timeout=600, sleep=5, exception=lib_exc.TimeoutException(error_msg))
def wait_for_interface_status(client, server_id, port_id, status, ssh_client=None, mac_address=None): """Waits for an interface to reach a given status and checks VM NIC This method enhances the tempest one. Apart from checking the interface status returned by Nova, this methods access the VM to check if the NIC interface is already detected by the kernel. """ body = waiters.wait_for_interface_status(client, server_id, port_id, status) if ssh_client and mac_address: ip_command = IPCommand(ssh_client) common_utils.wait_until_true( lambda: ip_command.get_nic_name_by_mac(mac_address), timeout=10, exception=RuntimeError('Interface with MAC %s not present in the ' 'VM' % mac_address)) return body
def wait_for_guest_os_ready(self, server, client=None): if not CONF.compute_feature_enabled.console_output: LOG.debug( 'Console output not supported, cannot check if server ' '%s is ready.', server['id']) return client = client or self.os_primary.servers_client def system_booted(): console_output = client.get_console_output(server['id'])['output'] for line in console_output.split('\n'): if 'login:'******'t be checked.", server['id'])
def test_port_forwarding_editing_and_deleting_tcp_rule(self): test_ext_port = 3333 server = self._prepare_resources(num_servers=1, external_port_base=1045) fip_id = server[0]['port_forwarding_tcp']['floatingip_id'] pf_id = server[0]['port_forwarding_tcp']['id'] # Check connectivity with the original parameters self.check_servers_hostnames(server) def fip_pf_connectivity(test_ssh_connect_timeout=60): try: self.check_servers_hostnames(server, timeout=test_ssh_connect_timeout) return True except (AssertionError, lib_exc.SSHTimeout): return False def no_fip_pf_connectivity(): return not fip_pf_connectivity(6) # Update external port and check connectivity with original parameters # Port under server[0]['port_forwarding_tcp']['external_port'] should # not answer at this point. self.client.update_port_forwarding(fip_id, pf_id, external_port=test_ext_port) utils.wait_until_true( no_fip_pf_connectivity, exception=RuntimeError( "Connection to the server {!r} through " "port {!r} is still possible.".format( server[0]['id'], server[0]['port_forwarding_tcp']['external_port']))) # Check connectivity with the new parameters server[0]['port_forwarding_tcp']['external_port'] = test_ext_port utils.wait_until_true( fip_pf_connectivity, exception=RuntimeError( "Connection to the server {!r} through " "port {!r} is not possible.".format( server[0]['id'], server[0]['port_forwarding_tcp']['external_port']))) # Remove port forwarding and ensure connection stops working. self.client.delete_port_forwarding(fip_id, pf_id) self.assertRaises(lib_exc.NotFound, self.client.get_port_forwarding, fip_id, pf_id) utils.wait_until_true( no_fip_pf_connectivity, exception=RuntimeError( "Connection to the server {!r} through " "port {!r} is still possible.".format( server[0]['id'], server[0]['port_forwarding_tcp']['external_port'])))
def test_nova_qos_fip_rate_limiting(self): """Test QOS when using NOVA flavor, with nuage fip rate limiting """ self._test_basic_resources() ssh_client = self._create_ssh_client() if hasattr(self, 'FILE_SIZE'): # Queens & Rocky: create file self._create_file_for_bw_tests(ssh_client) limit_bytes_sec = self.LIMIT_KBPS * 1024 * self.TOLERANCE_FACTOR # Check bw limited common_utils.wait_until_true( lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=limit_bytes_sec), timeout=200, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=limit_bytes_sec), timeout=200, sleep=1) # Set ingress & egress fip rate limiting self.client.update_floatingip( self.fip['id'], nuage_egress_fip_rate_kbps=400, nuage_ingress_fip_rate_kbps=200) # Check bw limited expected_egress_bw = 200 * 1024 * self.TOLERANCE_FACTOR / 8.0 expected_ingress_bw = 400 * 1024 * self.TOLERANCE_FACTOR / 8.0 common_utils.wait_until_true( lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=expected_egress_bw), timeout=200, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=expected_ingress_bw), timeout=200, sleep=1) # Remove fip rate limit self.client.update_floatingip( self.fip['id'], nuage_egress_fip_rate_kbps=-1, nuage_ingress_fip_rate_kbps=-1) # Check bw limited again to original nova qos limit_bytes_sec = self.LIMIT_KBPS * 1024 * 1.5 # Check bw limited common_utils.wait_until_true( lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=limit_bytes_sec), timeout=200, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=limit_bytes_sec), timeout=200, sleep=1)
def test_mac_learning_vms_on_same_network(self): """Test mac learning works in a network. The receiver server will receive all the sent packets. The non receiver should not receive any. """ sender = self._create_server() receiver = self._create_server() non_receiver = self._create_server() def check_server_result(server, expected_result, output_file): result = server['ssh_client'].execute_script( "cat {path} || echo '{path} not exists yet'".format( path=output_file)) LOG.debug("VM result: %s", result) return expected_result in result # Prepare the server that is intended to receive the packets self._prepare_listener(receiver, 5) # Prepare the server that is not intended receive of the packets. self._prepare_listener(non_receiver, 2) # Run the scripts for server in [receiver, non_receiver]: server['ssh_client'].execute_script("bash %s" % self.receiver_script_file, become_root=True) # Prepare the server that will make the ping. target_ip = receiver['port']['fixed_ips'][0]['ip_address'] self._prepare_sender(sender, address=target_ip) LOG.debug("The receiver IP is: %s", target_ip) # Run the sender node script sender['ssh_client'].execute_script("bash %s" % self.sender_script_file, become_root=True) # Check if the message was sent. utils.wait_until_true( lambda: check_server_result(sender, self.completed_message, self. sender_output_file), exception=RuntimeError("Sender script wasn't executed properly")) # Check receiver server receiver_expected_result = '5 packets captured' utils.wait_until_true( lambda: check_server_result(receiver, receiver_expected_result, self.output_file), exception=RuntimeError( 'Receiver server did not receive expected packet')) # Check the non_receiver server non_receiver_expected_result = '0 packets captured' try: LOG.debug("Try killing non-receiver tcpdump") non_receiver['ssh_client'].execute_script( "killall tcpdump && sleep 2", become_root=True) except exceptions.SSHScriptFailed: LOG.debug("Killing tcpdump failed") self.assertTrue( check_server_result(non_receiver, non_receiver_expected_result, self.output_file), 'Non targeted server received unexpected packets') return
def _wait_for_trunk(self, trunk, status=constants.ACTIVE): utils.wait_until_true( lambda: self._is_trunk_status(trunk, status), exception=RuntimeError( "Timed out waiting for trunk {!r} to transition to get " "status {!r}.".format(trunk['id'], status)))
def test_qos(self): """Test floating IP is binding to a QoS policy with ingress and egress bandwidth limit rules. And it applied correctly by sending a file from the instance to the test node. Then calculating the bandwidth every ~1 sec by the number of bits received / elapsed time. """ self._test_basic_resources() ssh_client = self._create_ssh_client() fip = self.os_admin.network_client.get_floatingip( self.fip['id'])['floatingip'] self.assertEqual(self.port['id'], fip['port_id']) if hasattr(self, 'FILE_SIZE'): # Queens & Rocky: create file self._create_file_for_bw_tests(ssh_client) # Check bw not limited unlimited_bw = sys.maxsize common_utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=unlimited_bw), timeout=240) self.os_admin.network_client.update_floatingip( self.fip['id'], nuage_egress_fip_rate_kbps=500, nuage_ingress_fip_rate_kbps=1000) expected_egress_bw = 500 * 1024 * self.TOLERANCE_FACTOR / 8.0 expected_ingress_bw = 1000 * 1024 * self.TOLERANCE_FACTOR / 8.0 common_utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=expected_egress_bw), timeout=120, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=expected_ingress_bw), timeout=120, sleep=1) # Update floating ip QOS to new value self.os_admin.network_client.update_floatingip( self.fip['id'], nuage_egress_fip_rate_kbps=200, nuage_ingress_fip_rate_kbps=400) expected_egress_bw = 200 * 1024 * self.TOLERANCE_FACTOR / 8.0 expected_ingress_bw = 400 * 1024 * self.TOLERANCE_FACTOR / 8.0 common_utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=expected_egress_bw), timeout=120, sleep=1) common_utils.wait_until_true( lambda: self._check_bw_ingress(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT + 1, expected_bw=expected_ingress_bw), timeout=120, sleep=1)
def test_qos(self): """Test floating IP is binding to a QoS policy with ingress and egress bandwidth limit rules. And it applied correctly by sending a file from the instance to the test node. Then calculating the bandwidth every ~1 sec by the number of bits received / elapsed time. """ self.skip_if_no_extension_enabled_in_l3_agents("fip_qos") self._test_basic_resources() # Create a new QoS policy policy_id = self._create_qos_policy() ssh_client = self._create_ssh_client() # As admin user create a new QoS rules rule_data = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND, 'max_burst_kbps': constants.LIMIT_KILO_BYTES, 'direction': lib_constants.INGRESS_DIRECTION } self.qos_bw_limit_rule_client.create_limit_bandwidth_rule( qos_policy_id=policy_id, **rule_data) rule_data = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND, 'max_burst_kbps': constants.LIMIT_KILO_BYTES, 'direction': lib_constants.EGRESS_DIRECTION } self.qos_bw_limit_rule_client.create_limit_bandwidth_rule( qos_policy_id=policy_id, **rule_data) rules = self.qos_bw_limit_rule_client.list_limit_bandwidth_rules( policy_id) self.assertEqual(2, len(rules['bandwidth_limit_rules'])) fip = self.os_admin.network_client.get_floatingip( self.fip['id'])['floatingip'] self.assertEqual(self.port['id'], fip['port_id']) # Associate QoS to the FIP self.os_admin.network_client.update_floatingip(self.fip['id'], qos_policy_id=policy_id) fip = self.os_admin.network_client.get_floatingip( self.fip['id'])['floatingip'] self.assertEqual(policy_id, fip['qos_policy_id']) # Basic test, Check that actual BW while downloading file # is as expected (Original BW) common_utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=120, sleep=1, exception=RuntimeError( 'Failed scenario: "Create a QoS policy associated with FIP" ' 'Actual BW is not as expected!')) # As admin user update QoS rules for rule in rules['bandwidth_limit_rules']: self.qos_bw_limit_rule_client.update_limit_bandwidth_rule( policy_id, rule['id'], **{ 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 2, 'max_burst_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 2 }) # Check that actual BW while downloading file # is as expected (Update BW) common_utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=test_qos.QoSTestMixin. LIMIT_BYTES_SEC * 2), timeout=120, sleep=1, exception=RuntimeError( 'Failed scenario: "Update QoS policy associated with FIP" ' 'Actual BW is not as expected!'))
def test_qos_basic_and_update(self): """This test covers both: 1) Basic QoS functionality This is a basic test that check that a QoS policy with a bandwidth limit rule is applied correctly by sending a file from the instance to the test node. Then calculating the bandwidth every ~1 sec by the number of bits received / elapsed time. 2) Update QoS policy Administrator has the ability to update existing QoS policy, this test is planned to verify that: - actual BW is affected as expected after updating QoS policy. Test scenario: 1) Associating QoS Policy with "Original_bandwidth" to the test node 2) BW validation - by downloading file on test node. ("Original_bandwidth" is expected) 3) Updating existing QoS Policy to a new BW value "Updated_bandwidth" 4) BW validation - by downloading file on test node. ("Updated_bandwidth" is expected) Note: There are two options to associate QoS policy to VM: "Neutron Port" or "Network", in this test both options are covered. """ # Setup resources self._test_basic_resources() ssh_client = self._create_ssh_client() # Create QoS policy bw_limit_policy_id = self._create_qos_policy() # As admin user create QoS rule rule_id = self.os_admin.network_client.create_bandwidth_limit_rule( policy_id=bw_limit_policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND )['bandwidth_limit_rule']['id'] # Associate QoS to the network self.os_admin.network_client.update_network( self.network['id'], qos_policy_id=bw_limit_policy_id) # Create file on VM self._create_file_for_bw_tests(ssh_client) # Basic test, Check that actual BW while downloading file # is as expected (Original BW) utils.wait_until_true(lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1) # As admin user update QoS rule self.os_admin.network_client.update_bandwidth_limit_rule( bw_limit_policy_id, rule_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2) # Check that actual BW while downloading file # is as expected (Update BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=QoSTest.LIMIT_BYTES_SEC * 2), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1) # Create a new QoS policy bw_limit_policy_id_new = self._create_qos_policy() # As admin user create a new QoS rule rule_id_new = self.os_admin.network_client.create_bandwidth_limit_rule( policy_id=bw_limit_policy_id_new, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND )['bandwidth_limit_rule']['id'] # Associate a new QoS policy to Neutron port self.os_admin.network_client.update_port( self.port['id'], qos_policy_id=bw_limit_policy_id_new) # Check that actual BW while downloading file # is as expected (Original BW) utils.wait_until_true(lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1) # As admin user update QoS rule self.os_admin.network_client.update_bandwidth_limit_rule( bw_limit_policy_id_new, rule_id_new, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 3, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 3) # Check that actual BW while downloading file # is as expected (Update BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=QoSTest.LIMIT_BYTES_SEC * 3), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1)
def test_modify_dhcp_port_ip_address(self): """Test Scenario 1) Create a network and a subnet with DHCP enabled 2) Modify the default IP address from the subnet DHCP port 3) Create a server in this network and check ssh connectivity For the step 3), the server needs to obtain ssh keys from the metadata Related bug: LP#1942794 """ # create subnet (dhcp is enabled by default) subnet = self.create_subnet(network=self.network, name=self.rand_name) def _get_dhcp_ports(): # in some cases, like ML2/OVS, the subnet port associated to DHCP # is created with device_owner='network:dhcp' dhcp_ports = self.client.list_ports( network_id=self.network['id'], device_owner=constants.DEVICE_OWNER_DHCP)['ports'] # in other cases, like ML2/OVN, the subnet port used for metadata # is created with device_owner='network:distributed' distributed_ports = self.client.list_ports( network_id=self.network['id'], device_owner=constants.DEVICE_OWNER_DISTRIBUTED)['ports'] self.dhcp_ports = dhcp_ports + distributed_ports self.assertLessEqual( len(self.dhcp_ports), 1, msg='Only one port was expected') return len(self.dhcp_ports) == 1 # obtain the dhcp port # in some cases this port is not created together with the subnet, but # immediately after it, so some delay may be needed and that is the # reason why a waiter function is used here self.dhcp_ports = [] neutron_utils.wait_until_true( lambda: _get_dhcp_ports(), timeout=10) dhcp_port = self.dhcp_ports[0] # modify DHCP port IP address old_dhcp_port_ip = netaddr.IPAddress( dhcp_port['fixed_ips'][0]['ip_address']) if str(old_dhcp_port_ip) != subnet['allocation_pools'][0]['end']: new_dhcp_port_ip = str(old_dhcp_port_ip + 1) else: new_dhcp_port_ip = str(old_dhcp_port_ip - 1) self.update_port(port=dhcp_port, fixed_ips=[{'subnet_id': subnet['id'], 'ip_address': new_dhcp_port_ip}]) # create server server = self.create_server( flavor_ref=CONF.compute.flavor_ref, image_ref=CONF.compute.image_ref, key_name=self.keypair['name'], security_groups=[{'name': self.security_group['name']}], networks=[{'uuid': self.network['id']}]) # attach fip to the server self.create_router_interface(self.router['id'], subnet['id']) server_port = self.client.list_ports( network_id=self.network['id'], device_id=server['server']['id'])['ports'][0] fip = self.create_floatingip(port_id=server_port['id']) # check connectivity self.check_connectivity(fip['floating_ip_address'], CONF.validation.image_ssh_user, self.keypair['private_key'])
def _wait_for_port(self, port, status=constants.ACTIVE): utils.wait_until_true( lambda: self._is_port_status(port, status), exception=RuntimeError( "Timed out waiting for port {!r} to transition to get " "status {!r}.".format(port['id'], status)))
def _check_multicast_conectivity(self, sender, receivers, unregistered): """Test multi-cast messaging between two servers [Sender server] -> ... some network topology ... -> [Receiver server] """ mcast_address = next(self.multicast_group_iter) LOG.debug("Multicast group address: %s", mcast_address) def _message_received(client, msg, file_path): result = client.execute_script( "cat {path} || echo '{path} not exists yet'".format( path=file_path)) return msg in result self._prepare_unregistered(unregistered, mcast_address) # Run the unregistered node script unregistered['ssh_client'].execute_script( "bash /tmp/unregistered_traffic_receiver.sh", become_root=True) self._prepare_sender(sender, mcast_address) receiver_ids = [] for receiver in receivers: self._prepare_receiver(receiver, mcast_address) receiver['ssh_client'].execute_script( "%s /tmp/multicast_traffic_receiver.py &" % PYTHON3_BIN, shell="bash") utils.wait_until_true( lambda: _message_received(receiver['ssh_client' ], self.hello_message, self. receiver_output_file), exception=RuntimeError( "Receiver script didn't start properly on server " "{!r}.".format(receiver['id']))) receiver_ids.append(receiver['id']) # Now lets run scripts on sender sender['ssh_client'].execute_script( "%s /tmp/multicast_traffic_sender.py" % PYTHON3_BIN) # And check if message was received for receiver in receivers: utils.wait_until_true( lambda: _message_received(receiver[ 'ssh_client'], self.multicast_message, self. receiver_output_file), exception=RuntimeError( "Receiver {!r} didn't get multicast message".format( receiver['id']))) # TODO(slaweq): add validation of answears on sended server replies_result = sender['ssh_client'].execute_script( "cat {path} || echo '{path} not exists yet'".format( path=self.sender_output_file)) for receiver_id in receiver_ids: self.assertIn(receiver_id, replies_result) def check_unregistered_host(): unregistered_result = unregistered['ssh_client'].execute_script( "cat {path} || echo '{path} not exists yet'".format( path=self.unregistered_output_file)) LOG.debug("Unregistered VM result: %s", unregistered_result) return expected_result in unregistered_result expected_result = '1 packet captured' unregistered_error_message = ( 'Unregistered server did not received expected packet.') if not self._is_multicast_traffic_expected(mcast_address): # Kill the tcpdump command runs on the unregistered node with "-c" # option so it will be stopped automatically if it will receive # packet matching filters, # We don't expect any packets to be captured really in this case # so let's kill tcpdump so it flushes its output to the output # file. expected_result = ('0 packets captured') unregistered_error_message = ( 'Unregistered server received unexpected packet(s).') try: unregistered['ssh_client'].execute_script( "killall tcpdump && sleep 2", become_root=True) except exceptions.SSHScriptFailed: # Probably some packet was captured by tcpdump and due to that # it is already stopped self.assertTrue(check_unregistered_host(), unregistered_error_message) return utils.wait_until_true( check_unregistered_host, exception=RuntimeError(unregistered_error_message))
def test_qos_basic_and_update(self): """This test covers following scenarios: 1) Create a QoS policy associated with the network. Expected result: BW is limited according the values set in QoS policy rule. 2) Update QoS policy associated with the network. Expected result: BW is limited according the new values set in QoS policy rule. 3) Create a new QoS policy associated with the VM port. Expected result: BW is limited according the values set in new QoS policy rule. Note: Neutron port is prioritized higher than Network, means that: "Neutron Port Priority" is also covered. 4) Update QoS policy associated with the VM port. Expected result: BW is limited according the new values set in QoS policy rule. """ # Setup resources self._test_basic_resources() ssh_client = self._create_ssh_client() # Create QoS policy bw_limit_policy_id = self._create_qos_policy() # As admin user create QoS rule rule_data = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND, 'max_burst_kbps': constants.LIMIT_KILO_BITS_PER_SECOND } rule_id = self._create_qos_bw_limit_rule(bw_limit_policy_id, rule_data)['id'] # Associate QoS to the network self.os_admin.network_client.update_network( self.network['id'], qos_policy_id=bw_limit_policy_id) # Basic test, Check that actual BW while downloading file # is as expected (Original BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.CHECK_TIMEOUT, sleep=1, exception=RuntimeError( 'Failed scenario: "Create a QoS policy associated with' ' the network" Actual BW is not as expected!')) # As admin user update QoS rule rule_update_data = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 2, 'max_burst_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 2 } self.qos_bw_limit_rule_client.update_limit_bandwidth_rule( qos_policy_id=bw_limit_policy_id, rule_id=rule_id, **rule_update_data) # Check that actual BW while downloading file # is as expected (Update BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=QoSTest.LIMIT_BYTES_SEC * 2), timeout=self.CHECK_TIMEOUT, sleep=1, exception=RuntimeError( 'Failed scenario: "Update QoS policy associated with' ' the network" Actual BW is not as expected!')) # Create a new QoS policy bw_limit_policy_id_new = self._create_qos_policy() # As admin user create a new QoS rule rule_data_new = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND, 'max_burst_kbps': constants.LIMIT_KILO_BITS_PER_SECOND } rule_id_new = self._create_qos_bw_limit_rule(bw_limit_policy_id_new, rule_data_new)['id'] # Associate a new QoS policy to Neutron port self.os_admin.network_client.update_port( self.port['id'], qos_policy_id=bw_limit_policy_id_new) # Check that actual BW while downloading file # is as expected (Original BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.CHECK_TIMEOUT, sleep=1, exception=RuntimeError( 'Failed scenario: "Create a new QoS policy associated with' ' the VM port" Actual BW is not as expected!')) # As admin user update QoS rule rule_update_data = { 'max_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 3, 'max_burst_kbps': constants.LIMIT_KILO_BITS_PER_SECOND * 3 } self.qos_bw_limit_rule_client.update_limit_bandwidth_rule( qos_policy_id=bw_limit_policy_id_new, rule_id=rule_id_new, **rule_update_data) # Check that actual BW while downloading file # is as expected (Update BW) utils.wait_until_true( lambda: self._check_bw(ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=QoSTest.LIMIT_BYTES_SEC * 3), timeout=self.CHECK_TIMEOUT, sleep=1, exception=RuntimeError( 'Failed scenario: "Update QoS policy associated with' ' the VM port" Actual BW is not as expected!'))
def test_qos_basic_and_update_ingress(self): # Setup resources self._test_basic_resources() ssh_client = self._create_ssh_client() # Create QoS policy bw_limit_policy_id = self._create_qos_policy() # As admin user create QoS rule rule_id = self.os_admin.network_client.create_bandwidth_limit_rule( policy_id=bw_limit_policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, direction='ingress')['bandwidth_limit_rule']['id'] # Associate QoS to the network self.os_admin.network_client.update_network( self.network['id'], qos_policy_id=bw_limit_policy_id) if hasattr(self, 'FILE_SIZE'): # Queens & Rocky: create file self._create_file_for_bw_tests(ssh_client) # Basic test, Check that actual BW while uploading file # is as expected (Original BW) common_utils.wait_until_true(lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.CHECK_TIMEOUT, sleep=1) # As admin user update QoS rule self.os_admin.network_client.update_bandwidth_limit_rule( bw_limit_policy_id, rule_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 2) # Check that actual BW while uploading file # is as expected (Update BW) common_utils.wait_until_true(lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=test_qos.QoSTestMixin.LIMIT_BYTES_SEC * 2), timeout=self.CHECK_TIMEOUT, sleep=1) # Create a new QoS policy bw_limit_policy_id_new = self._create_qos_policy() # As admin user create a new QoS rule rule_id_new = self.os_admin.network_client.create_bandwidth_limit_rule( policy_id=bw_limit_policy_id_new, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND )['bandwidth_limit_rule']['id'] # Associate a new QoS policy to Neutron port self.os_admin.network_client.update_port( self.port['id'], qos_policy_id=bw_limit_policy_id_new) # Check that actual BW while uploading file # is as expected (Original BW) common_utils.wait_until_true(lambda: self._check_bw_ingress( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1) # As admin user update QoS rule self.os_admin.network_client.update_bandwidth_limit_rule( bw_limit_policy_id_new, rule_id_new, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 3, max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND * 3) # Check that actual BW while uploading file # is as expected (Update BW) common_utils.wait_until_true(lambda: self._check_bw( ssh_client, self.fip['floating_ip_address'], port=self.NC_PORT, expected_bw=test_qos.QoSTestMixin.LIMIT_BYTES_SEC * 3), timeout=self.FILE_DOWNLOAD_TIMEOUT, sleep=1)