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)
Exemple #4
0
    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)
Exemple #5
0
    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']))
Exemple #6
0
    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)
Exemple #8
0
    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)
Exemple #10
0
    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)
Exemple #11
0
    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))
Exemple #12
0
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
Exemple #13
0
    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'])
Exemple #14
0
    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)
Exemple #16
0
    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)
Exemple #21
0
    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)))
Exemple #23
0
    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)