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