def test_multiple_vlans(self): with vlan_device(self.device_name, tag=16) as vlan1: with vlan_device(self.device_name, tag=17) as vlan2: for v in (vlan1, vlan2): qos.configure_outbound(HOST_QOS_OUTBOUND, self.device_name, v.tag) tc_classes, tc_filters, tc_qdiscs = \ self._analyse_qos_and_general_assertions() self.assertEqual(len(tc_classes.classes), 2) self.assertEqual(len(tc_qdiscs.leaf_qdiscs), 3) v1_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, vlan1.tag) v2_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, vlan2.tag) v1_class = self._vlan_class(tc_classes.classes, vlan1.tag) v2_class = self._vlan_class(tc_classes.classes, vlan2.tag) self._assert_parent([v1_qdisc], v1_class) self._assert_parent([v2_qdisc], v2_class) self.assertEqual(len(tc_filters.tagged_filters), 2) current_tagged_filters_flow_id = set( f['basic']['flowid'] for f in tc_filters.tagged_filters) expected_flow_ids = set( '%s%x' % (qos._ROOT_QDISC_HANDLE, v.tag) for v in (vlan1, vlan2)) self.assertEqual(current_tagged_filters_flow_id, expected_flow_ids)
def test_multiple_vlans(self, dummy): with vlan_device(dummy, tag=16) as vlan1: with vlan_device(dummy, tag=17) as vlan2: for v in (vlan1, vlan2): qos.configure_outbound(HOST_QOS_OUTBOUND, dummy, v.tag) tc_entities = self._analyse_qos_and_general_assertions(dummy) tc_classes, tc_filters, tc_qdiscs = tc_entities assert len(tc_classes.classes) == 2 assert len(tc_qdiscs.leaf_qdiscs) == 3 v1_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, vlan1.tag) v2_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, vlan2.tag) v1_class = self._vlan_class(tc_classes.classes, vlan1.tag) v2_class = self._vlan_class(tc_classes.classes, vlan2.tag) self._assert_parent([v1_qdisc], v1_class) self._assert_parent([v2_qdisc], v2_class) assert len(tc_filters.tagged_filters) == 2 current_tagged_filters_flow_id = set( f['basic']['flowid'] for f in tc_filters.tagged_filters) expected_flow_ids = set('%s%x' % (qos._ROOT_QDISC_HANDLE, v.tag) for v in (vlan1, vlan2)) assert current_tagged_filters_flow_id == expected_flow_ids
def test_iperf_upper_limit(self): # Upper limit is not an accurate measure. This is because it converges # over time and depends on current machine hardware (CPU). # Hence, it is hard to make hard assertions on it. The test should run # at least 60 seconds (the longer the better) and the user should # inspect the computed average rate and optionally the additional # traffic data that was collected in client.out in order to be # convinced QOS is working properly. limit_kbps = 1000 # 1 Mbps (in kbps) server_ip = '192.0.2.1' client_ip = '192.0.2.10' qos_out = {'ul': {'m2': limit_kbps}, 'ls': {'m2': limit_kbps}} # using a network namespace is essential since otherwise the kernel # short-circuits the traffic and bypasses the veth devices and the # classfull qdisc. with network_namespace( 'server_ns' ) as ns, bridge_device() as bridge, veth_pair() as ( server_peer, server_dev, ), veth_pair() as ( client_dev, client_peer, ): linkSet(server_peer, ['up']) linkSet(client_peer, ['up']) # iperf server and its veth peer lie in a separate network # namespace link_set_netns(server_dev, ns) bridge.addIf(server_peer) bridge.addIf(client_peer) linkSet(client_dev, ['up']) netns_exec(ns, ['ip', 'link', 'set', 'dev', server_dev, 'up']) addrAdd(client_dev, client_ip, 24) netns_exec( ns, [ 'ip', '-4', 'addr', 'add', 'dev', server_dev, '%s/24' % server_ip, ], ) qos.configure_outbound(qos_out, client_peer, None) with running(IperfServer(server_ip, network_ns=ns)): client = IperfClient(server_ip, client_ip, test_time=60) client.start() max_rate = max( [ float(interval['streams'][0]['bits_per_second']) // (2 ** 10) for interval in client.out['intervals'] ] ) self.assertTrue(0 < max_rate < limit_kbps * 1.5)
def test_single_non_vlan(self): qos.configure_outbound(HOST_QOS_OUTBOUND, self.device_name, None) tc_classes, tc_filters, tc_qdiscs = \ self._analyse_qos_and_general_assertions() self.assertEqual(tc_classes.classes, []) self.assertEqual(len(tc_qdiscs.leaf_qdiscs), 1) self.assertIsNotNone(self._non_vlan_qdisc(tc_qdiscs.leaf_qdiscs)) self._assert_parent(tc_qdiscs.leaf_qdiscs, tc_classes.default_class) self.assertEqual(len(tc_filters.tagged_filters), 0)
def test_single_non_vlan(self, dummy): qos.configure_outbound(HOST_QOS_OUTBOUND, dummy, None) tc_entities = self._analyse_qos_and_general_assertions(dummy) tc_classes, tc_filters, tc_qdiscs = tc_entities assert tc_classes.classes == [] assert len(tc_qdiscs.leaf_qdiscs) == 1 assert self._non_vlan_qdisc(tc_qdiscs.leaf_qdiscs) is not None self._assert_parent(tc_qdiscs.leaf_qdiscs, tc_classes.default_class) assert len(tc_filters.tagged_filters) == 0
def test_single_vlan(self, dummy, vlan16, repeating_calls): for _ in range(repeating_calls): qos.configure_outbound(HOST_QOS_OUTBOUND, dummy, VLAN16_TAG) tc_entities = self._analyse_qos_and_general_assertions(dummy) tc_classes, tc_filters, tc_qdiscs = tc_entities assert len(tc_classes.classes) == 1 assert len(tc_qdiscs.leaf_qdiscs) == 2 vlan_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, VLAN16_TAG) vlan_class = self._vlan_class(tc_classes.classes, VLAN16_TAG) self._assert_parent([vlan_qdisc], vlan_class) tag_filters = tc_filters.tagged_filters assert len(tag_filters) == 1 assert int(tag_filters[0]['basic']['value']) == VLAN16_TAG
def test_single_vlan(self, repeating_calls): with vlan_device(self.device_name) as vlan: for _ in range(repeating_calls): qos.configure_outbound(HOST_QOS_OUTBOUND, self.device_name, vlan.tag) tc_classes, tc_filters, tc_qdiscs = \ self._analyse_qos_and_general_assertions() self.assertEqual(len(tc_classes.classes), 1) self.assertEqual(len(tc_qdiscs.leaf_qdiscs), 2) vlan_qdisc = self._vlan_qdisc(tc_qdiscs.leaf_qdiscs, vlan.tag) vlan_class = self._vlan_class(tc_classes.classes, vlan.tag) self._assert_parent([vlan_qdisc], vlan_class) self.assertEqual(len(tc_filters.tagged_filters), 1) self.assertEqual( int(tc_filters.tagged_filters[0]['basic']['value']), vlan.tag)
def test_iperf_upper_limit(self): # Upper limit is not an accurate measure. This is because it converges # over time and depends on current machine hardware (CPU). # Hence, it is hard to make hard assertions on it. The test should run # at least 60 seconds (the longer the better) and the user should # inspect the computed average rate and optionally the additional # traffic data that was collected in client.out in order to be # convinced QOS is working properly. limit_kbps = 1000 # 1 Mbps (in kbps) server_ip = '192.0.2.1' client_ip = '192.0.2.10' qos_out = {'ul': {'m2': limit_kbps}, 'ls': {'m2': limit_kbps}} # using a network namespace is essential since otherwise the kernel # short-circuits the traffic and bypasses the veth devices and the # classfull qdisc. with network_namespace('server_ns') as ns, bridge_device() as bridge, \ veth_pair() as (server_peer, server_dev), \ veth_pair() as (client_dev, client_peer): linkSet(server_peer, ['up']) linkSet(client_peer, ['up']) # iperf server and its veth peer lie in a separate network # namespace link_set_netns(server_dev, ns) bridge.addIf(server_peer) bridge.addIf(client_peer) linkSet(client_dev, ['up']) netns_exec(ns, ['ip', 'link', 'set', 'dev', server_dev, 'up']) addrAdd(client_dev, client_ip, 24) netns_exec(ns, ['ip', '-4', 'addr', 'add', 'dev', server_dev, '%s/24' % server_ip]) qos.configure_outbound(qos_out, client_peer, None) with running(IperfServer(server_ip, network_ns=ns)): client = IperfClient(server_ip, client_ip, test_time=60) client.start() max_rate = max([float( interval['streams'][0]['bits_per_second']) / (2**10) for interval in client.out['intervals']]) self.assertTrue(0 < max_rate < limit_kbps * 1.5)
def _configure_qos(net_attrs, out): vlan = net_attrs.get('vlan') base_iface = _get_base_iface(net_attrs) qos.configure_outbound(out, base_iface, vlan)
def _configure_qos(net_attrs): out = net_attrs.get('hostQos', {}).get('out') if out: vlan = net_attrs.get('vlan') base_iface = _get_base_iface(net_attrs) qos.configure_outbound(out, base_iface, vlan)