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