def debug(cls, _, __, ___): config = load_service_config('pipelined') qos_impl_type = QosImplType(config["qos"]["impl"]) qos_store = QosStore(cls.__name__) for k, v in qos_store.items(): _, imsi, ip_addr, rule_num, d = get_key(k) _, qid, ambr, leaf = get_data(v) print('imsi :', imsi) print('ip_addr :', ip_addr) print('rule_num :', rule_num) print('direction :', d) print('qos_handle:', qid) print('qos_handle_ambr:', ambr) print('qos_handle_ambr_leaf:', leaf) if qos_impl_type == QosImplType.OVS_METER: MeterManager.dump_meter_state(v) else: intf = 'nat_iface' if d == FlowMatch.UPLINK else 'enodeb_iface' print("Dev: ", config[intf]) TrafficClass.dump_class_state(config[intf], qid) if leaf and leaf != qid: print("Leaf:") TrafficClass.dump_class_state(config[intf], leaf) if ambr: print("AMBR (parent):") TrafficClass.dump_class_state(config[intf], ambr) if qos_impl_type == QosImplType.LINUX_TC: dev = config['nat_iface'] print("Root stats for: ", dev) TrafficClass.dump_root_class_stats(dev) dev = config['enodeb_iface'] print("Root stats for: ", dev) TrafficClass.dump_root_class_stats(dev)
def testError(self, mock_check_call): def dummy_check_call(*args): raise subprocess.CalledProcessError(returncode=1, cmd="tc") mock_check_call.side_effect = dummy_check_call with self.assertLogs("pipelined.qos.tc_cmd", level="ERROR") as cm: TrafficClass.init_qdisc("eth0", show_error=True) self.assertTrue("error: 1 running: tc qdisc add dev " in cm.output[0])
def testSudoUser(self, _, mock_check_call): intf = 'qt' BRIDGE = 'qtbr0' BridgeTools.create_bridge(BRIDGE, BRIDGE) BridgeTools.create_internal_iface(BRIDGE, intf, None) TrafficClass.init_qdisc(intf) mock_check_call.assert_any_call( ["sudo", "tc", "qdisc", "add", "dev", intf, "root", "handle", "1:", "htb"], )
def debug(cls, _): config = load_service_config('pipelined') qos_impl_type = QosImplType(config["qos"]["impl"]) qos_store = QosStore(cls.__name__) for k, v in qos_store.items(): _, imsi, rule_num, d = get_key(k) print('imsi :', imsi) print('rule_num :', rule_num) print('direction :', d) print('qos_handle:', v) if qos_impl_type == QosImplType.OVS_METER: MeterManager.dump_meter_state(v) else: intf = 'nat_iface' if d == FlowMatch.UPLINK else 'enodeb_iface' TrafficClass.dump_class_state(config[intf], v)
def testSanity(self, mock_del_cls, mock_check_call): TrafficClass.create_class("en0", 2, 10) mock_del_cls.assert_called_with("en0", 2, show_error=False, throw_except=False) mock_check_call.assert_any_call([ 'tc', 'class', 'add', 'dev', 'en0', 'parent', '1:fffe', 'classid', '1:0x2', 'htb', 'rate', '12000', 'ceil', '10' ]) mock_check_call.assert_any_call([ 'tc', 'qdisc', 'add', 'dev', 'en0', 'parent', '1:0x2', 'fq_codel' ]) mock_check_call.assert_any_call([ 'tc', 'filter', 'add', 'dev', 'en0', 'protocol', 'ip', 'parent', '1:', 'prio', '1', 'handle', '0x2', 'fw', 'flowid', '1:0x2' ])
def testError(self, mock_check_call): def dummy_check_call(*args): raise subprocess.CalledProcessError(returncode=1, cmd="tc") mock_check_call.side_effect = dummy_check_call with self.assertLogs("pipelined.qos.qos_tc_impl", level="ERROR") as cm: try: TrafficClass.init_qdisc("en0", throw_except=True, show_error=True) self.fail("init_qdisc didn't raise an exception") except subprocess.CalledProcessError: pass self.assertTrue("error running tc qdisc add dev" in cm.output[0]) args = [ "tc", "qdisc", "add", "dev", "en0", "root", "handle", "1:", "htb" ] mock_check_call.assert_called_with(args)
def testError(self, mock_check_call): def dummy_check_call(*args): raise subprocess.CalledProcessError(returncode=1, cmd="tc") mock_check_call.side_effect = dummy_check_call with self.assertLogs('pipelined.qos.qos_tc_impl', level='ERROR') as cm: try: TrafficClass.init_qdisc("en0", throw_except=True, show_error=True) self.fail("init_qdisc didn't raise an exception") except subprocess.CalledProcessError: pass self.assertTrue("error running tc qdisc add dev" in cm.output[0]) args = [ 'tc', 'qdisc', 'add', 'dev', 'en0', 'root', 'handle', '1:', 'htb' ] mock_check_call.assert_called_with(args)
def testSanity(self, mock_del_cls, mock_check_call): TrafficClass.create_class("en0", 2, 10) mock_del_cls.assert_called_with("en0", 2, show_error=False, throw_except=False) mock_check_call.assert_any_call([ "tc", "class", "add", "dev", "en0", "parent", "1:fffe", "classid", "1:0x2", "htb", "rate", "12000", "ceil", "10", ]) mock_check_call.assert_any_call([ "tc", "qdisc", "add", "dev", "en0", "parent", "1:0x2", "fq_codel" ]) mock_check_call.assert_any_call([ "tc", "filter", "add", "dev", "en0", "protocol", "ip", "parent", "1:", "prio", "1", "handle", "0x2", "fw", "flowid", "1:0x2", ])
def testReadAllClasses(self, mock_check_output): tc_output = """ class htb 1:1 parent 1:fffe prio 0 rate 12Kbit ceil 1Gbit burst 1599b\n class htb 1:fffe root rate 1Gbit ceil 1Gbit burst 1375b cburst 1375b\n class htb 1:2 root rate 1Gbit ceil 1Gbit burst 1375b cburst 1375b\n class htb 1:5 root rate 1Gbit ceil 1Gbit burst 1375b cburst 1375b\n class htb 1:7 root rate 1Gbit ceil 1Gbit burst 1375b cburst 1375b\n class htb 1:8 root rate 1Gbit ceil 1Gbit burst 1375b cburst 1375b\n class fq_codel 8005:23b parent 8005: \n class fq_codel 8005:383 parent 8005: \n """ mock_check_output.return_value = bytes(tc_output, "utf-8") qid_list = TrafficClass.read_all_classes("testIntf") self.assertTrue(qid_list == [1, 65534, 2, 5, 7, 8])
def setUpClass(cls): BridgeTools.create_bridge(cls.BRIDGE, cls.BRIDGE) BridgeTools.create_internal_iface(cls.BRIDGE, cls.IFACE, None) TrafficClass.init_qdisc(cls.IFACE, True)
def testSanityTrafficClass(self): intf = 'qt' BRIDGE = 'qtbr0' BridgeTools.create_bridge(BRIDGE, BRIDGE) BridgeTools.create_internal_iface(BRIDGE, intf, None) parent_qid = 2 qid = 3 apn_ambr = 1000000 bearer_mbr = 500000 bearer_gbr = 250000 TrafficClass.init_qdisc(intf, show_error=False) # create APN level ambr TrafficClass.create_class(intf, qid=parent_qid, max_bw=apn_ambr) # create child queue TrafficClass.create_class( intf, qid=qid, rate=bearer_gbr, max_bw=bearer_mbr, parent_qid=parent_qid, ) # check if the filters installed for leaf class only filter_output = subprocess.check_output(['tc', 'filter', 'show', 'dev', intf]) filter_list = filter_output.decode('utf-8').split("\n") filter_list = [ln for ln in filter_list if 'classid' in ln] assert('classid 1:{qid}'.format(qid=parent_qid) in filter_list[0]) assert('classid 1:{qid}'.format(qid=qid) in filter_list[1]) # check if classes are installed with appropriate bandwidth limits class_output = subprocess.check_output(['tc', 'class', 'show', 'dev', intf]) class_list = class_output.decode('utf-8').split("\n") for info in class_list: if 'class htb 1:{qid}'.format(qid=qid) in info: child_class = info if 'class htb 1:{qid}'.format(qid=parent_qid) in info: parent_class = info assert(parent_class and 'ceil 1Mbit' in parent_class) assert(child_class and 'rate 250Kbit ceil 500Kbit' in child_class) # check if fq_codel is associated only with the leaf class qdisc_output = subprocess.check_output(['tc', 'qdisc', 'show', 'dev', intf]) # check if read_all_classes work qid_list = TrafficClass.read_all_classes(intf) assert((qid, parent_qid) in qid_list) # delete leaf class TrafficClass.delete_class(intf, 3) # check class for qid 3 removed class_output = subprocess.check_output(['tc', 'class', 'show', 'dev', intf]) class_list = class_output.decode('utf-8').split("\n") assert( not [ info for info in class_list if 'class htb 1:{qid}'.format( qid=qid, ) in info ] ) # delete APN AMBR class TrafficClass.delete_class(intf, 2) # verify that parent class is removed class_output = subprocess.check_output(['tc', 'class', 'show', 'dev', intf]) class_list = class_output.decode('utf-8').split("\n") assert( not [ info for info in class_list if 'class htb 1:{qid}'.format( qid=parent_qid, ) in info ] ) # check if no fq_codel nor filter exists qdisc_output = subprocess.check_output(['tc', 'qdisc', 'show', 'dev', intf]) filter_output = subprocess.check_output(['tc', 'filter', 'show', 'dev', intf]) filter_list = filter_output.decode('utf-8').split("\n") filter_list = [ln for ln in filter_list if 'classid' in ln] qdisc_list = qdisc_output.decode('utf-8').split("\n") qdisc_list = [ln for ln in qdisc_list if 'fq_codel' in ln] assert(not filter_list and not qdisc_list) # destroy all qos on intf run_cmd(['tc qdisc del dev {intf} root'.format(intf=intf)])
def testSudoUser(self, _, mock_check_call): TrafficClass.init_qdisc("eth0") mock_check_call.assert_any_call( ["sudo", "tc", "qdisc", "add", "dev", "eth0", "root", "handle", "1:", "htb"] )
def testSudoUser(self, _, mock_check_call): TrafficClass.init_qdisc("en0") mock_check_call.assert_any_call([ 'sudo', 'tc', 'qdisc', 'add', 'dev', 'en0', 'root', 'handle', '1:', 'htb' ])