diff --git a/Makefile b/Makefile index b19ba1b..f5b694b 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ .PHONY: format-check format-check: @echo "Checking format..." - python -m black --check src/ ptf + python -m black --check src/ ptf_nn/ example/ utests/ ptf --exclude [a-z]-nnpy.py .PHONY: format format: @echo "Formatting..." - python -m black src/ ptf + python -m black --check src/ ptf_nn/ example/ utests/ ptf --exclude [a-z]-nnpy.py .PHONY: set-dev set-dev: diff --git a/example/mytests/sai_base_test.py b/example/mytests/sai_base_test.py index 1a2b0a7..79079c3 100644 --- a/example/mytests/sai_base_test.py +++ b/example/mytests/sai_base_test.py @@ -23,19 +23,19 @@ from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol -class SAIThriftTest(BaseTest): +class SAIThriftTest(BaseTest): def setUp(self): BaseTest.setUp(self) test_params = testutils.test_params_get() - print - print "You specified the following test-params when invoking ptf:" - for k, v in test_params.items(): - print k, ":\t\t\t", v + print() + print("You specified the following test-params when invoking ptf:") + for k, v in list(test_params.items()): + print(k, ":\t\t\t", v) # Set up thrift client and contact server - self.transport = TSocket.TSocket('localhost', 9092) + self.transport = TSocket.TSocket("localhost", 9092) self.transport = TTransport.TBufferedTransport(self.transport) self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) @@ -46,8 +46,8 @@ def tearDown(self): BaseTest.tearDown(self) self.transport.close() -class SAIThriftDataplaneTest(SAIThriftTest): +class SAIThriftDataplaneTest(SAIThriftTest): def setUp(self): SAIThriftTest.setUp(self) diff --git a/example/mytests/switch.py b/example/mytests/switch.py index cb67669..39a7d1f 100644 --- a/example/mytests/switch.py +++ b/example/mytests/switch.py @@ -24,15 +24,16 @@ from ptf.testutils import * -from switch_sai_thrift.ttypes import * +from switch_sai_thrift.ttypes import * from ptf.mask import Mask -switch_inited=0 +switch_inited = 0 port_list = [] table_attr_list = [] -def verify_packet_list_any(test, pkt_list, ofport_list): + +def verify_packet_list_any(test, pkt_list, ofport_list): logging.debug("Checking for packet on given ports") (rcv_device, rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(timeout=1) test.assertTrue(rcv_pkt != None, "No packet received") @@ -41,13 +42,14 @@ def verify_packet_list_any(test, pkt_list, ofport_list): match_found = 0 for ofport in ofport_list: pkt = pkt_list[i] - if ((str(rcv_pkt) == str(pkt)) and (ofport == rcv_port)): + if (str(rcv_pkt) == str(pkt)) and (ofport == rcv_port): match_index = i match_found = 1 i = i + 1 test.assertTrue(match_found == 1, "Packet not received on expected port") return match_index + def switch_init(client): global switch_inited if switch_inited: @@ -57,81 +59,103 @@ def switch_init(client): attr_list = switch_attr_list.attr_list for attribute in attr_list: if attribute.id == 0: - print "max ports: " + attribute.value.u32 + print("max ports: " + attribute.value.u32) elif attribute.id == 1: for x in attribute.value.objlist.object_id_list: port_list.append(x) else: - print "unknown switch attribute" + print("unknown switch attribute") - attr_value = sai_thrift_attribute_value_t(mac='00:77:66:55:44:33') + attr_value = sai_thrift_attribute_value_t(mac="00:77:66:55:44:33") attr = sai_thrift_attribute_t(id=22, value=attr_value) client.sai_thrift_set_switch_attribute(attr) switch_inited = 1 + def sai_thrift_create_fdb(client, vlan_id, mac, port, mac_action): fdb_entry = sai_thrift_fdb_entry_t(mac_address=mac, vlan_id=vlan_id) - #value 0 represents static entry, id=0, represents entry type + # value 0 represents static entry, id=0, represents entry type fdb_attribute1_value = sai_thrift_attribute_value_t(u8=1) fdb_attribute1 = sai_thrift_attribute_t(id=0, value=fdb_attribute1_value) - #value oid represents object id, id=1 represents port id + # value oid represents object id, id=1 represents port id fdb_attribute2_value = sai_thrift_attribute_value_t(oid=port) fdb_attribute2 = sai_thrift_attribute_t(id=1, value=fdb_attribute2_value) - #value oid represents object id, id=1 represents port id + # value oid represents object id, id=1 represents port id fdb_attribute3_value = sai_thrift_attribute_value_t(u8=mac_action) fdb_attribute3 = sai_thrift_attribute_t(id=2, value=fdb_attribute3_value) fdb_attr_list = [fdb_attribute1, fdb_attribute2, fdb_attribute3] - client.sai_thrift_create_fdb_entry(thrift_fdb_entry=fdb_entry, thrift_attr_list=fdb_attr_list) + client.sai_thrift_create_fdb_entry( + thrift_fdb_entry=fdb_entry, thrift_attr_list=fdb_attr_list + ) + def sai_thrift_delete_fdb(client, vlan_id, mac, port): fdb_entry = sai_thrift_fdb_entry_t(mac_address=mac, vlan_id=vlan_id) client.sai_thrift_delete_fdb_entry(thrift_fdb_entry=fdb_entry) + def sai_thrift_create_virtual_router(client, v4_enabled, v6_enabled): - #v4 enabled + # v4 enabled vr_attribute1_value = sai_thrift_attribute_value_t(booldata=v4_enabled) vr_attribute1 = sai_thrift_attribute_t(id=0, value=vr_attribute1_value) - #v6 enabled + # v6 enabled vr_attribute2_value = sai_thrift_attribute_value_t(booldata=v6_enabled) vr_attribute2 = sai_thrift_attribute_t(id=1, value=vr_attribute1_value) vr_attr_list = [vr_attribute1, vr_attribute2] vr_id = client.sai_thrift_create_virtual_router(thrift_attr_list=vr_attr_list) return vr_id -def sai_thrift_create_router_interface(client, vr_id, is_port, port_id, vlan_id, v4_enabled, v6_enabled, mac): - #vrf attribute + +def sai_thrift_create_router_interface( + client, vr_id, is_port, port_id, vlan_id, v4_enabled, v6_enabled, mac +): + # vrf attribute rif_attribute1_value = sai_thrift_attribute_value_t(oid=vr_id) rif_attribute1 = sai_thrift_attribute_t(id=0, value=rif_attribute1_value) if is_port: - #port type and port id + # port type and port id rif_attribute2_value = sai_thrift_attribute_value_t(u8=0) rif_attribute2 = sai_thrift_attribute_t(id=1, value=rif_attribute2_value) rif_attribute3_value = sai_thrift_attribute_value_t(oid=port_id) rif_attribute3 = sai_thrift_attribute_t(id=2, value=rif_attribute3_value) else: - #vlan type and vlan id + # vlan type and vlan id rif_attribute2_value = sai_thrift_attribute_value_t(u8=1) rif_attribute2 = sai_thrift_attribute_t(id=1, value=rif_attribute2_value) rif_attribute3_value = sai_thrift_attribute_value_t(u16=vlan_id) rif_attribute3 = sai_thrift_attribute_t(id=3, value=rif_attribute3_value) - #v4_enabled + # v4_enabled rif_attribute4_value = sai_thrift_attribute_value_t(booldata=v4_enabled) rif_attribute4 = sai_thrift_attribute_t(id=5, value=rif_attribute4_value) - #v6_enabled + # v6_enabled rif_attribute5_value = sai_thrift_attribute_value_t(booldata=v6_enabled) rif_attribute5 = sai_thrift_attribute_t(id=6, value=rif_attribute5_value) if mac: rif_attribute6_value = sai_thrift_attribute_value_t(mac=mac) rif_attribute6 = sai_thrift_attribute_t(id=4, value=rif_attribute6_value) - rif_attr_list = [rif_attribute1, rif_attribute2, rif_attribute3, rif_attribute4, rif_attribute5, rif_attribute6] + rif_attr_list = [ + rif_attribute1, + rif_attribute2, + rif_attribute3, + rif_attribute4, + rif_attribute5, + rif_attribute6, + ] else: - rif_attr_list = [rif_attribute1, rif_attribute2, rif_attribute3, rif_attribute4, rif_attribute5] + rif_attr_list = [ + rif_attribute1, + rif_attribute2, + rif_attribute3, + rif_attribute4, + rif_attribute5, + ] rif_id = client.sai_thrift_create_router_interface(rif_attr_list) return rif_id + def sai_thrift_create_route(client, vr_id, addr_family, ip_addr, ip_mask, nhop): if addr_family == 0: addr = sai_thrift_ip_t(ip4=ip_addr) @@ -145,7 +169,10 @@ def sai_thrift_create_route(client, vr_id, addr_family, ip_addr, ip_mask, nhop): route_attribute1 = sai_thrift_attribute_t(id=2, value=route_attribute1_value) route = sai_thrift_unicast_route_entry_t(vr_id, ip_prefix) route_attr_list = [route_attribute1] - client.sai_thrift_create_route(thrift_unicast_route_entry=route, thrift_attr_list=route_attr_list) + client.sai_thrift_create_route( + thrift_unicast_route_entry=route, thrift_attr_list=route_attr_list + ) + def sai_thrift_remove_route(client, vr_id, addr_family, ip_addr, ip_mask, nhop): if addr_family == 0: @@ -159,6 +186,7 @@ def sai_thrift_remove_route(client, vr_id, addr_family, ip_addr, ip_mask, nhop): route = sai_thrift_unicast_route_entry_t(vr_id, ip_prefix) client.sai_thrift_remove_route(thrift_unicast_route_entry=route) + def sai_thrift_create_nhop(client, addr_family, ip_addr, rif_id): if addr_family == 0: addr = sai_thrift_ip_t(ip4=ip_addr) @@ -174,6 +202,7 @@ def sai_thrift_create_nhop(client, addr_family, ip_addr, rif_id): nhop = client.sai_thrift_create_next_hop(thrift_attr_list=nhop_attr_list) return nhop + def sai_thrift_create_neighbor(client, addr_family, rif_id, ip_addr, dmac): if addr_family == 0: addr = sai_thrift_ip_t(ip4=ip_addr) @@ -187,6 +216,7 @@ def sai_thrift_create_neighbor(client, addr_family, rif_id, ip_addr, dmac): neighbor_entry = sai_thrift_neighbor_entry_t(rif_id=rif_id, ip_address=ipaddr) client.sai_thrift_create_neighbor_entry(neighbor_entry, neighbor_attr_list) + def sai_thrift_remove_neighbor(client, addr_family, rif_id, ip_addr, dmac): if addr_family == 0: addr = sai_thrift_ip_t(ip4=ip_addr) @@ -197,42 +227,61 @@ def sai_thrift_remove_neighbor(client, addr_family, rif_id, ip_addr, dmac): neighbor_entry = sai_thrift_neighbor_entry_t(rif_id=rif_id, ip_address=ipaddr) client.sai_thrift_remove_neighbor_entry(neighbor_entry) + def sai_thrift_create_next_hop_group(client, nhop_list): nhop_group_attribute1_value = sai_thrift_attribute_value_t(u8=0) - nhop_group_attribute1 = sai_thrift_attribute_t(id=1, value=nhop_group_attribute1_value) - nhop_objlist = sai_thrift_object_list_t(count=len(nhop_list), object_id_list=nhop_list) + nhop_group_attribute1 = sai_thrift_attribute_t( + id=1, value=nhop_group_attribute1_value + ) + nhop_objlist = sai_thrift_object_list_t( + count=len(nhop_list), object_id_list=nhop_list + ) nhop_group_attribute2_value = sai_thrift_attribute_value_t(objlist=nhop_objlist) - nhop_group_attribute2 = sai_thrift_attribute_t(id=2, value=nhop_group_attribute2_value) + nhop_group_attribute2 = sai_thrift_attribute_t( + id=2, value=nhop_group_attribute2_value + ) nhop_group_attr_list = [nhop_group_attribute1, nhop_group_attribute2] - nhop_group = client.sai_thrift_create_next_hop_group(thrift_attr_list=nhop_group_attr_list) + nhop_group = client.sai_thrift_create_next_hop_group( + thrift_attr_list=nhop_group_attr_list + ) return nhop_group + def sai_thrift_create_lag(client, port_list): - lag_port_list = sai_thrift_object_list_t(count=len(port_list), object_id_list=port_list) + lag_port_list = sai_thrift_object_list_t( + count=len(port_list), object_id_list=port_list + ) lag1_attr_value = sai_thrift_attribute_value_t(objlist=lag_port_list) lag1_attr = sai_thrift_attribute_t(id=0, value=lag1_attr_value) lag_attr_list = [lag1_attr] lag = client.sai_thrift_create_lag(lag_attr_list) return lag + def sai_thrift_create_stp_entry(client, vlan_list): - vlanlist=sai_thrift_vlan_list_t(vlan_count=len(vlan_list), vlan_list=vlan_list) + vlanlist = sai_thrift_vlan_list_t(vlan_count=len(vlan_list), vlan_list=vlan_list) stp_attribute1_value = sai_thrift_attribute_value_t(vlanlist=vlanlist) stp_attribute1 = sai_thrift_attribute_t(id=0, value=stp_attribute1_value) stp_attr_list = [stp_attribute1] stp_id = client.sai_thrift_create_stp_entry(stp_attr_list) return stp_id + def sai_thrift_create_hostif_trap_group(client, queue_id, priority): attribute1_value = sai_thrift_attribute_value_t(u32=priority) attribute1 = sai_thrift_attribute_t(id=1, value=attribute1_value) attribute2_value = sai_thrift_attribute_value_t(u32=queue_id) attribute2 = sai_thrift_attribute_t(id=2, value=attribute2_value) attr_list = [attribute1, attribute2] - trap_group_id = client.sai_thrift_create_hostif_trap_group(thrift_attr_list=attr_list) + trap_group_id = client.sai_thrift_create_hostif_trap_group( + thrift_attr_list=attr_list + ) return trap_group_id -def sai_thrift_create_hostif_trap(client, trap_id, action, priority, channel, trap_group_id): + +def sai_thrift_create_hostif_trap( + client, trap_id, action, priority, channel, trap_group_id +): attribute3_value = sai_thrift_attribute_value_t(u32=channel) attribute3 = sai_thrift_attribute_t(id=2, value=attribute3_value) client.sai_thrift_set_hostif_trap(trap_id, attribute3) @@ -246,6 +295,7 @@ def sai_thrift_create_hostif_trap(client, trap_id, action, priority, channel, tr attribute2 = sai_thrift_attribute_t(id=1, value=attribute2_value) client.sai_thrift_set_hostif_trap(trap_id, attribute2) + def sai_thrift_create_hostif(client, rif_or_port_id, intf_name): attribute1_value = sai_thrift_attribute_value_t(u32=0) attribute1 = sai_thrift_attribute_t(id=0, value=attribute1_value) @@ -257,16 +307,17 @@ def sai_thrift_create_hostif(client, rif_or_port_id, intf_name): hif_id = client.sai_thrift_create_hostif(attr_list) return hif_id + class L2AccessToAccessVlanTest(sai_base_test.SAIThriftDataplaneTest): def runTest(self): - print - print "Sending L2 packet port 1 -> port 2 [access vlan=10])" + print() + print("Sending L2 packet port 1 -> port 2 [access vlan=10])") switch_init(self.client) vlan_id = 10 port1 = port_list[1] port2 = port_list[2] - mac1 = '00:11:11:11:11:11' - mac2 = '00:22:22:22:22:22' + mac1 = "00:11:11:11:11:11" + mac2 = "00:22:22:22:22:22" mac_action = 1 self.client.sai_thrift_create_vlan(vlan_id) @@ -277,11 +328,13 @@ def runTest(self): sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) - pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - ip_id=101, - ip_ttl=64) + pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + ip_id=101, + ip_ttl=64, + ) try: # in tuple: 0 is device number, 2 is port number @@ -295,22 +348,25 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_ports_from_vlan( + vlan_id, [vlan_port1, vlan_port2] + ) self.client.sai_thrift_delete_vlan(vlan_id) -#illustrates how to put test in a group + +# illustrates how to put test in a group @group("group_1") # illustrates how to disable a test @disabled class L2AccessToTrunkVlanTest(sai_base_test.SAIThriftDataplaneTest): def runTest(self): - print "Sending L2 packet - port 1 -> port 2 [trunk vlan=10])" + print("Sending L2 packet - port 1 -> port 2 [trunk vlan=10])") switch_init(self.client) vlan_id = 10 port1 = port_list[1] port2 = port_list[2] - mac1 = '00:11:11:11:11:11' - mac2 = '00:22:22:22:22:22' + mac1 = "00:11:11:11:11:11" + mac2 = "00:22:22:22:22:22" mac_action = 1 self.client.sai_thrift_create_vlan(vlan_id) @@ -321,19 +377,23 @@ def runTest(self): sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) - pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - ip_id=102, - ip_ttl=64) - exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - dl_vlan_enable=True, - vlan_vid=10, - ip_id=102, - ip_ttl=64, - pktlen=104) + pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + ip_id=102, + ip_ttl=64, + ) + exp_pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + dl_vlan_enable=True, + vlan_vid=10, + ip_id=102, + ip_ttl=64, + pktlen=104, + ) try: send_packet(self, 2, pkt) verify_packets(self, exp_pkt, [1]) @@ -341,19 +401,22 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_ports_from_vlan( + vlan_id, [vlan_port1, vlan_port2] + ) self.client.sai_thrift_delete_vlan(vlan_id) + @group("group_1") class L2AccessToTrunkVlanTest_Mask(sai_base_test.SAIThriftDataplaneTest): def runTest(self): - print "Sending L2 packet - port 1 -> port 2 [trunk vlan=10])" + print("Sending L2 packet - port 1 -> port 2 [trunk vlan=10])") switch_init(self.client) vlan_id = 10 port1 = port_list[1] port2 = port_list[2] - mac1 = '00:11:11:11:11:11' - mac2 = '00:22:22:22:22:22' + mac1 = "00:11:11:11:11:11" + mac2 = "00:22:22:22:22:22" mac_action = 1 self.client.sai_thrift_create_vlan(vlan_id) @@ -364,23 +427,27 @@ def runTest(self): sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) - pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - ip_id=102, - ip_ttl=64) - exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - dl_vlan_enable=True, - vlan_vid=10, - ip_id=102, - ip_ttl=64, - pktlen=104) + pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + ip_id=102, + ip_ttl=64, + ) + exp_pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + dl_vlan_enable=True, + vlan_vid=10, + ip_id=102, + ip_ttl=64, + pktlen=104, + ) # illustrates how to use a mask even if no impact here m = Mask(exp_pkt) - m.set_do_not_care_packet(IP, 'ttl') + m.set_do_not_care_packet(IP, "ttl") try: send_packet(self, 2, pkt) verify_packets(self, m, [1]) @@ -388,21 +455,24 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_ports_from_vlan( + vlan_id, [vlan_port1, vlan_port2] + ) self.client.sai_thrift_delete_vlan(vlan_id) + @group("group_1") @group("group_2") class L2TrunkToAccessVlanTest(sai_base_test.SAIThriftDataplaneTest): def runTest(self): - print - print "Sending L2 packet - port 1 -> port 2 [trunk vlan=10])" + print() + print("Sending L2 packet - port 1 -> port 2 [trunk vlan=10])") switch_init(self.client) vlan_id = 10 port1 = port_list[1] port2 = port_list[2] - mac1 = '00:11:11:11:11:11' - mac2 = '00:22:22:22:22:22' + mac1 = "00:11:11:11:11:11" + mac2 = "00:22:22:22:22:22" mac_action = 1 self.client.sai_thrift_create_vlan(vlan_id) @@ -413,19 +483,23 @@ def runTest(self): sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) - pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - dl_vlan_enable=True, - vlan_vid=10, - ip_dst='10.0.0.1', - ip_id=102, - ip_ttl=64) - exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', - eth_src='00:22:22:22:22:22', - ip_dst='10.0.0.1', - ip_id=102, - ip_ttl=64, - pktlen=96) + pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + dl_vlan_enable=True, + vlan_vid=10, + ip_dst="10.0.0.1", + ip_id=102, + ip_ttl=64, + ) + exp_pkt = simple_tcp_packet( + eth_dst="00:11:11:11:11:11", + eth_src="00:22:22:22:22:22", + ip_dst="10.0.0.1", + ip_id=102, + ip_ttl=64, + pktlen=96, + ) try: send_packet(self, 2, pkt) verify_packets(self, exp_pkt, [1]) @@ -433,6 +507,7 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_ports_from_vlan( + vlan_id, [vlan_port1, vlan_port2] + ) self.client.sai_thrift_delete_vlan(vlan_id) - diff --git a/ptf_nn/ptf_nn_agent.py b/ptf_nn/ptf_nn_agent.py index 2ecb121..b799e66 100644 --- a/ptf_nn/ptf_nn_agent.py +++ b/ptf_nn/ptf_nn_agent.py @@ -26,6 +26,7 @@ import time import struct import socket + try: import nnpy except ImportError: @@ -40,63 +41,71 @@ # copied from ptf.netutils # From bits/ioctls.h -SIOCGIFHWADDR = 0x8927 # Get hardware address -SIOCGIFINDEX = 0x8933 # name -> if_index mapping -SIOCGIFFLAGS = 0x8913 # get the active flag word of the device -SIOCSIFFLAGS = 0x8914 # set the active flag word of the device -IFF_UP = 0x0001 +SIOCGIFHWADDR = 0x8927 # Get hardware address +SIOCGIFINDEX = 0x8933 # name -> if_index mapping +SIOCGIFFLAGS = 0x8913 # get the active flag word of the device +SIOCSIFFLAGS = 0x8914 # set the active flag word of the device +IFF_UP = 0x0001 + def get_if(iff, cmd): s = socket.socket() - ifreq = ioctl(s, cmd, struct.pack("16s16x",iff.encode("utf-8"))) + ifreq = ioctl(s, cmd, struct.pack("16s16x", iff.encode("utf-8"))) s.close() return ifreq + def get_if_index(iff): return int(struct.unpack("I", get_if(iff, SIOCGIFINDEX)[16:20])[0]) + def get_mac(iff): - return ':'.join( - ['%02x' % char for char in bytearray(get_if(iff, SIOCGIFHWADDR)[18:24])]) + return ":".join( + ["%02x" % char for char in bytearray(get_if(iff, SIOCGIFHWADDR)[18:24])] + ) + def set_if_status(iff, status): s = socket.socket() - ifr = struct.pack('16sh', iff.encode("utf-8"), 0) + ifr = struct.pack("16sh", iff.encode("utf-8"), 0) result = ioctl(s, SIOCGIFFLAGS, ifr) - flags = struct.unpack('16sh', result)[1] + flags = struct.unpack("16sh", result)[1] if status: - flags |= IFF_UP + flags |= IFF_UP else: - flags &= ~IFF_UP - ifr = struct.pack('16sh', iff.encode("utf-8"), flags) + flags &= ~IFF_UP + ifr = struct.pack("16sh", iff.encode("utf-8"), flags) ioctl(s, SIOCSIFFLAGS, ifr) s.close() + def get_if_status(iff): try: s = socket.socket() - ifr = struct.pack('16sh', iff.encode("utf-8"), 0) + ifr = struct.pack("16sh", iff.encode("utf-8"), 0) result = ioctl(s, SIOCGIFFLAGS, ifr) s.close() except IOError: return False - flags = struct.unpack('16sh', result)[1] + flags = struct.unpack("16sh", result)[1] return flags & IFF_UP > 0 + def if_exists(iff): - ifaces = os.listdir('/sys/class/net') + ifaces = os.listdir("/sys/class/net") return iff in ifaces + # Taken from ptf parser class ActionInterface(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): # Parse --interface def check_interface(value): try: - dev_and_port, interface = value.split('@', 1) + dev_and_port, interface = value.split("@", 1) dev_and_port = dev_and_port.split("-") if len(dev_and_port) == 1: dev, port = 0, int(dev_and_port[0]) @@ -105,12 +114,16 @@ def check_interface(value): else: raise ValueError("") except ValueError: - parser.error("incorrect interface syntax (got %s, expected 'port@interface' or 'device-port@interface')" % repr(value)) + parser.error( + "incorrect interface syntax (got %s, expected 'port@interface' or 'device-port@interface')" + % repr(value) + ) return (dev, port, interface) - assert(type(values) is str) + assert type(values) is str getattr(namespace, self.dest).append(check_interface(values)) + class ActionDeviceSocket(argparse.Action): def __init__(self, *args, **kwargs): super(ActionDeviceSocket, self).__init__(*args, **kwargs) @@ -120,10 +133,13 @@ def __call__(self, parser, namespace, values, option_string=None): # Parse --device-socket def check_device_socket(value): try: - dev, addr = value.split('@', 1) + dev, addr = value.split("@", 1) dev = int(dev) except ValueError: - parser.error("incorrect device-socket syntax (got %s, expected something of the form @)" % repr(value)) + parser.error( + "incorrect device-socket syntax (got %s, expected something of the form @)" + % repr(value) + ) if dev in self.devices_observed: parser.error("cannot specify the same device twice") else: @@ -136,45 +152,78 @@ def check_device_socket(value): parser.error("nanomsg address must start with 'ipc://' or 'tcp://'") return (dev, addr) - assert(type(values) is str) + assert type(values) is str getattr(namespace, self.dest).append(check_device_socket(values)) -parser = argparse.ArgumentParser(description='PTF Nanomsg agent') + +parser = argparse.ArgumentParser(description="PTF Nanomsg agent") parser.add_argument( - "--device-socket", type=str, dest="device_sockets", - metavar="DEVICE-SOCKET", action=ActionDeviceSocket, default=[], - help="Specify the nanomsg socket to use to send / receive packets for a given device, as well as the ports to enable on the device.May be given multiple times. Example: 0@") + "--device-socket", + type=str, + dest="device_sockets", + metavar="DEVICE-SOCKET", + action=ActionDeviceSocket, + default=[], + help="Specify the nanomsg socket to use to send / receive packets for a given device, as well as the ports to enable on the device.May be given multiple times. Example: 0@", +) parser.add_argument( - "--interface", "-i", type=str, dest="interfaces", - metavar="INTERFACE", action=ActionInterface, default=[], - help="Specify a port number and the dataplane interface to use. May be given multiple times. Example: 0-1@eth2 (use eth2 as port 1 of device 0)") + "--interface", + "-i", + type=str, + dest="interfaces", + metavar="INTERFACE", + action=ActionInterface, + default=[], + help="Specify a port number and the dataplane interface to use. May be given multiple times. Example: 0-1@eth2 (use eth2 as port 1 of device 0)", +) parser.add_argument( - "--verbose", "-v", dest="verbose", action='store_true', - help="Specify if you need verbose output") + "--verbose", + "-v", + dest="verbose", + action="store_true", + help="Specify if you need verbose output", +) parser.add_argument( - "--set-nn-rcv-buffer", type=int, dest="nn_rcv_buf", - metavar="BUFFER_SIZE", default=0, - help="Specify a nanomsg socket receive buffer size") + "--set-nn-rcv-buffer", + type=int, + dest="nn_rcv_buf", + metavar="BUFFER_SIZE", + default=0, + help="Specify a nanomsg socket receive buffer size", +) parser.add_argument( - "--set-nn-snd-buffer", type=int, dest="nn_snd_buf", - metavar="BUFFER_SIZE", default=0, - help="Specify a nanomsg socket send buffer size") + "--set-nn-snd-buffer", + type=int, + dest="nn_snd_buf", + metavar="BUFFER_SIZE", + default=0, + help="Specify a nanomsg socket send buffer size", +) parser.add_argument( - "--set-iface-rcv-buffer", type=int, dest="iface_rcv_buf", - metavar="BUFFER_SIZE", default=0, - help="Specify an interface socket receive buffer size") + "--set-iface-rcv-buffer", + type=int, + dest="iface_rcv_buf", + metavar="BUFFER_SIZE", + default=0, + help="Specify an interface socket receive buffer size", +) parser.add_argument( - "--set-iface-snd-buffer", type=int, dest="iface_snd_buf", - metavar="BUFFER_SIZE", default=0, - help="Specify an interface socket send buffer size") + "--set-iface-snd-buffer", + type=int, + dest="iface_snd_buf", + metavar="BUFFER_SIZE", + default=0, + help="Specify an interface socket send buffer size", +) args = parser.parse_args() iface_mgrs = {} nano_mgrs = {} -logging.basicConfig(format='%(message)s') -logger = logging.getLogger('ptf_nn_agent') +logging.basicConfig(format="%(message)s") +logger = logging.getLogger("ptf_nn_agent") + class IfaceMgr(threading.Thread): def __init__(self, dev, port, iface_name, iface_rcv_buf=0, iface_snd_buf=0): @@ -195,8 +244,11 @@ def forward(self, p): self.tx_ctr += 1 def received(self, p): - logger.debug("IfaceMgr {}-{} ({}) received a packet".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) received a packet".format( + self.dev, self.port, self.iface_name + ) + ) if self.dev in nano_mgrs: nano_mgr = nano_mgrs[self.dev] nano_mgr.forward(p, self.port) @@ -215,13 +267,19 @@ def get_ctrs(self): def port_up(self): set_if_status(self.iface_name, True) - logger.debug("IfaceMgr {}-{} ({}) status set to UP".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) status set to UP".format( + self.dev, self.port, self.iface_name + ) + ) def port_down(self): set_if_status(self.iface_name, False) - logger.debug("IfaceMgr {}-{} ({}) status set to DOWN".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) status set to DOWN".format( + self.dev, self.port, self.iface_name + ) + ) def wait_if_ready(self): """ @@ -234,12 +292,18 @@ def wait_if_ready(self): if if_exists(self.iface_name) and get_if_status(self.iface_name): self.ready = True break - logger.debug("IfaceMgr {}-{} ({}) status is DOWN".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) status is DOWN".format( + self.dev, self.port, self.iface_name + ) + ) time.sleep(1) - logger.debug("IfaceMgr {}-{} ({}) status changed to UP".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) status changed to UP".format( + self.dev, self.port, self.iface_name + ) + ) def is_ready(self): return self.ready @@ -250,24 +314,35 @@ def run(self): while True: self.wait_if_ready() try: - self.socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, - socket.htons(0x03)) + self.socket = socket.socket( + socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x03) + ) afpacket.enable_auxdata(self.socket) if self.iface_rcv_buf != 0: - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.iface_rcv_buf) + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_RCVBUF, self.iface_rcv_buf + ) - if self.iface_snd_buf != 0: - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, self.iface_snd_buf) + if self.iface_snd_buf != 0: + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_SNDBUF, self.iface_snd_buf + ) self.socket.bind((self.iface_name, 0)) - logger.debug("IfaceMgr {}-{} ({}) AF_PACKET socket is open".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) AF_PACKET socket is open".format( + self.dev, self.port, self.iface_name + ) + ) while True: msg = afpacket.recv(self.socket, 4096) self.received(msg) except (socket.error, RuntimeError) as err: - logger.debug("IfaceMgr {}-{} ({}) Error reading from the socket.".format( - self.dev, self.port, self.iface_name)) + logger.debug( + "IfaceMgr {}-{} ({}) Error reading from the socket.".format( + self.dev, self.port, self.iface_name + ) + ) self.socket.close() @@ -302,8 +377,9 @@ def __init__(self, dev, socket_addr, nn_rcv_buf=0, nn_snd_buf=0): self.socket.bind(socket_addr) def forward(self, p, port): - msg = struct.pack(" counters_01_b[1]) self.assertTrue(counters_11_e[0] > counters_11_b[0]) + class VerifyAnyPacketAnyPort(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -91,7 +95,8 @@ def runTest(self): testutils.send_packet(self, (0, 1), pkt) print("packet sent") testutils.verify_any_packet_any_port( - self, pkts=[pkt], ports=[3, 1], device_number=1) + self, pkts=[pkt], ports=[3, 1], device_number=1 + ) # negative test: if the packet is indeed received, but not on one of the # expected ports, the test should fail @@ -99,20 +104,22 @@ def runTest(self): testutils.send_packet(self, (0, 1), pkt) print("packet sent") testutils.verify_any_packet_any_port( - self, pkts=[pkt], ports=[0, 2, 3], device_number=1) + self, pkts=[pkt], ports=[0, 2, 3], device_number=1 + ) print("Verify masked packets") pkt1 = testutils.simple_udp_packet(eth_dst="00:11:11:11:11:11") pkt2 = testutils.simple_udp_packet(eth_dst="00:22:22:22:22:22") exp_pkt = Mask(pkt2) - exp_pkt.set_do_not_care_packet(Ether, 'dst') + exp_pkt.set_do_not_care_packet(Ether, "dst") testutils.send_packet(self, (0, 1), pkt1) print("Packet sent") # pkt2 will not be received # pkt2 with masked eth_dst field will match testutils.verify_any_packet_any_port( - self, pkts=[pkt2, exp_pkt], ports=[0, 1], device_number=1) + self, pkts=[pkt2, exp_pkt], ports=[0, 1], device_number=1 + ) # negative tests with self.assertRaises(AssertionError): @@ -120,14 +127,17 @@ def runTest(self): print("Packet sent") # incorrect ports testutils.verify_any_packet_any_port( - self, pkts=[exp_pkt], ports=[0, 2, 3], device_number=1) + self, pkts=[exp_pkt], ports=[0, 2, 3], device_number=1 + ) with self.assertRaises(AssertionError): testutils.send_packet(self, (0, 1), pkt1) print("Packet sent") # incorrect packet testutils.verify_any_packet_any_port( - self, pkts=[pkt2], ports=[0, 1], device_number=1) + self, pkts=[pkt2], ports=[0, 1], device_number=1 + ) + class RemovePort(DataplaneBaseTest): def __init__(self): @@ -148,7 +158,7 @@ def runTest(self): # testing. In practice, you would not be removing ports which are part # of the original ptf config. def find_ifname(device_number, port_number): - for port_id, ifname in config["port_map"].items(): + for port_id, ifname in list(config["port_map"].items()): if (device_number, port_number) == port_id: return ifname @@ -164,6 +174,7 @@ def find_ifname(device_number, port_number): testutils.verify_packet(self, pkt, (1, 1)) testutils.verify_no_other_packets(self, 1) + class SimpleTcpPacketTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -177,6 +188,7 @@ def runTest(self): testutils.verify_packet(self, pkt, (1, 1)) testutils.verify_no_other_packets(self, 1) + class SimpleIpv4PacketTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -191,6 +203,7 @@ def runTest(self): testutils.verify_packet(self, pkt, (1, 1)) testutils.verify_no_other_packets(self, 1) + class SimpleIpv6PacketTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -204,6 +217,7 @@ def runTest(self): testutils.verify_packet(self, pkt, (1, 1)) testutils.verify_no_other_packets(self, 1) + class Ipv4InIpv4PacketTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -218,6 +232,7 @@ def runTest(self): testutils.verify_packet(self, pkt2, (1, 1)) testutils.verify_no_other_packets(self, 1) + class Ipv6InGREPacketTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -225,15 +240,16 @@ def __init__(self): def runTest(self): pktlen = 1000 udp = testutils.simple_udp_packet() - ipv6 = testutils.simple_ipv6ip_packet(inner_frame=udp['UDP']) + ipv6 = testutils.simple_ipv6ip_packet(inner_frame=udp["UDP"]) gre = testutils.simple_grev6_packet(pktlen=pktlen, inner_frame=ipv6["IPv6"]) - self.assertEqual(gre['GRE'].proto, 0x86DD) + self.assertEqual(gre["GRE"].proto, 0x86DD) testutils.send_packet(self, (0, 1), gre) print("packet sent") testutils.verify_packet(self, gre, (1, 1)) testutils.verify_no_other_packets(self, 1) + class VerifyPacketsOnMultiplePortListsTest(DataplaneBaseTest): def __init__(self): DataplaneBaseTest.__init__(self) @@ -248,7 +264,8 @@ def runTest(self): # pkt1 will be received on one of ports (0, 1) # pkt2 will be received on one of ports (1, 2, 3) testutils.verify_each_packet_on_multiple_port_lists( - self, pkts=[pkt1, pkt2], ports=[[0, 1], [1, 2, 3]], device_number=1) + self, pkts=[pkt1, pkt2], ports=[[0, 1], [1, 2, 3]], device_number=1 + ) # negative test with self.assertRaises(AssertionError): @@ -258,6 +275,5 @@ def runTest(self): # pkt1 will not be received on one of ports (0, 2, 3) # pkt1 will not be received on one of ports (1, 2, 3); it will be pkt2 testutils.verify_each_packet_on_multiple_port_lists( - self, pkts=[pkt1, pkt1], ports=[[0, 2, 3], [0, 1]], - device_number=1) - + self, pkts=[pkt1, pkt1], ports=[[0, 2, 3], [0, 1]], device_number=1 + ) diff --git a/ptf_nn/ptf_nn_test_bridge.py b/ptf_nn/ptf_nn_test_bridge.py index ab0e735..7bc680c 100644 --- a/ptf_nn/ptf_nn_test_bridge.py +++ b/ptf_nn/ptf_nn_test_bridge.py @@ -25,13 +25,14 @@ import scapy.all as sc import time -parser = argparse.ArgumentParser(description='PTF Nanomsg tester bridge') +parser = argparse.ArgumentParser(description="PTF Nanomsg tester bridge") parser.add_argument("-ifrom", type=str) parser.add_argument("-ito", type=str) args = parser.parse_args() forwarders = {} + class Forwarder(threading.Thread): def __init__(self, iface_name, other): threading.Thread.__init__(self) @@ -41,13 +42,14 @@ def __init__(self, iface_name, other): forwarders[iface_name] = self def forward(self, p): - print("forwarding", p, "---", self.other, "->", self.iface_name) + print(("forwarding", p, "---", self.other, "->", self.iface_name)) sc.sendp(p, iface=self.iface_name, verbose=0) def run(self): other_fwd = forwarders[self.other] sc.sniff(iface=self.iface_name, prn=lambda x: other_fwd.forward(x)) + def main(): f1 = Forwarder(args.ifrom, args.ito) f2 = Forwarder(args.ito, args.ifrom) @@ -60,5 +62,6 @@ def main(): except KeyboardInterrupt: return -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/ptf_nn/ptf_nn_test_eth.py b/ptf_nn/ptf_nn_test_eth.py index 2d03091..74e7ee3 100644 --- a/ptf_nn/ptf_nn_test_eth.py +++ b/ptf_nn/ptf_nn_test_eth.py @@ -23,18 +23,19 @@ import argparse import scapy.all as sc -parser = argparse.ArgumentParser(description='PTF Nanomsg tester 2') -parser.add_argument( - "--interface", type=str, dest="interface") -parser.add_argument( - "--receive", dest="receive", action='store_true', default=False) +parser = argparse.ArgumentParser(description="PTF Nanomsg tester 2") +parser.add_argument("--interface", type=str, dest="interface") +parser.add_argument("--receive", dest="receive", action="store_true", default=False) args = parser.parse_args() + def receive(interface): def printp(p): - print("Received:", p) + print(("Received:", p)) + sc.sniff(iface=interface, prn=lambda x: printp(x)) + def main(): if args.receive: receive(args.interface) @@ -42,5 +43,6 @@ def main(): p = "ab" * 20 sc.sendp(p, iface=args.interface, verbose=0) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/ptf_nn/ptf_nn_test_nn.py b/ptf_nn/ptf_nn_test_nn.py index bb3bddf..a1e9dbe 100644 --- a/ptf_nn/ptf_nn_test_nn.py +++ b/ptf_nn/ptf_nn_test_nn.py @@ -24,11 +24,9 @@ import struct import argparse -parser = argparse.ArgumentParser(description='PTF Nanomsg tester 1') -parser.add_argument( - "--socket", type=str, dest="socket") -parser.add_argument( - "--receive", dest="receive", action='store_true', default=False) +parser = argparse.ArgumentParser(description="PTF Nanomsg tester 1") +parser.add_argument("--socket", type=str, dest="socket") +parser.add_argument("--receive", dest="receive", action="store_true", default=False) args = parser.parse_args() MSG_TYPE_PORT_ADD = 0 @@ -37,6 +35,7 @@ MSG_TYPE_PACKET_IN = 3 MSG_TYPE_PACKET_OUT = 4 + def receive(socket): while True: msg = socket.recv() @@ -44,9 +43,10 @@ def receive(socket): msg_type, port_number, length = struct.unpack_from(fmt, msg) hdr_size = struct.calcsize(fmt) msg = msg[hdr_size:] - assert (msg_type == MSG_TYPE_PACKET_OUT) - assert (len(msg) == length) - print("Received:", msg) + assert msg_type == MSG_TYPE_PACKET_OUT + assert len(msg) == length + print(("Received:", msg)) + def main(): socket = nnpy.Socket(nnpy.AF_SP, nnpy.PAIR) @@ -56,11 +56,11 @@ def main(): else: # send one p = "ab" * 20 port = 1 - msg = struct.pack(">>None") else: - for k, v in params.items(): - print(">>>{}={}".format(k, v)) + for k, v in list(params.items()): + print((">>>{}={}".format(k, v))) + class TestParamGet(BaseTest): def setUp(self): BaseTest.setUp(self) def runTest(self): - v = testutils.test_param_get('k1', default=-1) + v = testutils.test_param_get("k1", default=-1) if v is None: print(">>>None") else: - print(">>>k1={}".format(v)) + print((">>>k1={}".format(v))) diff --git a/utests/tests/test.py b/utests/tests/test.py index 2a6cf00..f147692 100644 --- a/utests/tests/test.py +++ b/utests/tests/test.py @@ -2,6 +2,7 @@ import subprocess import unittest + class BaseTestCase(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -12,10 +13,13 @@ def setUp(self): def run_ptf(self, args=[], input=None): # redirect stderr to stdout so we can get error messages r = subprocess.run( - ['./ptf'] + args, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + ["./ptf"] + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, input=input, - universal_newlines=True) + universal_newlines=True, + ) return r.returncode, r.stdout def tearDown(self): @@ -25,30 +29,37 @@ def tearDown(self): class TestParamsTestCase(BaseTestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.testdir = 'utests/specs' + self.testdir = "utests/specs" def parse_params(self, out): params = {} for line in out.splitlines(): - if not line.startswith('>>>'): + if not line.startswith(">>>"): continue line = line[3:] if line == "None": return None - k, v = line.split('=') + k, v = line.split("=") params[k] = int(v) return params def do_test_params(self, testspec, test_params_str): rc, out = self.run_ptf( - args=['--test-dir', self.testdir, - '--test-params={}'.format(test_params_str), - '--platform', 'dummy', testspec]) + args=[ + "--test-dir", + self.testdir, + "--test-params={}".format(test_params_str), + "--platform", + "dummy", + testspec, + ] + ) self.assertEqual(rc, 0) return out - @nose2.tools.params(("k1=9;k2=18", {'k1':9, 'k2':18}), - ("k1=9;k2=18;", {'k1':9, 'k2':18})) + @nose2.tools.params( + ("k1=9;k2=18", {"k1": 9, "k2": 18}), ("k1=9;k2=18;", {"k1": 9, "k2": 18}) + ) def test_test_params_get(self, test_params_str, expected_params): testspec = "test.TestParamsGet" out = self.do_test_params(testspec, test_params_str) @@ -61,14 +72,12 @@ def test_test_params_get_error(self, test_params_str, expected_params): out = self.do_test_params(testspec, test_params_str) self.assertIn("Error when parsing test params", out) - @nose2.tools.params(("k1=9;k2=18", 9), - ("k1=9;k2=18;", 9), - ("k2=18", -1)) + @nose2.tools.params(("k1=9;k2=18", 9), ("k1=9;k2=18;", 9), ("k2=18", -1)) def test_test_param_get(self, test_params_str, expected_value): testspec = "test.TestParamGet" out = self.do_test_params(testspec, test_params_str) params = self.parse_params(out) - self.assertEqual(params['k1'], expected_value) + self.assertEqual(params["k1"], expected_value) @nose2.tools.params(("bad", None)) def test_test_param_get_error(self, test_params_str, expected_params):