def _add_tests(): import os import os.path import functools this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data') json_dir = os.path.join(this_dir, 'json') ofvers = [ 'of10', 'of12', 'of13', 'of14', 'of15', ] cases = set() for ver in ofvers: pdir = packet_data_dir + '/' + ver jdir = json_dir + '/' + ver n_added = 0 for file in os.listdir(pdir): if file.endswith('.packet'): truncated = None elif '.truncated' in file: # contents of .truncated files aren't relevant s1, s2 = file.split('.truncated') try: truncated = int(s2) except ValueError: continue file = s1 + '.packet' else: continue wire_msg = open(pdir + '/' + file, 'rb').read() if not truncated: json_str = open(jdir + '/' + file + '.json', 'r').read() else: json_str = open(jdir + '/' + file + '.truncated%d.json' % truncated, 'r').read() wire_msg = wire_msg[:truncated] method_name = ('test_' + file).replace('-', '_').replace('.', '_') if truncated: method_name += '_truncated%d' % truncated def _run(self, name, wire_msg, json_str): print('processing %s ...' % name) if six.PY3: self._test_msg(self, name, wire_msg, json_str) else: self._test_msg(name, wire_msg, json_str) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, wire_msg=wire_msg, json_str=json_str) test_lib.add_method(Test_Parser, method_name, f) cases.add(method_name) n_added += 1 assert n_added > 0 assert (cases == set(unittest.defaultTestLoader.getTestCaseNames(Test_Parser)))
def _add_tests_actions(cls): for act in cls.act_list: method_name = 'test_' + str(cls.ver) + '_' + act["type"] + '_action' def _run(self, name, act, cls): print('processing %s ...' % name) cls_ = Test_ofctl(name) cls_._test_actions(act, cls) print('adding %s ...' % method_name) func = functools.partial(_run, name=method_name, act=act, cls=cls) test_lib.add_method(Test_ofctl, method_name, func)
def _add_tests(): import os import os.path import functools this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, "../../packet_data") json_dir = os.path.join(this_dir, "json") ofvers = ["of10", "of12", "of13", "of14", "of15"] cases = set() for ver in ofvers: pdir = packet_data_dir + "/" + ver jdir = json_dir + "/" + ver n_added = 0 for file in os.listdir(pdir): if file.endswith(".packet"): truncated = None elif ".truncated" in file: # contents of .truncated files aren't relevant s1, s2 = file.split(".truncated") try: truncated = int(s2) except ValueError: continue file = s1 + ".packet" else: continue wire_msg = open(pdir + "/" + file, "rb").read() if not truncated: json_str = open(jdir + "/" + file + ".json", "r").read() else: json_str = open(jdir + "/" + file + ".truncated%d.json" % truncated, "r").read() wire_msg = wire_msg[:truncated] method_name = ("test_" + file).replace("-", "_").replace(".", "_") if truncated: method_name += "_truncated%d" % truncated def _run(self, name, wire_msg, json_str): print("processing %s ..." % name) if six.PY3: self._test_msg(self, name, wire_msg, json_str) else: self._test_msg(name, wire_msg, json_str) print("adding %s ..." % method_name) f = functools.partial(_run, name=method_name, wire_msg=wire_msg, json_str=json_str) test_lib.add_method(Test_Parser, method_name, f) cases.add(method_name) n_added += 1 assert n_added > 0 assert cases == set(unittest.defaultTestLoader.getTestCaseNames(Test_Parser))
def _add_tests_match(cls): for attr in cls.attr_list: for key, value in attr.items(): method_name = 'test_' + \ str(cls.ver) + '_' + key + '_' + str( value) + str(type(value)) + '_match' def _run(self, name, attr, cls): print('processing %s ...' % name) cls_ = Test_ofctl(name) cls_._test_match(attr, cls) print('adding %s ...' % method_name) func = functools.partial( _run, name=method_name, attr=attr, cls=cls) test_lib.add_method(Test_ofctl, method_name, func)
def _add_tests(): import functools import itertools ofpps = [ofproto_v1_2_parser, ofproto_v1_3_parser] for ofpp in ofpps: mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod + '_ofpmatch_compat' def _run(self, name, ofpp): print('processing %s ...' % name) self._test(name, ofpp) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, ofpp=ofpp) test_lib.add_method(Test_Parser_Compat, method_name, f)
def _add_tests(): import os import os.path import fnmatch import functools this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data') json_dir = os.path.join(this_dir, 'json') ofvers = [ 'of10', 'of12', 'of13', 'of14', 'of15', ] cases = set() for ver in ofvers: pdir = packet_data_dir + '/' + ver jdir = json_dir + '/' + ver n_added = 0 for file in os.listdir(pdir): if not fnmatch.fnmatch(file, '*.packet'): continue wire_msg = open(pdir + '/' + file, 'rb').read() json_str = open(jdir + '/' + file + '.json', 'r').read() method_name = ('test_' + file).replace('-', '_').replace('.', '_') def _run(self, name, wire_msg, json_str): print('processing %s ...' % name) if six.PY3: self._test_msg(self, name, wire_msg, json_str) else: self._test_msg(name, wire_msg, json_str) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, wire_msg=wire_msg, json_str=json_str) test_lib.add_method(Test_Parser, method_name, f) cases.add(method_name) n_added += 1 assert n_added > 0 assert (cases == set( unittest.defaultTestLoader.getTestCaseNames(Test_Parser)))
def _add_tests(): import os import os.path import fnmatch import functools this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data') json_dir = os.path.join(this_dir, 'json') ofvers = [ 'of10', 'of12', 'of13', 'of14', 'of15', ] cases = set() for ver in ofvers: pdir = packet_data_dir + '/' + ver jdir = json_dir + '/' + ver n_added = 0 for file in os.listdir(pdir): if not fnmatch.fnmatch(file, '*.packet'): continue wire_msg = open(pdir + '/' + file, 'rb').read() json_str = open(jdir + '/' + file + '.json', 'r').read() method_name = ('test_' + file).replace('-', '_').replace('.', '_') def _run(self, name, wire_msg, json_str): print('processing %s ...' % name) if six.PY3: self._test_msg(self, name, wire_msg, json_str) else: self._test_msg(name, wire_msg, json_str) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, wire_msg=wire_msg, json_str=json_str) test_lib.add_method(Test_Parser, method_name, f) cases.add(method_name) n_added += 1 assert n_added > 0 assert (cases == set(unittest.defaultTestLoader.getTestCaseNames(Test_Parser)))
def _add_tests(): _ofp_vers = { 'of10': ofproto_v1_0.OFP_VERSION, 'of12': ofproto_v1_2.OFP_VERSION, 'of13': ofproto_v1_3.OFP_VERSION, 'of14': ofproto_v1_4.OFP_VERSION, 'of15': ofproto_v1_5.OFP_VERSION, } this_dir = os.path.dirname(sys.modules[__name__].__file__) ofctl_rest_json_dir = os.path.join(this_dir, 'ofctl_rest_json/') for ofp_ver in _ofp_vers: # read a json file json_path = os.path.join(ofctl_rest_json_dir, ofp_ver + '.json') if os.path.exists(json_path): _test_cases = json.load(open(json_path)) else: # print("Skip to load test cases for %s" % ofp_ver) continue # add test for test in _test_cases: method = test['method'] path = test['path'] body = test.get('body', {}) name = 'test_ofctl_rest_' + method + '_' + ofp_ver + '_' + path # print('adding %s ...' % name) f = functools.partial( Test_ofctl_rest._test, name=name, dp=DummyDatapath(_ofp_vers[ofp_ver]), method=test['method'], path=test['path'], body=body ) test_lib.add_method(Test_ofctl_rest, name, f)
def _add_tests(): _ofp_vers = { 'of10': ofproto_v1_0.OFP_VERSION, 'of12': ofproto_v1_2.OFP_VERSION, 'of13': ofproto_v1_3.OFP_VERSION, 'of14': ofproto_v1_4.OFP_VERSION, 'of15': ofproto_v1_5.OFP_VERSION, } this_dir = os.path.dirname(sys.modules[__name__].__file__) ofctl_rest_json_dir = os.path.join(this_dir, 'ofctl_rest_json/') for ofp_ver in _ofp_vers.keys(): # read a json file json_path = os.path.join(ofctl_rest_json_dir, ofp_ver + '.json') if os.path.exists(json_path): _test_cases = json.load(open(json_path)) else: print("Skip to load test cases for %s" % ofp_ver) continue # add test for test in _test_cases: method = test['method'] path = test['path'] body = test.get('body', {}) name = 'test_ofctl_rest_' + method + '_' + ofp_ver + '_' + path print('adding %s ...' % name) f = functools.partial( Test_ofctl_rest._test, name=name, dp=DummyDatapath(_ofp_vers[ofp_ver]), method=test['method'], path=test['path'], body=body ) test_lib.add_method(Test_ofctl_rest, name, f)
def _add_tests(): import functools import itertools class Field(object): @classmethod def generate_mask(cls): return list(cls.generate())[1] class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ ofproto_v1_2_parser, ofproto_v1_3_parser, ofproto_v1_4_parser, ofproto_v1_5_parser ] common = [ # OpenFlow Basic ('in_port', Int4), ('in_phy_port', Int4), ('metadata', Int8), ('eth_dst', Mac), ('eth_src', Mac), ('eth_type', Int2), ('vlan_vid', Int2), ('vlan_pcp', Int1), ('ip_dscp', Int1), ('ip_ecn', Int1), ('ip_proto', Int1), ('ipv4_src', IPv4), ('ipv4_dst', IPv4), ('tcp_src', Int2), ('tcp_dst', Int2), ('udp_src', Int2), ('udp_dst', Int2), ('sctp_src', Int2), ('sctp_dst', Int2), ('icmpv4_type', Int1), ('icmpv4_code', Int1), ('arp_op', Int2), ('arp_spa', IPv4), ('arp_tpa', IPv4), ('arp_sha', Mac), ('arp_tha', Mac), ('ipv6_src', IPv6), ('ipv6_dst', IPv6), ('ipv6_flabel', Int4), ('icmpv6_type', Int1), ('icmpv6_code', Int1), ('ipv6_nd_target', IPv6), ('ipv6_nd_sll', Mac), ('ipv6_nd_tll', Mac), ('mpls_label', Int4), ('mpls_tc', Int1), # Old ONF Experimenter --> OpenFlow Basic (OF1.4+) ('pbb_uca', Int1), # ONF Experimenter --> OpenFlow Basic (OF1.5+) ('tcp_flags', Int2), ('actset_output', Int4), # Nicira Experimenter ('eth_dst_nxm', Mac), ('eth_src_nxm', Mac), ('tunnel_id_nxm', Int8), ('tun_ipv4_src', IPv4), ('tun_ipv4_dst', IPv4), ('pkt_mark', Int4), ('conj_id', Int4), ('_dp_hash', Int4), ('reg0', Int4), ('reg1', Int4), ('reg2', Int4), ('reg3', Int4), ('reg4', Int4), ('reg5', Int4), ('reg6', Int4), ('reg7', Int4), # Common Experimenter ('field_100', B64), ] L = {} L[ofproto_v1_2_parser] = common + [ # OF1.2 doesn't have OXM_OF_PBB_ISID. # OFPXMC_OPENFLOW_BASIC = 0x8000 # OXM_OF_PBB_ISID = 37 # (OFPXMC_OPENFLOW_BASIC << 7) + OXM_OF_PBB_ISID == 4194341 ('field_4194341', B64), ] L[ofproto_v1_3_parser] = common + [ # OpenFlow Basic (OF1.3+) ('mpls_bos', Int1), ('pbb_isid', Int3), ('tunnel_id', Int8), ('ipv6_exthdr', Int2), ] L[ofproto_v1_4_parser] = L[ofproto_v1_3_parser] L[ofproto_v1_5_parser] = L[ofproto_v1_4_parser] + [ # OpenFlow Basic (OF1.5+) ('packet_type', Int4), ] def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: reduce(flatten_one, l, []) for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = [flatten(x)[1:] for x in l] for domask in [True, False]: for values in l: if domask: values = [(value, cls.generate_mask()) for (cls, value) in zip(clss, values)] d = dict(zip(keys, values)) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod if domask: method_name += '_mask' for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') def _run(self, name, ofpp, d, domask): print('processing %s ...' % name) if six.PY3: self._test(self, name, ofpp, d, domask) else: self._test(name, ofpp, d, domask) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, ofpp=ofpp, d=d, domask=domask) test_lib.add_method(Test_Parser_OFPMatch, method_name, f)
def _add_tests(): import functools import itertools class Field(object): pass class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int4double(Field): @staticmethod def generate(): # Note: If yield value as a tuple, flatten_one() will reduce it # into a single value. So the followings avoid this problem by # using a list value. yield [0, 1] yield [0x12345678, 0x23456789] yield [0xffffffff, 0xfffffffe] class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ofproto_v1_5_parser] common = [ ('duration', Int4double), ('idle_time', Int4double), ('flow_count', Int4), ('packet_count', Int8), ('byte_count', Int8), ('field_100', B64), ] L = {} L[ofproto_v1_5_parser] = common def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: reduce(flatten_one, l, []) for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = map(lambda x: flatten(x)[1:], l) for values in l: d = dict(zip(keys, values)) for n, uv in d.items(): if isinstance(uv, list): # XXX # OFPStats returns value as tuple when field is # 'duration' or 'idle_time'. Then convert list # value into tuple here. d[n] = tuple(uv) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') def _run(self, name, ofpp, d): print('processing %s ...' % name) self._test(name, ofpp, d) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, ofpp=ofpp, d=d) test_lib.add_method(Test_Parser_OFPStats, method_name, f)
def _add_tests(): import os import os.path import functools this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data') json_dir = os.path.join(this_dir, 'json') ofvers = [ 'of10', 'of12', 'of13', 'of14', 'of15', ] cases = set() for ver in ofvers: pdir = packet_data_dir + '/' + ver jdir = json_dir + '/' + ver n_added = 0 for file in os.listdir(pdir): if file.endswith('.packet'): truncated = None elif '.truncated' in file: # contents of .truncated files aren't relevant s1, s2 = file.split('.truncated') try: truncated = int(s2) except ValueError: continue file = s1 + '.packet' else: continue wire_msg = open(pdir + '/' + file, 'rb').read() if not truncated: json_str = open(jdir + '/' + file + '.json', 'r').read() else: json_str = open( jdir + '/' + file + '.truncated%d.json' % truncated, 'r').read() wire_msg = wire_msg[:truncated] method_name = ('test_' + file).replace('-', '_').replace('.', '_') if truncated: method_name += '_truncated%d' % truncated def _run(self, name, wire_msg, json_str): print('processing %s ...' % name) if six.PY3: self._test_msg(self, name, wire_msg, json_str) else: self._test_msg(name, wire_msg, json_str) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, wire_msg=wire_msg, json_str=json_str) test_lib.add_method(Test_Parser, method_name, f) cases.add(method_name) n_added += 1 assert n_added > 0 assert (cases == set( unittest.defaultTestLoader.getTestCaseNames(Test_Parser)))
def _add_tests(): _ofp_vers = { 'of10': 0x01, 'of12': 0x03, 'of13': 0x04, 'of14': 0x05, } _test_cases = { 'of10': [ { 'method': ofctl_v1_0.mod_flow_entry, 'request': '1-2-ofp_flow_mod.packet.json', 'reply': None }, ], 'of12': [ { 'method': ofctl_v1_2.get_desc_stats, 'request': '3-24-ofp_desc_stats_request.packet.json', 'reply': '3-0-ofp_desc_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_stats, 'request': '3-37-ofp_queue_stats_request.packet.json', 'reply': '3-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet1.json', 'reply': '3-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet2.json', 'reply': '3-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet3.json', 'reply': '3-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_config, 'request': '3-35-ofp_queue_get_config_request.packet.json', 'reply': '3-36-ofp_queue_get_config_reply.packet.json' }, { 'method': ofctl_v1_2.get_flow_stats, 'request': '3-11-ofp_flow_stats_request.packet.json', 'reply': '3-12-ofp_flow_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_aggregate_flow_stats, 'request': '3-25-ofp_aggregate_stats_request.packet.json', 'reply': '3-26-ofp_aggregate_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_table_stats, 'request': '3-27-ofp_table_stats_request.packet.json', 'reply': '3-28-ofp_table_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_port_stats, 'request': '3-29-ofp_port_stats_request.packet.json', 'reply': '3-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_port_stats, 'request': 'lib-ofctl-ofp_port_stats_request.packet.json', 'reply': '3-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_stats, 'request': '3-61-ofp_group_stats_request.packet.json', 'reply': '3-62-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_stats, 'request': 'lib-ofctl-ofp_group_stats_request.packet.json', 'reply': '3-62-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_features, 'request': '3-31-ofp_group_features_stats_request.packet.json', 'reply': '3-32-ofp_group_features_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_desc, 'request': '3-33-ofp_group_desc_stats_request.packet.json', 'reply': '3-34-ofp_group_desc_stats_reply.packet.json' }, # In OpenFlow 1.2, ofp_port_desc is not defined. # We use ofp_features_request to get ports description instead. { 'method': ofctl_v1_2.get_port_desc, 'request': '3-5-ofp_features_request.packet.json', 'reply': '3-6-ofp_features_reply.packet.json' }, { 'method': ofctl_v1_2.mod_flow_entry, 'request': '3-2-ofp_flow_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.mod_group_entry, 'request': '3-21-ofp_group_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.mod_port_behavior, 'request': '3-22-ofp_port_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.send_experimenter, 'request': '3-16-ofp_experimenter.packet.json', 'reply': None }, ], 'of13': [ { 'method': ofctl_v1_3.get_desc_stats, 'request': '4-24-ofp_desc_request.packet.json', 'reply': '4-0-ofp_desc_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_stats, 'request': '4-37-ofp_queue_stats_request.packet.json', 'reply': '4-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet1.json', 'reply': '4-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet2.json', 'reply': '4-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_stats, 'request': 'lib-ofctl-ofp_queue_stats_request.packet3.json', 'reply': '4-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_config, 'request': '4-35-ofp_queue_get_config_request.packet.json', 'reply': '4-36-ofp_queue_get_config_reply.packet.json' }, { 'method': ofctl_v1_3.get_flow_stats, 'request': '4-11-ofp_flow_stats_request.packet.json', 'reply': '4-12-ofp_flow_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_aggregate_flow_stats, 'request': '4-25-ofp_aggregate_stats_request.packet.json', 'reply': '4-26-ofp_aggregate_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_table_stats, 'request': '4-27-ofp_table_stats_request.packet.json', 'reply': '4-28-ofp_table_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_table_features, 'request': 'lib-ofctl-ofp_table_features_request.packet.json', 'reply': '4-56-ofp_table_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_port_stats, 'request': '4-29-ofp_port_stats_request.packet.json', 'reply': '4-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_port_stats, 'request': 'lib-ofctl-ofp_port_stats_request.packet.json', 'reply': '4-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_stats, 'request': '4-49-ofp_meter_stats_request.packet.json', 'reply': '4-50-ofp_meter_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_stats, 'request': 'lib-ofctl-ofp_meter_stats_request.packet.json', 'reply': '4-50-ofp_meter_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_features, 'request': '4-51-ofp_meter_features_request.packet.json', 'reply': '4-52-ofp_meter_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_config, 'request': '4-47-ofp_meter_config_request.packet.json', 'reply': '4-48-ofp_meter_config_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_config, 'request': 'lib-ofctl-ofp_meter_config_request.packet.json', 'reply': '4-48-ofp_meter_config_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_stats, 'request': '4-57-ofp_group_stats_request.packet.json', 'reply': '4-58-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_stats, 'request': 'lib-ofctl-ofp_group_stats_request.packet.json', 'reply': '4-58-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_features, 'request': '4-31-ofp_group_features_request.packet.json', 'reply': '4-32-ofp_group_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_desc, 'request': '4-33-ofp_group_desc_request.packet.json', 'reply': '4-34-ofp_group_desc_reply.packet.json' }, { 'method': ofctl_v1_3.get_port_desc, 'request': '4-53-ofp_port_desc_request.packet.json', 'reply': '4-54-ofp_port_desc_reply.packet.json' }, { 'method': ofctl_v1_3.mod_flow_entry, 'request': '4-2-ofp_flow_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_meter_entry, 'request': '4-45-ofp_meter_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_group_entry, 'request': '4-21-ofp_group_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_port_behavior, 'request': '4-22-ofp_port_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.send_experimenter, 'request': '4-16-ofp_experimenter.packet.json', 'reply': None }, ], 'of14': [ { 'method': ofctl_v1_4.get_desc_stats, 'request': '5-24-ofp_desc_request.packet.json', 'reply': '5-0-ofp_desc_reply.packet.json' }, { 'method': ofctl_v1_4.get_queue_stats, 'request': '5-35-ofp_queue_stats_request.packet.json', 'reply': '5-36-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_queue_desc_stats, 'request': '5-63-ofp_queue_desc_request.packet.json', 'reply': '5-64-ofp_queue_desc_reply.packet.json' }, { 'method': ofctl_v1_4.get_flow_stats, 'request': '5-11-ofp_flow_stats_request.packet.json', 'reply': '5-12-ofp_flow_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_aggregate_flow_stats, 'request': '5-25-ofp_aggregate_stats_request.packet.json', 'reply': '5-26-ofp_aggregate_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_table_stats, 'request': '5-27-ofp_table_stats_request.packet.json', 'reply': '5-28-ofp_table_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_table_features, 'request': 'lib-ofctl-ofp_table_features_request.packet.json', 'reply': '5-54-ofp_table_features_reply.packet.json' }, { 'method': ofctl_v1_4.get_port_stats, 'request': '5-29-ofp_port_stats_request.packet.json', 'reply': '5-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_meter_stats, 'request': '5-47-ofp_meter_stats_request.packet.json', 'reply': '5-48-ofp_meter_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_meter_features, 'request': '5-49-ofp_meter_features_request.packet.json', 'reply': '5-50-ofp_meter_features_reply.packet.json' }, { 'method': ofctl_v1_4.get_meter_config, 'request': '5-45-ofp_meter_config_request.packet.json', 'reply': '5-46-ofp_meter_config_reply.packet.json' }, { 'method': ofctl_v1_4.get_group_stats, 'request': '5-55-ofp_group_stats_request.packet.json', 'reply': '5-56-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_4.get_group_features, 'request': '5-31-ofp_group_features_request.packet.json', 'reply': '5-32-ofp_group_features_reply.packet.json' }, { 'method': ofctl_v1_4.get_group_desc, 'request': '5-33-ofp_group_desc_request.packet.json', 'reply': '5-34-ofp_group_desc_reply.packet.json' }, { 'method': ofctl_v1_4.get_port_desc, 'request': '5-51-ofp_port_desc_request.packet.json', 'reply': '5-52-ofp_port_desc_reply.packet.json' }, { 'method': ofctl_v1_4.mod_flow_entry, 'request': '5-2-ofp_flow_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_4.mod_meter_entry, 'request': '5-43-ofp_meter_mod.packet.json', # flow --> meter 'reply': None }, { 'method': ofctl_v1_4.mod_group_entry, 'request': '5-21-ofp_group_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_4.mod_port_behavior, 'request': '5-22-ofp_port_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_4.send_experimenter, 'request': '5-16-ofp_experimenter.packet.json', 'reply': None }, ], } def _jsonfile_to_msg(datapath, jsonfile): return ofproto_parser.ofp_msg_from_jsondict( datapath, json.load(open(jsonfile))) this_dir = os.path.dirname(sys.modules[__name__].__file__) parser_json_root = os.path.join(this_dir, '../ofproto/json/') ofctl_json_root = os.path.join(this_dir, 'ofctl_json/') for ofp_ver, tests in _test_cases.items(): dp = DummyDatapath(_ofp_vers[ofp_ver]) parser_json_dir = os.path.join(parser_json_root, ofp_ver) ofctl_json_dir = os.path.join(ofctl_json_root, ofp_ver) for test in tests: name = 'test_ofctl_' + ofp_ver + '_' + test['request'] print('adding %s ...' % name) args = {} args_json_path = os.path.join(ofctl_json_dir, test['request']) if os.path.exists(args_json_path): args = json.load(open(args_json_path)) request = _jsonfile_to_msg( dp, os.path.join(parser_json_dir, test['request'])) reply = None expected = None if test['reply']: reply = _jsonfile_to_msg( dp, os.path.join(parser_json_dir, test['reply'])) expected = json.load( open(os.path.join(ofctl_json_dir, test['reply']))) f = functools.partial( Test_ofctl._test, name=name, dp=dp, method=test['method'], args=args, request=request, reply=reply, expected=expected) test_lib.add_method(Test_ofctl, name, f)
def _add_tests(): import functools import itertools class Field(object): pass class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int4double(Field): @staticmethod def generate(): # Note: If yield value as a tuple, flatten_one() will reduce it # into a single value. So the followings avoid this problem by # using a list value. yield [0, 1] yield [0x12345678, 0x23456789] yield [0xffffffff, 0xfffffffe] class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ofproto_v1_5_parser] common = [ ('duration', Int4double), ('idle_time', Int4double), ('flow_count', Int4), ('packet_count', Int8), ('byte_count', Int8), ('field_100', B64), ] L = {} L[ofproto_v1_5_parser] = common def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: reduce(flatten_one, l, []) for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = [flatten(x)[1:] for x in l] for values in l: d = dict(zip(keys, values)) for n, uv in d.items(): if isinstance(uv, list): # XXX # OFPStats returns value as tuple when field is # 'duration' or 'idle_time'. Then convert list # value into tuple here. d[n] = tuple(uv) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') def _run(self, name, ofpp, d): print('processing %s ...' % name) if six.PY3: self._test(self, name, ofpp, d) else: self._test(name, ofpp, d) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, ofpp=ofpp, d=d) test_lib.add_method(Test_Parser_OFPStats, method_name, f)
def _add_tests(): _ofp_vers = { 'of10': 0x01, 'of12': 0x03, 'of13': 0x04 } _test_cases = { 'of10': [ { 'method': ofctl_v1_0.mod_flow_entry, 'request': '1-2-ofp_flow_mod.packet.json', 'reply': None }, ], 'of12': [ { 'method': ofctl_v1_2.get_desc_stats, 'request': '3-24-ofp_desc_stats_request.packet.json', 'reply': '3-0-ofp_desc_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_stats, 'request': '3-37-ofp_queue_stats_request.packet.json', 'reply': '3-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_queue_config, 'request': '3-35-ofp_queue_get_config_request.packet.json', 'reply': '3-36-ofp_queue_get_config_reply.packet.json' }, { 'method': ofctl_v1_2.get_flow_stats, 'request': '3-11-ofp_flow_stats_request.packet.json', 'reply': '3-12-ofp_flow_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_aggregate_flow_stats, 'request': '3-25-ofp_aggregate_stats_request.packet.json', 'reply': '3-26-ofp_aggregate_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_table_stats, 'request': '3-27-ofp_table_stats_request.packet.json', 'reply': '3-28-ofp_table_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_port_stats, 'request': '3-29-ofp_port_stats_request.packet.json', 'reply': '3-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_stats, 'request': '3-61-ofp_group_stats_request.packet.json', 'reply': '3-62-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_features, 'request': '3-31-ofp_group_features_stats_request.packet.json', 'reply': '3-32-ofp_group_features_stats_reply.packet.json' }, { 'method': ofctl_v1_2.get_group_desc, 'request': '3-33-ofp_group_desc_stats_request.packet.json', 'reply': '3-34-ofp_group_desc_stats_reply.packet.json' }, # In OpenFlow 1.2, ofp_port_desc is not defined. # We use ofp_features_request to get ports description instead. { 'method': ofctl_v1_2.get_port_desc, 'request': '3-5-ofp_features_request.packet.json', 'reply': '3-6-ofp_features_reply.packet.json' }, { 'method': ofctl_v1_2.mod_flow_entry, 'request': '3-2-ofp_flow_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.mod_group_entry, 'request': '3-21-ofp_group_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.mod_port_behavior, 'request': '3-22-ofp_port_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_2.send_experimenter, 'request': '3-16-ofp_experimenter.packet.json', 'reply': None }, ], 'of13': [ { 'method': ofctl_v1_3.get_desc_stats, 'request': '4-24-ofp_desc_request.packet.json', 'reply': '4-0-ofp_desc_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_stats, 'request': '4-37-ofp_queue_stats_request.packet.json', 'reply': '4-38-ofp_queue_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_queue_config, 'request': '4-35-ofp_queue_get_config_request.packet.json', 'reply': '4-36-ofp_queue_get_config_reply.packet.json' }, { 'method': ofctl_v1_3.get_flow_stats, 'request': '4-11-ofp_flow_stats_request.packet.json', 'reply': '4-12-ofp_flow_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_aggregate_flow_stats, 'request': '4-25-ofp_aggregate_stats_request.packet.json', 'reply': '4-26-ofp_aggregate_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_table_stats, 'request': '4-27-ofp_table_stats_request.packet.json', 'reply': '4-28-ofp_table_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_table_features, 'request': 'lib-ofctl-ofp_table_features_request.packet.json', 'reply': '4-56-ofp_table_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_port_stats, 'request': '4-29-ofp_port_stats_request.packet.json', 'reply': '4-30-ofp_port_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_stats, 'request': '4-49-ofp_meter_stats_request.packet.json', 'reply': '4-50-ofp_meter_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_features, 'request': '4-51-ofp_meter_features_request.packet.json', 'reply': '4-52-ofp_meter_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_meter_config, 'request': '4-47-ofp_meter_config_request.packet.json', 'reply': '4-48-ofp_meter_config_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_stats, 'request': '4-57-ofp_group_stats_request.packet.json', 'reply': '4-58-ofp_group_stats_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_features, 'request': '4-31-ofp_group_features_request.packet.json', 'reply': '4-32-ofp_group_features_reply.packet.json' }, { 'method': ofctl_v1_3.get_group_desc, 'request': '4-33-ofp_group_desc_request.packet.json', 'reply': '4-34-ofp_group_desc_reply.packet.json' }, { 'method': ofctl_v1_3.get_port_desc, 'request': '4-53-ofp_port_desc_request.packet.json', 'reply': '4-54-ofp_port_desc_reply.packet.json' }, { 'method': ofctl_v1_3.mod_flow_entry, 'request': '4-2-ofp_flow_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_meter_entry, 'request': '4-45-ofp_meter_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_group_entry, 'request': '4-21-ofp_group_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.mod_port_behavior, 'request': '4-22-ofp_port_mod.packet.json', 'reply': None }, { 'method': ofctl_v1_3.send_experimenter, 'request': '4-16-ofp_experimenter.packet.json', 'reply': None }, ] } def _jsonfile_to_msg(datapath, jsonfile): return ofproto_parser.ofp_msg_from_jsondict( datapath, json.load(open(jsonfile))) this_dir = os.path.dirname(sys.modules[__name__].__file__) parser_json_root = os.path.join(this_dir, '../ofproto/json/') ofctl_json_root = os.path.join(this_dir, 'ofctl_json/') for ofp_ver, tests in _test_cases.items(): dp = DummyDatapath(_ofp_vers[ofp_ver]) parser_json_dir = os.path.join(parser_json_root, ofp_ver) ofctl_json_dir = os.path.join(ofctl_json_root, ofp_ver) for test in tests: name = 'test_ofctl_' + test['request'] print('adding %s ...' % name) args = {} args_json_path = os.path.join(ofctl_json_dir, test['request']) if os.path.exists(args_json_path): args = json.load(open(args_json_path)) request = _jsonfile_to_msg( dp, os.path.join(parser_json_dir, test['request'])) reply = None expected = None if test['reply']: reply = _jsonfile_to_msg( dp, os.path.join(parser_json_dir, test['reply'])) expected = json.load( open(os.path.join(ofctl_json_dir, test['reply']))) f = functools.partial( Test_ofctl._test, name=name, dp=dp, method=test['method'], args=args, request=request, reply=reply, expected=expected) test_lib.add_method(Test_ofctl, name, f)
def _add_tests(): import functools import itertools class Field(object): @classmethod def generate_mask(cls): return list(cls.generate())[1] class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ofproto_v1_2_parser, ofproto_v1_3_parser, ofproto_v1_4_parser, ofproto_v1_5_parser] common = [ # OpenFlow Basic ('in_port', Int4), ('in_phy_port', Int4), ('metadata', Int8), ('eth_dst', Mac), ('eth_src', Mac), ('eth_type', Int2), ('vlan_vid', Int2), ('vlan_pcp', Int1), ('ip_dscp', Int1), ('ip_ecn', Int1), ('ip_proto', Int1), ('ipv4_src', IPv4), ('ipv4_dst', IPv4), ('tcp_src', Int2), ('tcp_dst', Int2), ('udp_src', Int2), ('udp_dst', Int2), ('sctp_src', Int2), ('sctp_dst', Int2), ('icmpv4_type', Int1), ('icmpv4_code', Int1), ('arp_op', Int2), ('arp_spa', IPv4), ('arp_tpa', IPv4), ('arp_sha', Mac), ('arp_tha', Mac), ('ipv6_src', IPv6), ('ipv6_dst', IPv6), ('ipv6_flabel', Int4), ('icmpv6_type', Int1), ('icmpv6_code', Int1), ('ipv6_nd_target', IPv6), ('ipv6_nd_sll', Mac), ('ipv6_nd_tll', Mac), ('mpls_label', Int4), ('mpls_tc', Int1), # Old ONF Experimenter --> OpenFlow Basic (OF1.4+) ('pbb_uca', Int1), # ONF Experimenter --> OpenFlow Basic (OF1.5+) ('tcp_flags', Int2), ('actset_output', Int4), # Nicira Experimenter ('eth_dst_nxm', Mac), ('eth_src_nxm', Mac), ('tunnel_id_nxm', Int8), ('tun_ipv4_src', IPv4), ('tun_ipv4_dst', IPv4), ('pkt_mark', Int4), ('conj_id', Int4), ('tun_ipv6_src', IPv6), ('tun_ipv6_dst', IPv6), ('_dp_hash', Int4), ('reg0', Int4), ('reg1', Int4), ('reg2', Int4), ('reg3', Int4), ('reg4', Int4), ('reg5', Int4), ('reg6', Int4), ('reg7', Int4), # Common Experimenter ('field_100', B64), ] L = {} L[ofproto_v1_2_parser] = common + [ # OF1.2 doesn't have OXM_OF_PBB_ISID. # OFPXMC_OPENFLOW_BASIC = 0x8000 # OXM_OF_PBB_ISID = 37 # (OFPXMC_OPENFLOW_BASIC << 7) + OXM_OF_PBB_ISID == 4194341 ('field_4194341', B64), ] L[ofproto_v1_3_parser] = common + [ # OpenFlow Basic (OF1.3+) ('mpls_bos', Int1), ('pbb_isid', Int3), ('tunnel_id', Int8), ('ipv6_exthdr', Int2), ] L[ofproto_v1_4_parser] = L[ofproto_v1_3_parser] L[ofproto_v1_5_parser] = L[ofproto_v1_4_parser] + [ # OpenFlow Basic (OF1.5+) ('packet_type', Int4), ] def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: reduce(flatten_one, l, []) for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = [flatten(x)[1:] for x in l] for domask in [True, False]: for values in l: if domask: values = [(value, cls.generate_mask()) for (cls, value) in zip(clss, values)] d = dict(zip(keys, values)) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod if domask: method_name += '_mask' for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') def _run(self, name, ofpp, d, domask): print('processing %s ...' % name) if six.PY3: self._test(self, name, ofpp, d, domask) else: self._test(name, ofpp, d, domask) print('adding %s ...' % method_name) f = functools.partial(_run, name=method_name, ofpp=ofpp, d=d, domask=domask) test_lib.add_method(Test_Parser_OFPMatch, method_name, f)