blob: a15bc506c369ff1501b0f981225e55c34665a80a [file] [log] [blame]
Rich Lane89e12652013-10-10 17:26:25 -07001# Distributed under the OpenFlow Software License (see LICENSE)
2# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
3# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
4# Copyright (c) 2012, 2013 CPqD
5# Copyright (c) 2012, 2013 Ericsson
6"""
7Group table test cases.
8"""
9
10import logging
11
12from oftest import config
13import oftest
14import oftest.base_tests as base_tests
15import ofp
16
17from oftest.testutils import *
18
19class GroupTest(base_tests.SimpleDataPlane):
20 def setUp(self):
21 base_tests.SimpleDataPlane.setUp(self)
22 delete_all_flows(self.controller)
23 delete_all_groups(self.controller)
24
25
26class GroupAdd(GroupTest):
27 """
28 A regular group should be added successfully
29 """
30
31 def runTest(self):
32 port1, = openflow_ports(1)
33
34 msg = ofp.message.group_mod(
35 command=ofp.OFPGC_ADD,
36 group_type=ofp.OFPGT_ALL,
37 group_id=0,
38 buckets=[
39 ofp.bucket(actions=[ofp.action.output(port1)])])
40
41 self.controller.message_send(msg)
42 do_barrier(self.controller)
43
44 stats = get_stats(self, ofp.message.group_desc_stats_request())
45 self.assertEquals(stats, [
46 ofp.group_desc_stats_entry(
47 type=msg.group_type,
48 group_id=msg.group_id,
49 buckets=msg.buckets)])
50
51
52class GroupAddInvalidAction(GroupTest):
53 """
54 If any action in the buckets is invalid, OFPET_BAD_ACTION/<code> should be returned
55 """
56
57 def runTest(self):
58 msg = ofp.message.group_mod(
59 command=ofp.OFPGC_ADD,
60 group_type=ofp.OFPGT_ALL,
61 group_id=0,
62 buckets=[
63 ofp.bucket(actions=[ofp.action.output(ofp.OFPP_ANY)])])
64
65 response, _ = self.controller.transact(msg)
66 self.assertIsInstance(response, ofp.message.error_msg)
67 self.assertEquals(response.err_type, ofp.OFPET_BAD_ACTION)
68 self.assertEquals(response.code, ofp.OFPBAC_BAD_OUT_PORT)
69
70
71class GroupAddExisting(GroupTest):
72 """
73 An addition with existing group id should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_GROUP_EXISTS
74 """
75
76 def runTest(self):
77 port1, port2, = openflow_ports(2)
78
79 msg = ofp.message.group_mod(
80 command=ofp.OFPGC_ADD,
81 group_type=ofp.OFPGT_ALL,
82 group_id=0,
83 buckets=[
84 ofp.bucket(actions=[ofp.action.output(port1)])])
85
86 self.controller.message_send(msg)
87 do_barrier(self.controller)
88
89 msg = ofp.message.group_mod(
90 command=ofp.OFPGC_ADD,
91 group_type=ofp.OFPGT_ALL,
92 group_id=0,
93 buckets=[
94 ofp.bucket(actions=[ofp.action.output(port2)])])
95
96 response, _ = self.controller.transact(msg)
97 self.assertIsInstance(response, ofp.message.error_msg)
98 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
99 self.assertEquals(response.code, ofp.OFPGMFC_GROUP_EXISTS)
100
101
102class GroupAddInvalidID(GroupTest):
103 """
104 An addition with invalid group id (reserved) should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_INVALID_GROUP
105 """
106
107 def runTest(self):
108 port1, = openflow_ports(1)
109
110 msg = ofp.message.group_mod(
111 command=ofp.OFPGC_ADD,
112 group_type=ofp.OFPGT_ALL,
113 group_id=ofp.OFPG_ALL,
114 buckets=[
115 ofp.bucket(actions=[ofp.action.output(port1)])])
116
117 response, _ = self.controller.transact(msg)
118 self.assertIsInstance(response, ofp.message.error_msg)
119 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
120 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
121
122
123class GroupModify(GroupTest):
124 """
125 A regular group modification should be successful
126 """
127
128 def runTest(self):
129 port1, port2, = openflow_ports(2)
130
131 msg = ofp.message.group_mod(
132 command=ofp.OFPGC_ADD,
133 group_type=ofp.OFPGT_ALL,
134 group_id=0,
135 buckets=[
136 ofp.bucket(actions=[ofp.action.output(port1)])])
137
138 self.controller.message_send(msg)
139 do_barrier(self.controller)
140
141 msg = ofp.message.group_mod(
142 command=ofp.OFPGC_MODIFY,
143 group_type=ofp.OFPGT_ALL,
144 group_id=0,
145 buckets=[
146 ofp.bucket(actions=[ofp.action.output(port2)])])
147
148 self.controller.message_send(msg)
149 do_barrier(self.controller)
150
151 stats = get_stats(self, ofp.message.group_desc_stats_request())
152 self.assertEquals(stats, [
153 ofp.group_desc_stats_entry(
154 type=msg.group_type,
155 group_id=msg.group_id,
156 buckets=msg.buckets)])
157
158
159class GroupModifyNonexisting(GroupTest):
160 """
161 A modification for a non-existing group should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_UNKNOWN_GROUP
162 """
163
164 def runTest(self):
165 port1, = openflow_ports(1)
166
167 msg = ofp.message.group_mod(
168 command=ofp.OFPGC_MODIFY,
169 group_type=ofp.OFPGT_ALL,
170 group_id=0,
171 buckets=[
172 ofp.bucket(actions=[ofp.action.output(port1)])])
173
174 response, _ = self.controller.transact(msg)
175 self.assertIsInstance(response, ofp.message.error_msg)
176 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
177 self.assertEquals(response.code, ofp.OFPGMFC_UNKNOWN_GROUP)
178
179
180class GroupModifyLoop(GroupTest):
181 """
182 A modification causing loop should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_LOOP
183 """
184
185 def runTest(self):
186 port1, = openflow_ports(1)
187
188 msg = ofp.message.group_mod(
189 command=ofp.OFPGC_ADD,
190 group_type=ofp.OFPGT_ALL,
191 group_id=0,
192 buckets=[
193 ofp.bucket(actions=[ofp.action.output(port1)])])
194
195 self.controller.message_send(msg)
196 do_barrier(self.controller)
197
198 msg = ofp.message.group_mod(
199 command=ofp.OFPGC_ADD,
200 group_type=ofp.OFPGT_ALL,
201 group_id=1,
202 buckets=[
203 ofp.bucket(actions=[ofp.action.group(0)])])
204
205 self.controller.message_send(msg)
206 do_barrier(self.controller)
207
208 msg = ofp.message.group_mod(
209 command=ofp.OFPGC_ADD,
210 group_type=ofp.OFPGT_ALL,
211 group_id=2,
212 buckets=[
213 ofp.bucket(actions=[ofp.action.group(1)])])
214
215 self.controller.message_send(msg)
216 do_barrier(self.controller)
217
218 msg = ofp.message.group_mod(
219 command=ofp.OFPGC_MODIFY,
220 group_type=ofp.OFPGT_ALL,
221 group_id=0,
222 buckets=[
223 ofp.bucket(actions=[ofp.action.group(2)])])
224
225 response, _ = self.controller.transact(msg)
226 self.assertIsInstance(response, ofp.message.error_msg)
227 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
228 self.assertEquals(response.code, ofp.OFPGMFC_LOOP)
229
230
231class GroupModifyInvalidID(GroupTest):
232 """
233 A modification for a reserved group should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_INVALID_GROUP
234 """
235
236 def runTest(self):
237 port1, = openflow_ports(1)
238
239 msg = ofp.message.group_mod(
240 command=ofp.OFPGC_ADD,
241 group_type=ofp.OFPGT_ALL,
242 group_id=ofp.OFPG_ALL,
243 buckets=[
244 ofp.bucket(actions=[ofp.action.output(port1)])])
245
246 response, _ = self.controller.transact(msg)
247 self.assertIsInstance(response, ofp.message.error_msg)
248 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
249 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
250
251
252class GroupModifyEmpty(GroupTest):
253 """
254 A modification for an existing group with no buckets should be accepted
255 """
256
257 def runTest(self):
258 port1, = openflow_ports(1)
259
260 msg = ofp.message.group_mod(
261 command=ofp.OFPGC_ADD,
262 group_type=ofp.OFPGT_ALL,
263 group_id=0,
264 buckets=[
265 ofp.bucket(actions=[ofp.action.output(port1)])])
266
267 self.controller.message_send(msg)
268 do_barrier(self.controller)
269
270 msg = ofp.message.group_mod(
271 command=ofp.OFPGC_MODIFY,
272 group_type=ofp.OFPGT_ALL,
273 group_id=0,
274 buckets=[])
275
276 self.controller.message_send(msg)
277 do_barrier(self.controller)
278
279 stats = get_stats(self, ofp.message.group_desc_stats_request())
280 self.assertEquals(stats, [
281 ofp.group_desc_stats_entry(
282 type=msg.group_type,
283 group_id=msg.group_id,
284 buckets=msg.buckets)])
285
286
287class GroupDeleteExisting(GroupTest):
288 """
289 A deletion for an existing group should remove the group
290 """
291
292 def runTest(self):
293 port1, = openflow_ports(1)
294
295 msg = ofp.message.group_mod(
296 command=ofp.OFPGC_ADD,
297 group_type=ofp.OFPGT_ALL,
298 group_id=0,
299 buckets=[
300 ofp.bucket(actions=[ofp.action.output(port1)])])
301
302 self.controller.message_send(msg)
303 do_barrier(self.controller)
304
305 msg = ofp.message.group_mod(
306 command=ofp.OFPGC_DELETE,
307 group_id=0)
308
309 self.controller.message_send(msg)
310 do_barrier(self.controller)
311
312 stats = get_stats(self, ofp.message.group_desc_stats_request())
313 self.assertEquals(stats, [])
314
315
316class GroupDeleteNonexisting(GroupTest):
317 """
318 A deletion for nonexisting group should result in no error
319 """
320
321 def runTest(self):
322 msg = ofp.message.group_mod(
323 command=ofp.OFPGC_DELETE,
324 group_id=0)
325
326 self.controller.message_send(msg)
327 do_barrier(self.controller)
328 verify_no_errors(self.controller)
329
330
331class GroupDeleteAll(GroupTest):
332 """
333 A deletion for OFPG_ALL should remove all groups
334 """
335
336 def runTest(self):
337 port1, = openflow_ports(1)
338
339 msg = ofp.message.group_mod(
340 command=ofp.OFPGC_ADD,
341 group_type=ofp.OFPGT_ALL,
342 group_id=0,
343 buckets=[
344 ofp.bucket(actions=[ofp.action.output(port1)])])
345
346 self.controller.message_send(msg)
347 do_barrier(self.controller)
348
349 msg = ofp.message.group_mod(
350 command=ofp.OFPGC_ADD,
351 group_type=ofp.OFPGT_ALL,
352 group_id=1,
353 buckets=[
354 ofp.bucket(actions=[ofp.action.output(port1)])])
355
356 self.controller.message_send(msg)
357 do_barrier(self.controller)
358
359 msg = ofp.message.group_mod(
360 command=ofp.OFPGC_DELETE,
361 group_id=ofp.OFPG_ALL)
362
363 self.controller.message_send(msg)
364 do_barrier(self.controller)
365
366 stats = get_stats(self, ofp.message.group_desc_stats_request())
367 self.assertEquals(stats, [])
368
369
370class GroupAddAllWeight(GroupTest):
371 """
372 An ALL group with weights for buckets should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
373 """
374
375 def runTest(self):
376 port1, port2, = openflow_ports(2)
377
378 msg = ofp.message.group_mod(
379 command=ofp.OFPGC_ADD,
380 group_type=ofp.OFPGT_ALL,
381 group_id=0,
382 buckets=[
383 ofp.bucket(weight=1, actions=[ofp.action.output(port1)]),
384 ofp.bucket(weight=2, actions=[ofp.action.output(port2)])])
385
386 response, _ = self.controller.transact(msg)
387 self.assertIsInstance(response, ofp.message.error_msg)
388 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
389 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
390
391
392class GroupAddIndirectWeight(GroupTest):
393 """
394 An INDIRECT group with weights for buckets should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
395 """
396
397 def runTest(self):
398 port1, = openflow_ports(1)
399
400 msg = ofp.message.group_mod(
401 command=ofp.OFPGC_ADD,
402 group_type=ofp.OFPGT_INDIRECT,
403 group_id=0,
404 buckets=[
405 ofp.bucket(weight=1, actions=[ofp.action.output(port1)])])
406
407 response, _ = self.controller.transact(msg)
408 self.assertIsInstance(response, ofp.message.error_msg)
409 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
410 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
411
412
413class GroupAddIndirectBuckets(GroupTest):
414 """
415 An INDIRECT group with <>1 bucket should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
416 """
417
418 def runTest(self):
419 port1, port2, = openflow_ports(2)
420
421 msg = ofp.message.group_mod(
422 command=ofp.OFPGC_ADD,
423 group_type=ofp.OFPGT_INDIRECT,
424 group_id=0,
425 buckets=[
426 ofp.bucket(actions=[ofp.action.output(port1)]),
427 ofp.bucket(actions=[ofp.action.output(port2)])])
428
429 response, _ = self.controller.transact(msg)
430 self.assertIsInstance(response, ofp.message.error_msg)
431 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
432 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
433
434
435class GroupAddSelectNoWeight(GroupTest):
436 """
437 A SELECT group with ==0 weights should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
438 """
439
440 def runTest(self):
441 port1, port2, = openflow_ports(2)
442
443 msg = ofp.message.group_mod(
444 command=ofp.OFPGC_ADD,
445 group_type=ofp.OFPGT_SELECT,
446 group_id=0,
447 buckets=[
448 ofp.bucket(actions=[ofp.action.output(port1)]),
449 ofp.bucket(actions=[ofp.action.output(port2)])])
450
451 response, _ = self.controller.transact(msg)
452 self.assertIsInstance(response, ofp.message.error_msg)
453 self.assertEquals(response.err_type, ofp.OFPET_GROUP_MOD_FAILED)
454 self.assertEquals(response.code, ofp.OFPGMFC_INVALID_GROUP)
455
456
457class GroupStats(GroupTest):
458 """
459 A group stats request should return an entry for the specified group
460 """
461
462 def runTest(self):
463 port1, port2, = openflow_ports(2)
464
465 msg = ofp.message.group_mod(
466 command=ofp.OFPGC_ADD,
467 group_type=ofp.OFPGT_ALL,
468 group_id=10,
469 buckets=[
470 ofp.bucket(actions=[
471 ofp.action.set_field(ofp.oxm.tcp_src(2000)),
472 ofp.action.output(port1)]),
473 ofp.bucket(actions=[
474 ofp.action.set_field(ofp.oxm.tcp_src(3000)),
475 ofp.action.output(port2)])])
476
477 self.controller.message_send(msg)
478 do_barrier(self.controller)
479
480 request = ofp.message.group_stats_request(group_id=10)
481 stats = get_stats(self, request)
482
483 self.assertEquals(len(stats), 1)
484 self.assertEquals(stats[0].group_id, 10)
485 self.assertEquals(stats[0].ref_count, 0)
486 self.assertEquals(stats[0].packet_count, 0)
487 self.assertEquals(stats[0].byte_count, 0)
488 self.assertEquals(len(stats[0].bucket_stats), 2)
489
490
491class GroupStatsNonexistent(GroupTest):
492 """
493 A group stats request for a nonexistent group should return an empty list
494 """
495
496 def runTest(self):
497 request = ofp.message.group_stats_request(group_id=10)
498 stats = get_stats(self, request)
499 self.assertEquals(len(stats), 0)
500
501
502class GroupStatsAll(GroupTest):
503 """
504 A group stats request with OFPG_ALL should return an entry for each group
505 """
506
507 def runTest(self):
508 port1, port2, = openflow_ports(2)
509
510 msg0 = ofp.message.group_mod(
511 command=ofp.OFPGC_ADD,
512 group_type=ofp.OFPGT_ALL,
513 group_id=0,
514 buckets=[
515 ofp.bucket(actions=[
516 ofp.action.set_field(ofp.oxm.tcp_src(2000)),
517 ofp.action.output(port1)]),
518 ofp.bucket(actions=[
519 ofp.action.set_field(ofp.oxm.tcp_src(3000)),
520 ofp.action.output(port2)])])
521
522 self.controller.message_send(msg0)
523 do_barrier(self.controller)
524
525 msg1 = ofp.message.group_mod(
526 command=ofp.OFPGC_ADD,
527 group_type=ofp.OFPGT_ALL,
528 group_id=1,
529 buckets=[
530 ofp.bucket(actions=[
531 ofp.action.set_field(ofp.oxm.tcp_src(2001)),
532 ofp.action.output(port1)]),
533 ofp.bucket(actions=[
534 ofp.action.set_field(ofp.oxm.tcp_src(3001)),
535 ofp.action.output(port2)])])
536
537 self.controller.message_send(msg1)
538 do_barrier(self.controller)
539
540 request = ofp.message.group_stats_request(group_id=ofp.OFPG_ALL)
541 stats = sorted(get_stats(self, request), key=lambda x: x.group_id)
542
543 self.assertEquals(len(stats), 2)
544
545 self.assertEquals(stats[0].group_id, 0)
546 self.assertEquals(stats[0].ref_count, 0)
547 self.assertEquals(stats[0].packet_count, 0)
548 self.assertEquals(stats[0].byte_count, 0)
549 self.assertEquals(len(stats[0].bucket_stats), 2)
550
551 self.assertEquals(stats[1].group_id, 1)
552 self.assertEquals(stats[1].ref_count, 0)
553 self.assertEquals(stats[1].packet_count, 0)
554 self.assertEquals(stats[1].byte_count, 0)
555 self.assertEquals(len(stats[1].bucket_stats), 2)
556
557
558class GroupDescStats(GroupTest):
559 """
560 A group desc stats request should return the type, id, and buckets for each group
561 """
562
563 def runTest(self):
564 port1, port2, port3, = openflow_ports(3)
565
566 msg0 = ofp.message.group_mod(
567 command=ofp.OFPGC_ADD,
568 group_type=ofp.OFPGT_ALL,
569 group_id=0,
570 buckets=[
571 ofp.bucket(actions=[
572 ofp.action.set_field(ofp.oxm.tcp_src(2000)),
573 ofp.action.output(port1)]),
574 ofp.bucket(actions=[
575 ofp.action.set_field(ofp.oxm.tcp_src(3000)),
576 ofp.action.output(port2)]),
577 ofp.bucket(actions=[
578 ofp.action.set_field(ofp.oxm.tcp_src(4000)),
579 ofp.action.output(port3)])])
580
581 self.controller.message_send(msg0)
582 do_barrier(self.controller)
583
584 msg1 = ofp.message.group_mod(
585 command=ofp.OFPGC_ADD,
586 group_type=ofp.OFPGT_SELECT,
587 group_id=1,
588 buckets=[
589 ofp.bucket(
590 weight=1,
591 actions=[
592 ofp.action.set_field(ofp.oxm.tcp_src(2001)),
593 ofp.action.output(port1)]),
594 ofp.bucket(
595 weight=2,
596 actions=[
597 ofp.action.set_field(ofp.oxm.tcp_src(3001)),
598 ofp.action.output(port2)]),
599 ofp.bucket(
600 weight=3,
601 actions=[
602 ofp.action.set_field(ofp.oxm.tcp_src(4001)),
603 ofp.action.output(port3)])])
604
605 self.controller.message_send(msg1)
606 do_barrier(self.controller)
607
608 msg2 = ofp.message.group_mod(
609 command=ofp.OFPGC_ADD,
610 group_type=ofp.OFPGT_FF,
611 group_id=2,
612 buckets=[
613 ofp.bucket(
614 watch_port=port1,
615 actions=[
616 ofp.action.set_field(ofp.oxm.tcp_src(2002)),
617 ofp.action.output(port1)]),
618 ofp.bucket(
619 watch_port=port2,
620 actions=[
621 ofp.action.set_field(ofp.oxm.tcp_src(3002)),
622 ofp.action.output(port2,)]),
623 ofp.bucket(
624 watch_port=port3,
625 actions=[
626 ofp.action.set_field(ofp.oxm.tcp_src(4002)),
627 ofp.action.output(port3,)])])
628
629 self.controller.message_send(msg2)
630 do_barrier(self.controller)
631
632 request = ofp.message.group_desc_stats_request()
633 stats = sorted(get_stats(self, request), key=lambda x: x.group_id)
634
635 self.assertEquals(len(stats), 3)
636
637 self.assertEquals(stats[0].group_id, msg0.group_id)
638 self.assertEquals(stats[0].type, msg0.group_type)
639 self.assertEquals(stats[0].buckets, msg0.buckets)
640
641 self.assertEquals(stats[1].group_id, msg1.group_id)
642 self.assertEquals(stats[1].type, msg1.group_type)
643 self.assertEquals(stats[1].buckets, msg1.buckets)
644
645 self.assertEquals(stats[2].group_id, msg2.group_id)
646 self.assertEquals(stats[2].type, msg2.group_type)
647 self.assertEquals(stats[2].buckets, msg2.buckets)
648
649
650class GroupFlowSelect(GroupTest):
651 """
652 A flow stats request qualified on group id should select the correct flows
653 """
654
655 def runTest(self):
656 port1, = openflow_ports(1)
657
658 msg = ofp.message.group_mod(
659 command=ofp.OFPGC_ADD,
660 group_type=ofp.OFPGT_ALL,
661 group_id=1,
662 buckets=[])
663
664 self.controller.message_send(msg)
665 do_barrier(self.controller)
666
667 msg = ofp.message.group_mod(
668 command=ofp.OFPGC_ADD,
669 group_type=ofp.OFPGT_ALL,
670 group_id=2,
671 buckets=[])
672
673 self.controller.message_send(msg)
674 do_barrier(self.controller)
675
676 packet_in1 = simple_tcp_packet(tcp_sport=1000)
677
678 flow_add_msg1 = flow_msg_create(
679 self,
680 packet_in1,
681 ing_port=1,
682 action_list=[
683 ofp.action.group(1),
684 ofp.action.output(port1)])
685
686 self.controller.message_send(flow_add_msg1)
687 do_barrier(self.controller)
688
689 packet_in2 = simple_tcp_packet(tcp_sport=2000)
690
691 flow_add_msg2 = flow_msg_create(
692 self,
693 packet_in2,
694 ing_port=1,
695 action_list=[
696 ofp.action.group(2),
697 ofp.action.output(port1)])
698
699 self.controller.message_send(flow_add_msg2)
700 do_barrier(self.controller)
701
702 packet_in3 = simple_tcp_packet(tcp_sport=3000)
703
704 flow_add_msg3 = flow_msg_create(
705 self,
706 packet_in3,
707 ing_port=1,
708 action_list=[
709 ofp.action.group(2),
710 ofp.action.output(port1)])
711
712 self.controller.message_send(flow_add_msg3)
713 do_barrier(self.controller)
714
715 packet_in4 = simple_tcp_packet(tcp_sport=4000)
716
717 flow_add_msg4 = flow_msg_create(
718 self,
719 packet_in4,
720 ing_port=1,
721 action_list=[
722 ofp.action.output(port1)])
723
724 self.controller.message_send(flow_add_msg4)
725 do_barrier(self.controller)
726
727 request = ofp.message.aggregate_stats_request(
728 table_id=ofp.OFPTT_ALL,
729 out_port=ofp.OFPP_ANY,
730 out_group=2)
731
732 response, _ = self.controller.transact(request)
733
734 self.assertEqual(response.flow_count, 2,
735 'Did not match expected flow count')