blob: a95910246848b1d95e5a360acbdf3d6f073a2d3f [file] [log] [blame]
Dan Talayco89d57342010-06-07 16:24:59 -07001"""
2Flow stats test case.
3Similar to Flow stats test case in the perl test harness.
4
5"""
6
7import logging
8
9import unittest
10import random
11
12import oftest.controller as controller
13import oftest.cstruct as ofp
14import oftest.message as message
15import oftest.dataplane as dataplane
16import oftest.action as action
17import oftest.parse as parse
18import basic
19
20from testutils import *
21from time import sleep
22
Ken Chiangfb593e72012-03-28 17:19:13 -070023#@var fs_port_map Local copy of the configuration map from OF port
Dan Talayco89d57342010-06-07 16:24:59 -070024# numbers to OS interfaces
Ken Chiangfb593e72012-03-28 17:19:13 -070025fs_port_map = None
26#@var fs_logger Local logger object
27fs_logger = None
28#@var fs_config Local copy of global configuration data
29fs_config = None
Dan Talayco89d57342010-06-07 16:24:59 -070030
Ken Chiang620bdcc2012-03-23 12:52:07 -070031# TODO: ovs has problems with VLAN id?
32WILDCARD_VALUES = [ofp.OFPFW_IN_PORT,
Dan Talayco488fbc52012-04-09 16:30:41 -070033 # (ofp.OFPFW_DL_VLAN | ofp.OFPFW_DL_VLAN_PCP),
Ken Chiang620bdcc2012-03-23 12:52:07 -070034 ofp.OFPFW_DL_SRC,
35 ofp.OFPFW_DL_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070036 (ofp.OFPFW_DL_TYPE | ofp.OFPFW_NW_SRC_ALL |
37 ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS | ofp.OFPFW_NW_PROTO |
38 ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
39 (ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST),
Ken Chiang620bdcc2012-03-23 12:52:07 -070040 ofp.OFPFW_TP_SRC,
41 ofp.OFPFW_TP_DST,
Dan Talayco488fbc52012-04-09 16:30:41 -070042 ofp.OFPFW_NW_SRC_MASK,
43 ofp.OFPFW_NW_DST_MASK,
Ken Chiang620bdcc2012-03-23 12:52:07 -070044 ofp.OFPFW_DL_VLAN_PCP,
45 ofp.OFPFW_NW_TOS]
46
Dan Talayco89d57342010-06-07 16:24:59 -070047def test_set_init(config):
48 """
49 Set up function for packet action test classes
50
51 @param config The configuration dictionary; see oft
52 """
53
Ed Swierk89f78352012-03-29 12:32:32 -070054 basic.test_set_init(config)
55
Ken Chiangfb593e72012-03-28 17:19:13 -070056 global fs_port_map
57 global fs_logger
58 global fs_config
Dan Talayco89d57342010-06-07 16:24:59 -070059
Ken Chiangfb593e72012-03-28 17:19:13 -070060 fs_logger = logging.getLogger("flow_stats")
61 fs_logger.info("Initializing test set")
62 fs_port_map = config["port_map"]
63 fs_config = config
Dan Talayco89d57342010-06-07 16:24:59 -070064
Ken Chiangaa5bc062012-03-31 14:03:28 -070065def sendPacket(obj, pkt, ingress_port, egress_port, test_timeout):
66
67 fs_logger.info("Sending packet to dp port " + str(ingress_port) +
68 ", expecting output on " + str(egress_port))
69 obj.dataplane.send(ingress_port, str(pkt))
70
71 exp_pkt_arg = None
72 exp_port = None
73 if fs_config["relax"]:
74 exp_pkt_arg = pkt
75 exp_port = egress_port
76
77 (rcv_port, rcv_pkt, pkt_time) = obj.dataplane.poll(timeout=1,
78 port_number=exp_port,
79 exp_pkt=exp_pkt_arg)
80 obj.assertTrue(rcv_pkt is not None,
81 "Packet not received on port " + str(egress_port))
82 fs_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
83 str(rcv_port))
84 obj.assertEqual(rcv_port, egress_port,
85 "Packet received on port " + str(rcv_port) +
86 ", expected port " + str(egress_port))
87 obj.assertEqual(str(pkt), str(rcv_pkt),
88 'Response packet does not match send packet')
89
Ken Chiang620bdcc2012-03-23 12:52:07 -070090class SingleFlowStats(basic.SimpleDataPlane):
Dan Talayco89d57342010-06-07 16:24:59 -070091 """
92 Verify flow stats are properly retrieved.
93
94 Generate a packet
Ken Chiang620bdcc2012-03-23 12:52:07 -070095 Generate and install a matching flow
96 Send the packet
97 Send a flow stats request to match the flow and retrieve stats
98 Verify that the packet counter has incremented
Dan Talayco89d57342010-06-07 16:24:59 -070099 """
Ken Chiang620bdcc2012-03-23 12:52:07 -0700100
101 def verifyStats(self, match, out_port, test_timeout, packet_count):
102 stat_req = message.flow_stats_request()
103 stat_req.match = match
104 stat_req.table_id = 0xff
105 stat_req.out_port = out_port
106
107 all_packets_received = 0
108 for i in range(0,test_timeout):
Ken Chiangfb593e72012-03-28 17:19:13 -0700109 fs_logger.info("Sending stats request")
110 response, pkt = self.controller.transact(stat_req,
111 timeout=test_timeout)
112 self.assertTrue(response is not None,
113 "No response to stats request")
114 self.assertTrue(len(response.stats) == 1,
115 "Did not receive flow stats reply")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700116 for obj in response.stats:
117 # TODO: pad1 and pad2 fields may be nonzero, is this a bug?
118 # for now, just clear them so the assert is simpler
119 #obj.match.pad1 = 0
120 #obj.match.pad2 = [0, 0]
121 #self.assertEqual(match, obj.match,
122 # "Matches do not match")
Ken Chiangfb593e72012-03-28 17:19:13 -0700123 fs_logger.info("Received " + str(obj.packet_count) + " packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700124 if obj.packet_count == packet_count:
125 all_packets_received = 1
126
127 if all_packets_received:
128 break
129 sleep(1)
130
131 self.assertTrue(all_packets_received,
132 "Packet count does not match number sent")
133
Dan Talayco89d57342010-06-07 16:24:59 -0700134 def runTest(self):
Ken Chiangfb593e72012-03-28 17:19:13 -0700135 global fs_port_map
Dan Talayco89d57342010-06-07 16:24:59 -0700136
Ken Chiang620bdcc2012-03-23 12:52:07 -0700137 # TODO: set from command-line parameter
138 test_timeout = 60
139
Ken Chiangfb593e72012-03-28 17:19:13 -0700140 of_ports = fs_port_map.keys()
Dan Talayco89d57342010-06-07 16:24:59 -0700141 of_ports.sort()
142 self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
143
Ken Chiangfb593e72012-03-28 17:19:13 -0700144 rc = delete_all_flows(self.controller, fs_logger)
Dan Talayco89d57342010-06-07 16:24:59 -0700145 self.assertEqual(rc, 0, "Failed to delete all flows")
146
Ken Chiang620bdcc2012-03-23 12:52:07 -0700147 # build packet
Dan Talayco89d57342010-06-07 16:24:59 -0700148 pkt = simple_tcp_packet()
149 match = parse.packet_to_flow_match(pkt)
150 match.wildcards &= ~ofp.OFPFW_IN_PORT
151 self.assertTrue(match is not None,
152 "Could not generate flow match from pkt")
153 act = action.action_output()
154
Ken Chiang620bdcc2012-03-23 12:52:07 -0700155 # build flow
Dan Talayco39bf6912010-07-08 14:17:52 -0700156 ingress_port = of_ports[0];
157 egress_port = of_ports[1];
Ken Chiangfb593e72012-03-28 17:19:13 -0700158 fs_logger.info("Ingress " + str(ingress_port) +
Dan Talayco89d57342010-06-07 16:24:59 -0700159 " to egress " + str(egress_port))
Ken Chiang620bdcc2012-03-23 12:52:07 -0700160 match.in_port = ingress_port
161 flow_mod_msg = message.flow_mod()
162 flow_mod_msg.match = match
163 flow_mod_msg.cookie = random.randint(0,9007199254740992)
164 flow_mod_msg.buffer_id = 0xffffffff
165 flow_mod_msg.idle_timeout = 0
166 flow_mod_msg.hard_timeout = 0
167 act.port = egress_port
168 self.assertTrue(flow_mod_msg.actions.add(act), "Could not add action")
169
170 # send flow
Ken Chiangfb593e72012-03-28 17:19:13 -0700171 fs_logger.info("Inserting flow")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700172 rv = self.controller.message_send(flow_mod_msg)
173 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700174 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700175
176 # no packets sent, so zero packet count
177 self.verifyStats(match, ofp.OFPP_NONE, test_timeout, 0)
178
179 # send packet N times
180 num_sends = random.randint(10,20)
Ken Chiangfb593e72012-03-28 17:19:13 -0700181 fs_logger.info("Sending " + str(num_sends) + " test packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700182 for i in range(0,num_sends):
Ken Chiangaa5bc062012-03-31 14:03:28 -0700183 sendPacket(self, pkt, ingress_port, egress_port,
184 test_timeout)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700185
186 self.verifyStats(match, ofp.OFPP_NONE, test_timeout, num_sends)
187 self.verifyStats(match, egress_port, test_timeout, num_sends)
188 for wc in WILDCARD_VALUES:
189 match.wildcards = wc
190 self.verifyStats(match, egress_port, test_timeout, num_sends)
191
192
193class TwoFlowStats(basic.SimpleDataPlane):
194 """
195 Verify flow stats are properly retrieved.
196
197 Generate two packets and install two matching flows
198 Send some number of packets
199 Send a flow stats request to match the flows and retrieve stats
200 Verify that the packet counter has incremented
201
202 TODO: add a third flow, and then configure the match to exclude
203 that flow?
204 """
205
206 def buildFlowModMsg(self, pkt, ingress_port, egress_port):
207 match = parse.packet_to_flow_match(pkt)
208 match.wildcards &= ~ofp.OFPFW_IN_PORT
209 self.assertTrue(match is not None,
210 "Could not generate flow match from pkt")
Dan Talayco89d57342010-06-07 16:24:59 -0700211 match.in_port = ingress_port
212
213 flow_mod_msg = message.flow_mod()
214 flow_mod_msg.match = match
215 flow_mod_msg.cookie = random.randint(0,9007199254740992)
216 flow_mod_msg.buffer_id = 0xffffffff
Ken Chiang620bdcc2012-03-23 12:52:07 -0700217 flow_mod_msg.idle_timeout = 0
218 flow_mod_msg.hard_timeout = 0
219 act = action.action_output()
Dan Talayco89d57342010-06-07 16:24:59 -0700220 act.port = egress_port
221 self.assertTrue(flow_mod_msg.actions.add(act), "Could not add action")
Dan Talayco89d57342010-06-07 16:24:59 -0700222
Ken Chiangfb593e72012-03-28 17:19:13 -0700223 fs_logger.info("Ingress " + str(ingress_port) +
Ken Chiang620bdcc2012-03-23 12:52:07 -0700224 " to egress " + str(egress_port))
Dan Talayco89d57342010-06-07 16:24:59 -0700225
Ken Chiang620bdcc2012-03-23 12:52:07 -0700226 return flow_mod_msg
Dan Talayco89d57342010-06-07 16:24:59 -0700227
Ken Chiangaa5bc062012-03-31 14:03:28 -0700228 def sumStatsReplyCounts(self, response):
229 total_packets = 0
230 for obj in response.stats:
231 # TODO: pad1 and pad2 fields may be nonzero, is this a bug?
232 # for now, just clear them so the assert is simpler
233 #obj.match.pad1 = 0
234 #obj.match.pad2 = [0, 0]
235 #self.assertEqual(match, obj.match,
236 # "Matches do not match")
237 fs_logger.info("Received " + str(obj.packet_count)
238 + " packets")
239 total_packets += obj.packet_count
240 return total_packets
Ken Chiang620bdcc2012-03-23 12:52:07 -0700241
242 def verifyStats(self, match, out_port, test_timeout, packet_count):
243 stat_req = message.flow_stats_request()
244 stat_req.match = match
245 stat_req.table_id = 0xff
246 stat_req.out_port = out_port
247
248 all_packets_received = 0
249 for i in range(0,test_timeout):
Ken Chiangfb593e72012-03-28 17:19:13 -0700250 fs_logger.info("Sending stats request")
Ken Chiangaa5bc062012-03-31 14:03:28 -0700251 # TODO: move REPLY_MORE handling to controller.transact?
Ken Chiangfb593e72012-03-28 17:19:13 -0700252 response, pkt = self.controller.transact(stat_req,
253 timeout=test_timeout)
254 self.assertTrue(response is not None,
255 "No response to stats request")
Ken Chiangaa5bc062012-03-31 14:03:28 -0700256 total_packets = self.sumStatsReplyCounts(response)
257
258 while response.flags == ofp.OFPSF_REPLY_MORE:
259 response, pkt = self.controller.poll(exp_msg=
260 ofp.OFPT_STATS_REPLY,
261 timeout=test_timeout)
262 total_packets += self.sumStatsReplyCounts(response)
263
Ken Chiang620bdcc2012-03-23 12:52:07 -0700264 if total_packets == packet_count:
265 all_packets_received = 1
266 break
267 sleep(1)
268
269 self.assertTrue(all_packets_received,
Ken Chiangaa5bc062012-03-31 14:03:28 -0700270 "Total stats packet count " + str(total_packets) +
271 " does not match number sent " + str(packet_count))
Ken Chiang620bdcc2012-03-23 12:52:07 -0700272
273 def runTest(self):
Ken Chiangfb593e72012-03-28 17:19:13 -0700274 global fs_port_map
Ken Chiang620bdcc2012-03-23 12:52:07 -0700275
276 # TODO: set from command-line parameter
277 test_timeout = 60
278
Ken Chiangfb593e72012-03-28 17:19:13 -0700279 of_ports = fs_port_map.keys()
Ken Chiang620bdcc2012-03-23 12:52:07 -0700280 of_ports.sort()
281 self.assertTrue(len(of_ports) >= 3, "Not enough ports for test")
282 ingress_port = of_ports[0];
283 egress_port1 = of_ports[1];
284 egress_port2 = of_ports[2];
285
Ken Chiangfb593e72012-03-28 17:19:13 -0700286 rc = delete_all_flows(self.controller, fs_logger)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700287 self.assertEqual(rc, 0, "Failed to delete all flows")
288
289 pkt1 = simple_tcp_packet()
290 flow_mod_msg1 = self.buildFlowModMsg(pkt1, ingress_port, egress_port1)
291
292 pkt2 = simple_tcp_packet(dl_src='0:7:7:7:7:7')
293 flow_mod_msg2 = self.buildFlowModMsg(pkt2, ingress_port, egress_port2)
294
Ken Chiangfb593e72012-03-28 17:19:13 -0700295 fs_logger.info("Inserting flow1")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700296 rv = self.controller.message_send(flow_mod_msg1)
297 self.assertTrue(rv != -1, "Error installing flow mod")
Ken Chiangfb593e72012-03-28 17:19:13 -0700298 fs_logger.info("Inserting flow2")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700299 rv = self.controller.message_send(flow_mod_msg2)
300 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700301 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco89d57342010-06-07 16:24:59 -0700302
Ken Chiang620bdcc2012-03-23 12:52:07 -0700303 num_pkt1s = random.randint(10,30)
Ken Chiangfb593e72012-03-28 17:19:13 -0700304 fs_logger.info("Sending " + str(num_pkt1s) + " pkt1s")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700305 num_pkt2s = random.randint(10,30)
Ken Chiangfb593e72012-03-28 17:19:13 -0700306 fs_logger.info("Sending " + str(num_pkt2s) + " pkt2s")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700307 for i in range(0,num_pkt1s):
Ken Chiangaa5bc062012-03-31 14:03:28 -0700308 sendPacket(self, pkt1, ingress_port, egress_port1, test_timeout)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700309 for i in range(0,num_pkt2s):
Ken Chiangaa5bc062012-03-31 14:03:28 -0700310 sendPacket(self, pkt2, ingress_port, egress_port2, test_timeout)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700311
312 match1 = parse.packet_to_flow_match(pkt1)
Ken Chiangaa5bc062012-03-31 14:03:28 -0700313 fs_logger.info("Verifying flow1's " + str(num_pkt1s) + " packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700314 self.verifyStats(match1, ofp.OFPP_NONE, test_timeout, num_pkt1s)
315 match2 = parse.packet_to_flow_match(pkt2)
Ken Chiangaa5bc062012-03-31 14:03:28 -0700316 fs_logger.info("Verifying flow2's " + str(num_pkt2s) + " packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700317 self.verifyStats(match2, ofp.OFPP_NONE, test_timeout, num_pkt2s)
318 match1.wildcards |= ofp.OFPFW_DL_SRC
Ken Chiangaa5bc062012-03-31 14:03:28 -0700319 fs_logger.info("Verifying combined " + str(num_pkt1s+num_pkt2s) + " packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700320 self.verifyStats(match1, ofp.OFPP_NONE, test_timeout,
321 num_pkt1s+num_pkt2s)
322 # TODO: sweep through the wildcards to verify matching?
323
324
325class AggregateStats(basic.SimpleDataPlane):
326 """
327 Verify aggregate flow stats are properly retrieved.
328
329 Generate two packets
330 Generate and install two matching flows
331 Send an aggregate stats request
332 Verify that aggregate stats are correct
333 Also verify out_port filtering
334 """
335
336 def buildFlowModMsg(self, pkt, ingress_port, egress_port):
337 match = parse.packet_to_flow_match(pkt)
338 match.wildcards &= ~ofp.OFPFW_IN_PORT
339 self.assertTrue(match is not None,
340 "Could not generate flow match from pkt")
341 match.in_port = ingress_port
342
343 flow_mod_msg = message.flow_mod()
344 flow_mod_msg.match = match
345 flow_mod_msg.cookie = random.randint(0,9007199254740992)
346 flow_mod_msg.buffer_id = 0xffffffff
347 flow_mod_msg.idle_timeout = 0
348 flow_mod_msg.hard_timeout = 0
349 act = action.action_output()
350 act.port = egress_port
351 self.assertTrue(flow_mod_msg.actions.add(act), "Could not add action")
352
Ken Chiangfb593e72012-03-28 17:19:13 -0700353 fs_logger.info("Ingress " + str(ingress_port) +
Ken Chiang620bdcc2012-03-23 12:52:07 -0700354 " to egress " + str(egress_port))
355
356 return flow_mod_msg
357
Ken Chiang620bdcc2012-03-23 12:52:07 -0700358 def verifyAggFlowStats(self, match, out_port, test_timeout,
359 flow_count, packet_count):
360 stat_req = message.aggregate_stats_request()
361 stat_req.match = match
362 stat_req.table_id = 0xff
363 stat_req.out_port = out_port
364
365 all_packets_received = 0
366 for i in range(0,test_timeout):
Ken Chiangfb593e72012-03-28 17:19:13 -0700367 fs_logger.info("Sending stats request")
368 response, pkt = self.controller.transact(stat_req,
369 timeout=test_timeout)
370 self.assertTrue(response is not None,
371 "No response to stats request")
Dan Talaycoaff26c82012-03-25 15:06:26 -0700372 self.assertTrue(len(response.stats) == 1,
373 "Did not receive flow stats reply")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700374 for obj in response.stats:
375 self.assertTrue(obj.flow_count == flow_count,
376 "Flow count " + str(obj.flow_count) +
377 " does not match expected " + str(flow_count))
Ken Chiangfb593e72012-03-28 17:19:13 -0700378 fs_logger.info("Received " + str(obj.packet_count) + " packets")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700379 if obj.packet_count == packet_count:
380 all_packets_received = 1
381
382 if all_packets_received:
383 break
384 sleep(1)
385
386 self.assertTrue(all_packets_received,
387 "Packet count does not match number sent")
388
389 def runTest(self):
Ken Chiangfb593e72012-03-28 17:19:13 -0700390 global fs_port_map
Ken Chiang620bdcc2012-03-23 12:52:07 -0700391
392 # TODO: set from command-line parameter
393 test_timeout = 60
394
Ken Chiangfb593e72012-03-28 17:19:13 -0700395 of_ports = fs_port_map.keys()
Ken Chiang620bdcc2012-03-23 12:52:07 -0700396 of_ports.sort()
397 self.assertTrue(len(of_ports) >= 3, "Not enough ports for test")
398 ingress_port = of_ports[0];
399 egress_port1 = of_ports[1];
400 egress_port2 = of_ports[2];
401
Ken Chiangfb593e72012-03-28 17:19:13 -0700402 rc = delete_all_flows(self.controller, fs_logger)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700403 self.assertEqual(rc, 0, "Failed to delete all flows")
404
405 pkt1 = simple_tcp_packet()
406 flow_mod_msg1 = self.buildFlowModMsg(pkt1, ingress_port, egress_port1)
407
408 pkt2 = simple_tcp_packet(dl_src='0:7:7:7:7:7')
409 flow_mod_msg2 = self.buildFlowModMsg(pkt2, ingress_port, egress_port2)
410
Ken Chiangfb593e72012-03-28 17:19:13 -0700411 fs_logger.info("Inserting flow1")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700412 rv = self.controller.message_send(flow_mod_msg1)
413 self.assertTrue(rv != -1, "Error installing flow mod")
Ken Chiangfb593e72012-03-28 17:19:13 -0700414 fs_logger.info("Inserting flow2")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700415 rv = self.controller.message_send(flow_mod_msg2)
416 self.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco0fc08bd2012-04-09 16:56:18 -0700417 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700418
419 num_pkt1s = random.randint(10,30)
Ken Chiangfb593e72012-03-28 17:19:13 -0700420 fs_logger.info("Sending " + str(num_pkt1s) + " pkt1s")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700421 num_pkt2s = random.randint(10,30)
Ken Chiangfb593e72012-03-28 17:19:13 -0700422 fs_logger.info("Sending " + str(num_pkt2s) + " pkt2s")
Ken Chiang620bdcc2012-03-23 12:52:07 -0700423 for i in range(0,num_pkt1s):
Ken Chiangaa5bc062012-03-31 14:03:28 -0700424 sendPacket(self, pkt1, ingress_port, egress_port1, test_timeout)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700425 for i in range(0,num_pkt2s):
Ken Chiangaa5bc062012-03-31 14:03:28 -0700426 sendPacket(self, pkt2, ingress_port, egress_port2, test_timeout)
Ken Chiang620bdcc2012-03-23 12:52:07 -0700427
428 # loop on flow stats request until timeout
429 match = parse.packet_to_flow_match(pkt1)
430 match.wildcards |= ofp.OFPFW_DL_SRC
431 self.verifyAggFlowStats(match, ofp.OFPP_NONE, test_timeout,
432 2, num_pkt1s+num_pkt2s)
433
434 # out_port filter for egress_port1
435 self.verifyAggFlowStats(match, egress_port1, test_timeout,
436 1, num_pkt1s)
437
438 # out_port filter for egress_port1
439 self.verifyAggFlowStats(match, egress_port2, test_timeout,
440 1, num_pkt2s)