Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 1 | import sys |
Dan Talayco | b9cb548 | 2010-02-09 15:23:12 -0800 | [diff] [blame] | 2 | sys.path.append('../../../src/python/oftest/protocol') |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 3 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 4 | from parse import of_message_parse |
| 5 | from parse import of_header_parse |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 6 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 7 | from defs import * |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 8 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 9 | def error_out(string): |
| 10 | print >> sys.stderr, string |
| 11 | print string |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 12 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 13 | def obj_comp(orig, new, objname, errstr=None): |
| 14 | """ |
| 15 | Compare two objects |
| 16 | """ |
| 17 | dump = False |
| 18 | if not errstr: |
| 19 | errstr = "(unknown)" |
| 20 | errstr += " " + objname |
| 21 | if not new: |
| 22 | error_out("ERROR: obj comp, new is None for " + errstr) |
| 23 | dump = True |
| 24 | elif type(orig) != type(new): |
| 25 | error_out("ERROR: type mismatch for " + errstr + " ") |
| 26 | dump = True |
| 27 | elif orig != new: |
| 28 | error_out("ERROR: " + errstr + " orig != new") |
| 29 | dump = True |
| 30 | if dump: |
| 31 | print "Dump of mismatch for " + errstr |
| 32 | print "type orig " + str(type(orig)) |
| 33 | print "orig length ", len(orig) |
| 34 | orig.show(" ") |
| 35 | if new: |
| 36 | print "type new" + str(type(new)) |
| 37 | print "new length ", len(new) |
| 38 | new.show(" ") |
| 39 | print |
| 40 | |
| 41 | |
| 42 | # Generate a long action list |
| 43 | |
| 44 | def action_list_create(n=10): |
| 45 | """ |
| 46 | Create an action list |
| 47 | |
| 48 | @param n The number of actions to put in the list |
| 49 | |
| 50 | Cycle through the list of all actions, adding each type |
| 51 | """ |
| 52 | |
| 53 | al = action_list() |
| 54 | for i in range(n): |
| 55 | idx = i % len(action_class_list) |
| 56 | cls = action_class_list[idx]() |
| 57 | al.add(cls) |
| 58 | return al |
| 59 | |
| 60 | # Test classes with action lists |
| 61 | def class_action_test(): |
| 62 | """ |
| 63 | Test objects that use action lists |
| 64 | """ |
| 65 | |
| 66 | print "Testing action lists: flow mod, packet out, flow stats" |
| 67 | for acount in [0, 1, 5, 16, 34]: |
| 68 | print " " + str(acount) + " actions in list" |
| 69 | obj = flow_mod() |
| 70 | obj.actions = action_list_create(acount) |
| 71 | packed = obj.pack() |
| 72 | header = of_header_parse(packed) |
| 73 | obj_check = flow_mod() |
| 74 | if obj_check.unpack(packed) != "": |
| 75 | error_out("ERROR: flow mod action list test extra " + |
| 76 | "string on unpack") |
| 77 | obj_comp(obj, obj_check, 'flow_mod', "unpack test " + str(acount)) |
| 78 | obj_check = of_message_parse(packed) |
| 79 | obj_comp(obj, obj_check, 'flow_mod', "parse test " + str(acount)) |
| 80 | # obj.show() |
| 81 | |
| 82 | # packet out with and without data |
| 83 | obj = packet_out() |
| 84 | obj.actions = action_list_create(acount) |
| 85 | packed = obj.pack() |
| 86 | header = of_header_parse(packed) |
| 87 | obj_check = packet_out() |
| 88 | if obj_check.unpack(packed) != "": |
| 89 | error_out("ERROR: packet out packet_out test extra " + |
| 90 | "string on unpack") |
| 91 | obj_comp(obj, obj_check, 'packet_out', "unpack test " + str(acount)) |
| 92 | obj_check = of_message_parse(packed) |
| 93 | obj_comp(obj, obj_check, 'packet_out', "parse test " + str(acount)) |
| 94 | # obj.show() |
| 95 | |
| 96 | obj = packet_out() |
| 97 | obj.actions = action_list_create(acount) |
| 98 | obj.data = "short test string for packet data" |
| 99 | packed = obj.pack() |
| 100 | header = of_header_parse(packed) |
| 101 | obj_check = packet_out() |
| 102 | if obj_check.unpack(packed) != "": |
| 103 | error_out("ERROR: packet out packet_out test extra " + |
| 104 | "string on unpack") |
| 105 | obj_comp(obj, obj_check, 'packet_out', "unpack test " + str(acount)) |
| 106 | obj_check = of_message_parse(packed) |
| 107 | obj_comp(obj, obj_check, 'packet_out', "parse test " + str(acount)) |
| 108 | # obj.show() |
| 109 | |
| 110 | # flow stats entry (not a message) |
| 111 | obj = flow_stats_entry() |
| 112 | obj.actions = action_list_create(acount) |
| 113 | packed = obj.pack() |
| 114 | obj_check = flow_stats_entry() |
| 115 | if obj_check.unpack(packed) != "": |
| 116 | error_out("ERROR: packet out flow stats test extra " + |
| 117 | "string on unpack") |
| 118 | obj_comp(obj, obj_check, 'packet_out', "unpack test " + str(acount)) |
| 119 | # obj.show() |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 120 | |
| 121 | print "Generating all classes with no data init" |
| 122 | print |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 123 | for cls in all_objs: |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 124 | print "Creating class " + ofmsg_names[cls] |
| 125 | obj = cls() |
| 126 | print ofmsg_names[cls] + " length: " + str(len(obj)) |
| 127 | obj.show(" ") |
| 128 | print |
| 129 | |
| 130 | print "End of class generation" |
| 131 | print |
| 132 | print |
| 133 | |
| 134 | print "Generating messages, packing, showing (to verify len)" |
| 135 | print "and calling self unpack" |
| 136 | print |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 137 | for cls in all_objs: |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 138 | print "Pack/unpack test for class " + ofmsg_names[cls] |
| 139 | obj = cls() |
| 140 | packed = obj.pack() |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 141 | obj_check = cls() |
| 142 | string = obj_check.unpack(packed) |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 143 | if string != "": |
| 144 | print >> sys.stderr, "WARNING: " + ofmsg_names[cls] + \ |
| 145 | ", unpack returned string " + string |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 146 | obj_comp(obj, obj_check, ofmsg_names[cls], "pack/unpack") |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 147 | |
| 148 | print "End of class pack check" |
| 149 | print |
Dan Talayco | b9cb548 | 2010-02-09 15:23:12 -0800 | [diff] [blame] | 150 | print |
| 151 | |
| 152 | |
| 153 | print "Testing message parsing" |
| 154 | print |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 155 | for cls in all_objs: |
| 156 | # Can only parse real messages |
| 157 | if not cls in of_messages: |
| 158 | print "Not testing " + ofmsg_names[cls] |
| 159 | continue |
| 160 | print "Parse test for class " + ofmsg_names[cls] |
Dan Talayco | b9cb548 | 2010-02-09 15:23:12 -0800 | [diff] [blame] | 161 | obj = cls() |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 162 | packed = obj.pack() |
| 163 | header = of_header_parse(packed) |
| 164 | obj_check = of_message_parse(packed) |
| 165 | obj_comp(obj, obj_check, ofmsg_names[cls], "parse test") |
Dan Talayco | b9cb548 | 2010-02-09 15:23:12 -0800 | [diff] [blame] | 166 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 167 | print "End of parse testing" |
Dan Talayco | b9cb548 | 2010-02-09 15:23:12 -0800 | [diff] [blame] | 168 | print |
| 169 | print |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 170 | |
Dan Talayco | dc88181 | 2010-02-10 22:42:12 -0800 | [diff] [blame^] | 171 | class_action_test() |
| 172 | print |
| 173 | print |
Dan Talayco | c85e97e | 2010-02-07 22:59:04 -0800 | [diff] [blame] | 174 | |
| 175 | # |
| 176 | # TO DO |
| 177 | # Generate varying actions lists and attach to flow_mod, |
| 178 | # packet out and flow_stats_entry objects. |
| 179 | # Generate varying lists of stats entries for replies in |
| 180 | # flow_stats_reply, table_stats_reply, port_stats_reply and |
| 181 | # queue_stats_reply |
| 182 | # Create and test packet-to-flow function |
| 183 | |
| 184 | |
| 185 | f = flow_stats_reply() |
| 186 | ent = flow_stats_entry() |
| 187 | |
| 188 | |
| 189 | act = action_strip_vlan() |
| 190 | alist = action_list() |
| 191 | alist.add(act) |
| 192 | |
| 193 | act = action_set_tp_dst() |
| 194 | act.tp_port = 17 |
| 195 | |
| 196 | m = ofp_match() |
| 197 | m.wildcards = OFPFW_IN_PORT + OFPFW_DL_VLAN + OFPFW_DL_SRC |
| 198 | |
| 199 | # |
| 200 | # Need: Easy reference from action to data members |
| 201 | m.in_port = 12 |
| 202 | m.dl_src= [1,2,3,4,5,6] |
| 203 | m.dl_dst= [11,22,23,24,25,26] |
| 204 | m.dl_vlan = 83 |
| 205 | m.dl_vlan_pcp = 1 |
| 206 | m.dl_type = 0x12 |
| 207 | m.nw_tos = 3 |
| 208 | m.nw_proto = 0x300 |
| 209 | m.nw_src = 0x232323 |
| 210 | m.nw_dst = 0x3232123 |
| 211 | m.tp_src = 32 |
| 212 | m.tp_dst = 2 |
| 213 | |
| 214 | m.show() |
| 215 | |