blob: 999604b53e9a63bf64a56c22d664cc0b15b85bd3 [file] [log] [blame]
Rich Laneea873262013-01-11 08:15:55 -08001"""
2Group table test cases.
3"""
4import time
5import signal
6import sys
7import logging
8import unittest
9
10from oftest import config
11import of12 as ofp
12import oftest.oft12.testutils as testutils
13import oftest.base_tests as base_tests
14
15def create_group_desc_stats_req():
16 # XXX Zoltan: hack, remove if message module is fixed
17 m = ofp.message.group_desc_stats_request()
18
19 return m
20
21
22
23def create_group_stats_req(group_id = 0):
24 m = ofp.message.group_stats_request()
25 m.group_id = group_id
26
27 return m
28
29
30
31def create_group_mod_msg(command = ofp.OFPGC_ADD, type = ofp.OFPGT_ALL,
32 group_id = 0, buckets = []):
33 m = ofp.message.group_mod()
34 m.command = command
35 m.type = type
36 m.group_id = group_id
37 for b in buckets:
38 m.buckets.add(b)
39
40 return m
41
42
43
44# XXX Zoltan: watch_port/_group off ?
45def create_bucket(weight = 0, watch_port = 0, watch_group = 0, actions=[]):
46 b = ofp.bucket.bucket()
47 b.weight = weight
48 b.watch_port = watch_port
49 b.watch_group = watch_group
50 for a in actions:
51 b.actions.add(a)
52
53 return b
54
55
56
57def create_action(**kwargs):
58 a = kwargs.get('action')
59 if a == ofp.OFPAT_OUTPUT:
60 act = ofp.action.action_output()
61 act.port = kwargs.get('port', 1)
62 return act
63 if a == ofp.OFPAT_GROUP:
64 act = ofp.action.action_group()
65 act.group_id = kwargs.get('group_id', 0)
66 return act
67 if a == ofp.OFPAT_SET_FIELD:
68 port = kwargs.get('tcp_sport', 0)
69 field_2b_set = ofp.match.tcp_src(port)
70 act = ofp.action.action_set_field()
71 act.field = field_2b_set
72 return act;
73
74
75
76def create_flow_msg(packet = None, in_port = None, match = None, apply_action_list = []):
77
78 apply_inst = ofp.instruction.instruction_apply_actions()
79
80 if apply_action_list is not None:
81 for act in apply_action_list:
82 apply_inst.actions.add(act)
83
84 request = ofp.message.flow_mod()
85 request.match.type = ofp.OFPMT_OXM
86
87 if match is None:
88 match = ofp.parse.packet_to_flow_match(packet)
89
90 request.match_fields = match
91
92 if in_port != None:
93 match_port = testutils.oxm_field.in_port(in_port)
94 request.match_fields.tlvs.append(match_port)
95 request.buffer_id = 0xffffffff
96 request.priority = 1000
97
98 request.instructions.add(apply_inst)
99
100 return request
101
102
103
104class GroupTest(base_tests.SimpleDataPlane):
105
106 def clear_switch(self):
107 testutils.delete_all_flows(self.controller, logging)
108 testutils.delete_all_groups(self.controller, logging)
109
110 def send_ctrl_exp_noerror(self, msg, log = ''):
111 logging.info('Sending message ' + log)
112# logging.debug(msg.show())
113 rv = self.controller.message_send(msg)
114 self.assertTrue(rv != -1, 'Error sending!')
115
116 logging.info('Waiting for error messages...')
117 (response, raw) = self.controller.poll(ofp.OFPT_ERROR, 1)
118
119 self.assertTrue(response is None, 'Unexpected error message received')
120
121 testutils.do_barrier(self.controller);
122
123
124
125 def send_ctrl_exp_error(self, msg, log = '', type = 0, code = 0):
126 logging.info('Sending message ' + log)
127 logging.debug(msg.show())
128 rv = self.controller.message_send(msg)
129 self.assertTrue(rv != -1, 'Error sending!')
130
131 logging.info('Waiting for error messages...')
132 (response, raw) = self.controller.poll(ofp.OFPT_ERROR, 1)
133
134 self.assertTrue(response is not None,
135 'Did not receive an error message')
136
137 self.assertEqual(response.header.type, ofp.OFPT_ERROR,
138 'Did not receive an error message')
139
140 if type != 0:
141 self.assertEqual(response.type, type,
142 'Did not receive a ' + str(type) + ' type error message')
143
144 if code != 0:
145 self.assertEqual(response.code, code,
146 'Did not receive a ' + str(code) + ' code error message')
147
148 testutils.do_barrier(self.controller);
149
150
151
152 def send_ctrl_exp_reply(self, msg, resp_type = ofp.OFPT_ERROR, log = ''):
153 logging.info('Sending message ' + log)
154 logging.debug(msg.show())
155 rv = self.controller.message_send(msg)
156 self.assertTrue(rv != -1, 'Error sending!')
157
158 logging.info('Waiting for error messages...')
159 (response, raw) = self.controller.poll(resp_type, 1)
160
161 self.assertTrue(response is not None, 'Did not receive expected message')
162
163 return response
164
165
166
167 def send_data(self, packet, in_port):
168 self.logger.debug("Send packet on port " + str(in_port))
169 self.dataplane.send(in_port, str(packet))
170
171
172 def recv_data(self, port, expected = None):
173 pkt = testutils.receive_pkt_verify(self, port, expected)
174 return pkt
175
176"""
177Management
178"""
179
180class GroupAdd(GroupTest):
181 """
182 A regular group should be added successfully (without errors)
183 """
184
185 def runTest(self):
186 self.clear_switch()
187
188 group_add_msg = \
189 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
190 create_bucket(0, 0, 0, [
191 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
192 ])
193 ])
194
195 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
196
197
198
199class GroupAddInvalidAction(GroupTest):
200 """
201 If any action in the buckets is invalid, OFPET_BAD_ACTION/<code> should be returned
202 """
203
204 def runTest(self):
205 self.clear_switch()
206
207 group_add_msg = \
208 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
209 create_bucket(0, 0, 0, [
210 create_action(action= ofp.OFPAT_OUTPUT, port= ofp.OFPP_ANY)
211 ])
212 ])
213
214 self.send_ctrl_exp_error(group_add_msg, 'group add',
215 ofp.OFPET_BAD_ACTION,
216 ofp.OFPBAC_BAD_OUT_PORT)
217
218
219
220class GroupAddExisting(GroupTest):
221 """
222 An addition with existing group id should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_GROUP_EXISTS
223 """
224
225 def runTest(self):
226 self.clear_switch()
227
228 group_add_msg = \
229 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
230 create_bucket(0, 0, 0, [
231 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
232 ])
233 ])
234
235 self.send_ctrl_exp_noerror(group_add_msg, 'group add 1')
236
237 group_mod_msg2 = \
238 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
239 create_bucket(0, 0, 0, [
240 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
241 ])
242 ])
243
244 self.send_ctrl_exp_error(group_add_msg, 'group add 2',
245 ofp.OFPET_GROUP_MOD_FAILED,
246 ofp.OFPGMFC_GROUP_EXISTS)
247
248
249
250class GroupAddInvalidID(GroupTest):
251 """
252 An addition with invalid group id (reserved) should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_INVALID_GROUP
253 """
254
255 def runTest(self):
256 self.clear_switch()
257
258 group_add_msg = \
259 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = ofp.OFPG_ALL, buckets = [
260 create_bucket(0, 0, 0, [
261 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
262 ])
263 ])
264
265 self.send_ctrl_exp_error(group_add_msg, 'group add',
266 ofp.OFPET_GROUP_MOD_FAILED,
267 ofp.OFPGMFC_INVALID_GROUP)
268
269
270
271class GroupMod(GroupTest):
272 """
273 A regular group modification should be successful (no errors)
274 """
275
276 def runTest(self):
277 self.clear_switch()
278
279 group_add_msg = \
280 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
281 create_bucket(0, 0, 0, [
282 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
283 ])
284 ])
285
286 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
287
288 group_mod_msg = \
289 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = 0, buckets = [
290 create_bucket(0, 0, 0, [
291 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
292 ])
293 ])
294
295 self.send_ctrl_exp_noerror(group_mod_msg, 'group mod')
296
297
298
299class GroupModNonexisting(GroupTest):
300 """
301 A modification for non-existing group should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_UNKNOWN_GROUP
302 """
303
304 def runTest(self):
305 self.clear_switch()
306
307 group_add_msg = \
308 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
309 create_bucket(0, 0, 0, [
310 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
311 ])
312 ])
313
314 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
315
316 group_mod_msg = \
317 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = 1, buckets = [
318 create_bucket(0, 0, 0, [
319 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
320 ])
321 ])
322
323 self.send_ctrl_exp_error(group_mod_msg, 'group mod',
324 ofp.OFPET_GROUP_MOD_FAILED,
325 ofp.OFPGMFC_UNKNOWN_GROUP)
326
327
328
329class GroupModLoop(GroupTest):
330 """
331 A modification causing loop should result in OFPET_GROUP_MOD_FAILED/OFPGMFC_LOOP
332 """
333
334 def runTest(self):
335 self.clear_switch()
336
337 group_add_msg1 = \
338 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
339 create_bucket(0, 0, 0, [
340 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
341 ])
342 ])
343
344 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
345
346 group_add_msg2 = \
347 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
348 create_bucket(0, 0, 0, [
349 create_action(action= ofp.OFPAT_GROUP, group_id= 0)
350 ])
351 ])
352
353 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
354
355 group_add_msg3 = \
356 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [
357 create_bucket(0, 0, 0, [
358 create_action(action= ofp.OFPAT_GROUP, group_id= 0)
359 ])
360 ])
361
362 self.send_ctrl_exp_noerror(group_add_msg3, 'group add 3')
363
364
365 group_mod_msg = \
366 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = 0, buckets = [
367 create_bucket(0, 0, 0, [
368 create_action(action= ofp.OFPAT_GROUP, group_id= 2)
369 ])
370 ])
371
372 self.send_ctrl_exp_error(group_mod_msg, 'group mod',
373 ofp.OFPET_GROUP_MOD_FAILED,
374 ofp.OFPGMFC_LOOP)
375
376
377
378class GroupModInvalidID(GroupTest):
379 """
380 A modification for reserved group should result in OFPET_BAD_ACTION/OFPGMFC_INVALID_GROUP
381 """
382
383 def runTest(self):
384 self.clear_switch()
385
386 group_mod_msg = \
387 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = ofp.OFPG_ALL, buckets = [
388 create_bucket(0, 0, 0, [
389 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
390 ])
391 ])
392
393 self.send_ctrl_exp_error(group_mod_msg, 'group mod',
394 ofp.OFPET_GROUP_MOD_FAILED,
395 ofp.OFPGMFC_INVALID_GROUP)
396
397
398
399class GroupModEmpty(GroupTest):
400 """
401 A modification for existing group with no buckets should be accepted
402 """
403
404 def runTest(self):
405 self.clear_switch()
406
407 group_add_msg = \
408 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
409 create_bucket(0, 0, 0, [
410 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
411 ])
412 ])
413
414 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
415
416 group_mod_msg = \
417 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = 0, buckets = [
418 ])
419
420 self.send_ctrl_exp_noerror(group_mod_msg, 'group mod')
421
422
423
424class GroupDelExisting(GroupTest):
425 """
426 A deletion for existing group should remove the group
427 """
428
429 def runTest(self):
430 #self.clear_switch()
431
432 group_add_msg = \
433 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 10, buckets = [
434 create_bucket(0, 0, 0, [
435 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
436 ])
437 ])
438
439 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
440
441 group_del_msg = \
442 create_group_mod_msg(ofp.OFPGC_DELETE, ofp.OFPGT_ALL, group_id = 10, buckets = [
443 ])
444
445 self.send_ctrl_exp_noerror(group_del_msg, 'group del')
446
447# self.send_ctrl_exp_noerror(group_add_msg, 'group add')
448
449
450
451
452class GroupDelNonexisting(GroupTest):
453 """
454 A deletion for nonexisting group should result in no error
455 """
456
457 def runTest(self):
458 #self.clear_switch()
459
460 group_add_msg = \
461 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
462 create_bucket(0, 0, 0, [
463 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
464 ])
465 ])
466
467# self.send_ctrl_exp_noerror(group_add_msg, 'group add')
468
469 group_del_msg = \
470 create_group_mod_msg(ofp.OFPGC_DELETE, ofp.OFPGT_ALL, group_id = 10, buckets = [
471 ])
472
473 self.send_ctrl_exp_noerror(group_del_msg, 'group del')
474
475
476
477class GroupDelAll(GroupTest):
478 """
479 #@todo: A deletion for OFGP_ALL should remove all groups
480 """
481
482 def runTest(self):
483 self.clear_switch()
484
485 group_add_msg1 = \
486 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
487 create_bucket(0, 0, 0, [
488 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
489 ])
490 ])
491
492 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
493
494 group_add_msg2 = \
495 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [
496 create_bucket(0, 0, 0, [
497 create_action(action= ofp.OFPAT_OUTPUT, port= 1)
498 ])
499 ])
500
501 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
502
503 group_del_msg = \
504 create_group_mod_msg(ofp.OFPGC_DELETE, group_id = ofp.OFPG_ALL)
505
506 self.send_ctrl_exp_noerror(group_del_msg, 'group del')
507
508# self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
509# self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
510
511
512"""
513Management (specific)
514"""
515
516class GroupAddAllWeight(GroupTest):
517 """
518 An ALL group with weights for buckets should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
519 """
520
521 def runTest(self):
522 self.clear_switch()
523
524 group_add_msg = \
525 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 0, buckets = [
526 create_bucket(1, 0, 0, [
527 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
528 ]),
529 create_bucket(2, 0, 0, [
530 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
531 ])
532 ])
533
534 self.send_ctrl_exp_error(group_add_msg, 'group add',
535 ofp.OFPET_GROUP_MOD_FAILED,
536 ofp.OFPGMFC_INVALID_GROUP)
537
538
539
540class GroupAddIndirectWeight(GroupTest):
541 """
542 An INDIRECT group with weights for buckets should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
543 """
544
545 def runTest(self):
546 self.clear_switch()
547
548 group_add_msg = \
549 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_INDIRECT, group_id = 0, buckets = [
550 create_bucket(1, 0, 0, [
551 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
552 ])
553 ])
554
555 self.send_ctrl_exp_error(group_add_msg, 'group add',
556 ofp.OFPET_GROUP_MOD_FAILED,
557 ofp.OFPGMFC_INVALID_GROUP)
558
559
560
561class GroupAddIndirectBuckets(GroupTest):
562 """
563 An INDIRECT group with <>1 bucket should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
564 """
565
566 def runTest(self):
567 self.clear_switch()
568
569 group_add_msg = \
570 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_INDIRECT, group_id = 0, buckets = [
571 create_bucket(0, 0, 0, [
572 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
573 ]),
574 create_bucket(0, 0, 0, [
575 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
576 ])
577 ])
578
579 self.send_ctrl_exp_error(group_add_msg, 'group add',
580 ofp.OFPET_GROUP_MOD_FAILED,
581 ofp.OFPGMFC_INVALID_GROUP)
582
583
584
585class GroupAddSelectNoWeight(GroupTest):
586 """
587 A SELECT group with ==0 weights should result in OFPET_GROUP_MOD_FAILED, OFPGMFC_INVALID_GROUP
588 """
589
590 def runTest(self):
591 self.clear_switch()
592
593 group_add_msg = \
594 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id = 0, buckets = [
595 create_bucket(0, 0, 0, [
596 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
597 ]),
598 create_bucket(0, 0, 0, [
599 create_action(action= ofp.OFPAT_OUTPUT, port= 2)
600 ])
601 ])
602
603 self.send_ctrl_exp_error(group_add_msg, 'group add',
604 ofp.OFPET_GROUP_MOD_FAILED,
605 ofp.OFPGMFC_INVALID_GROUP)
606
607
608"""
609Action
610"""
611
612#@todo: A group action with invalid id should result in error
613#@todo: A group action for nonexisting group should result in error
614
615
616"""
617Working
618"""
619
620class GroupProcEmpty(GroupTest):
621 """
622 A group with no buckets should not alter the action set of the packet
623 """
624
625 def runTest(self):
626
627 self.clear_switch()
628
629 group_add_msg = \
630 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
631 ])
632
633 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
634
635 packet_in = testutils.simple_tcp_packet()
636
637 flow_add_msg = \
638 create_flow_msg(packet = packet_in, in_port = 1, apply_action_list = [
639 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
640 ])
641
642 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
643
644 self.send_data(packet_in, 1)
645
646 self.recv_data(2, None)
647
648class GroupProcSimple(GroupTest):
649 """
650 A group should apply its actions on packets
651 """
652
653 def runTest(self):
654# self.clear_switch()
655 testutils.clear_switch(self,config["port_map"],logging)
656
657 group_add_msg = \
658 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
659 create_bucket(0, 0, 0, [
660 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
661 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
662 ])
663 ])
664
665 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
666
667 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
668 packet_out = testutils.simple_tcp_packet(tcp_sport=2000)
669
670 flow_add_msg = \
671 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
672 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
673 ])
674
675 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
676
677 self.send_data(packet_in, 1)
678
679 self.recv_data(2, packet_out)
680
681
682
683class GroupProcMod(GroupTest):
684 """
685 A modification for existing group should modify the group
686 """
687
688 def runTest(self):
689 testutils.clear_switch(self,config["port_map"],logging)
690# self.clear_switch()
691
692 group_add_msg = \
693 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
694 create_bucket(0, 0, 0, [
695 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
696 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
697 ])
698 ])
699
700 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
701
702 group_mod_msg = \
703 create_group_mod_msg(ofp.OFPGC_MODIFY, ofp.OFPGT_ALL, group_id = 1, buckets = [
704 create_bucket(0, 0, 0, [
705 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
706 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
707 ])
708 ])
709
710 self.send_ctrl_exp_noerror(group_mod_msg, 'group mod')
711
712
713 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
714 packet_out = testutils.simple_tcp_packet(tcp_sport=3000)
715
716 flow_add_msg = \
717 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
718 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
719 ])
720
721 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
722
723 self.send_data(packet_in, 1)
724
725 self.recv_data(2, packet_out)
726
727
728
729class GroupProcChain(GroupTest):
730 """
731 A group after a group should apply its actions on packets
732 """
733
734 def runTest(self):
735 self.clear_switch()
736
737 group_add_msg2 = \
738 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [
739 create_bucket(0, 0, 0, [
740 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
741 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
742 ])
743 ])
744
745 self.send_ctrl_exp_noerror(group_add_msg2, 'group add')
746
747 group_add_msg1 = \
748 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
749 create_bucket(0, 0, 0, [
750 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
751 ])
752 ])
753
754 self.send_ctrl_exp_noerror(group_add_msg1, 'group add')
755
756 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
757 packet_out = testutils.simple_tcp_packet(tcp_sport=2000)
758
759 flow_add_msg = \
760 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
761 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
762 ])
763
764 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
765
766 self.send_data(packet_in, 1)
767
768 self.recv_data(2, packet_out)
769
770
771
772"""
773Working (specific)
774"""
775
776class GroupProcAll(GroupTest):
777 """
778 An ALL group should use all of its buckets, modifying the resulting packet(s)
779 """
780
781 def runTest(self):
782 self.clear_switch()
783
784 group_add_msg = \
785 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
786 create_bucket(0, 0, 0, [
787 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
788 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
789 ]),
790 create_bucket(0, 0, 0, [
791 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
792 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
793 ]),
794 create_bucket(0, 0, 0, [
795 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 4000),
796 create_action(action = ofp.OFPAT_OUTPUT, port = 4)
797 ])
798 ])
799
800 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
801
802 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
803 packet_out1 = testutils.simple_tcp_packet(tcp_sport=2000)
804 packet_out2 = testutils.simple_tcp_packet(tcp_sport=3000)
805 packet_out3 = testutils.simple_tcp_packet(tcp_sport=4000)
806
807 flow_add_msg = \
808 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
809 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
810 ])
811
812 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
813
814 self.send_data(packet_in, 1)
815
816 self.recv_data(2, packet_out1)
817 self.recv_data(3, packet_out2)
818 self.recv_data(4, packet_out3)
819
820
821
822class GroupProcAllChain(GroupTest):
823 """
824 An ALL group should use all of its buckets, modifying the resulting packet(s)
825 """
826
827 def runTest(self):
828 self.clear_switch()
829
830 group_add_msg2 = \
831 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [
832 create_bucket(0, 0, 0, [
833 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
834 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
835 ])
836 ])
837
838 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
839
840 group_add_msg3 = \
841 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 3, buckets = [
842 create_bucket(0, 0, 0, [
843 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
844 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
845 ]),
846 create_bucket(0, 0, 0, [
847 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 4000),
848 create_action(action = ofp.OFPAT_OUTPUT, port = 4)
849 ])
850 ])
851
852 self.send_ctrl_exp_noerror(group_add_msg3, 'group add 3')
853
854 group_add_msg1 = \
855 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [
856 create_bucket(0, 0, 0, [
857 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
858 ]),
859 create_bucket(0, 0, 0, [
860 create_action(action = ofp.OFPAT_GROUP, group_id = 3),
861 ])
862 ])
863
864 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
865
866 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
867 packet_out1 = testutils.simple_tcp_packet(tcp_sport=2000)
868 packet_out2 = testutils.simple_tcp_packet(tcp_sport=3000)
869 packet_out3 = testutils.simple_tcp_packet(tcp_sport=4000)
870
871 flow_add_msg = \
872 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
873 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
874 ])
875
876 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
877
878 self.send_data(packet_in, 1)
879
880 self.recv_data(2, packet_out1)
881 self.recv_data(3, packet_out2)
882 self.recv_data(4, packet_out3)
883
884
885
886class GroupProcIndirect(GroupTest):
887 """
888 An INDIRECT group should use its only bucket
889 """
890
891 def runTest(self):
892 testutils.clear_switch(self,config["port_map"],logging)
893# self.clear_switch()
894
895 group_add_msg = \
896 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_INDIRECT, group_id = 1, buckets = [
897 create_bucket(0, 0, 0, [
898 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
899 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
900 ])
901 ])
902
903 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
904
905 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
906 packet_out = testutils.simple_tcp_packet(tcp_sport=2000)
907
908 flow_add_msg = \
909 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
910 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
911 ])
912
913 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
914
915 self.send_data(packet_in, 1)
916
917 self.recv_data(2, packet_out)
918
919
920
921class GroupProcSelect(GroupTest):
922 """
923 An ALL group should use all of its buckets, modifying the resulting packet(s)
924 """
925
926 def runTest(self):
927 testutils.clear_switch(self,config["port_map"],logging)
928# self.clear_switch()
929
930 group_add_msg = \
931 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id = 1, buckets = [
932 create_bucket(1, 0, 0, [
933 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
934 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
935 ]),
936 create_bucket(1, 0, 0, [
937 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
938 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
939 ]),
940 create_bucket(1, 0, 0, [
941 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 4000),
942 create_action(action = ofp.OFPAT_OUTPUT, port = 4)
943 ])
944 ])
945
946 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
947
948 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
949 packet_out1 = testutils.simple_tcp_packet(tcp_sport=2000)
950 packet_out2 = testutils.simple_tcp_packet(tcp_sport=3000)
951 packet_out3 = testutils.simple_tcp_packet(tcp_sport=4000)
952
953 flow_add_msg = \
954 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
955 create_action(action = ofp.OFPAT_GROUP, group_id = 1)
956 ])
957
958 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
959
960 self.send_data(packet_in, 1)
961
962 recv1 = self.recv_data(2)
963 recv2 = self.recv_data(3)
964 recv3 = self.recv_data(4)
965
966 self.assertTrue(((recv1 is not None) or (recv2 is not None) or (recv3 is not None)),
967 "Did not receive a packet")
968
969 self.assertTrue(((recv1 is not None) and (recv2 is None) and (recv3 is None)) or \
970 ((recv1 is None) and (recv2 is not None) and (recv3 is None)) or \
971 ((recv1 is None) and (recv2 is None) and (recv3 is not None)),
972 "Received too many packets")
973
974 self.assertTrue(((recv1 is not None) and testutils.pkt_verify(self, recv1, packet_out1)) or \
975 ((recv2 is not None) and testutils.pkt_verify(self, recv2, packet_out2)) or \
976 ((recv3 is not None) and testutils.pkt_verify(self, recv3, packet_out3)),
977 "Received unexpected packet")
978
979#@todo: A FF group should always use its first alive bucket
980
981
982"""
983Statistics
984"""
985
986#@todo A regular group added should increase the number of groups and buckets
987
988class GroupStats(GroupTest):
989 """
990 A packet sent to the group should increase byte/packet counters of group
991 """
992
993 def runTest(self):
994# self.clear_switch()
995 testutils.clear_switch(self,config["port_map"],logging)
996
997 group_add_msg = \
998 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 10, buckets = [
999 create_bucket(0, 0, 0, [
1000 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
1001 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1002 ]),
1003 create_bucket(0, 0, 0, [
1004 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
1005 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
1006 ])
1007 ])
1008
1009 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
1010
1011 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
1012
1013 flow_add_msg = \
1014 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
1015 create_action(action = ofp.OFPAT_GROUP, group_id = 10)
1016 ])
1017
1018 self.send_ctrl_exp_noerror(flow_add_msg, 'flow add')
1019
1020 self.send_data(packet_in, 1)
1021 self.send_data(packet_in, 1)
1022 self.send_data(packet_in, 1)
1023
1024 group_stats_req = \
1025 create_group_stats_req(10)
1026
1027 response = \
1028 self.send_ctrl_exp_reply(group_stats_req,
1029 ofp.OFPT_STATS_REPLY, 'group stat')
1030
1031 exp_len = ofp.OFP_HEADER_BYTES + \
1032 ofp.OFP_STATS_REPLY_BYTES + \
1033 ofp.OFP_GROUP_STATS_BYTES + \
1034 ofp.OFP_BUCKET_COUNTER_BYTES * 2
1035
1036 self.assertEqual(len(response), exp_len,
1037 'Received packet length does not equal expected length')
1038 # XXX Zoltan: oftest group_stats_req handling needs to be fixed
1039 # right now only the expected message length is checked
1040 # responses should be checked in Wireshark
1041
1042
1043
1044class GroupStatsAll(GroupTest):
1045 """
1046 A packet sent to the group should increase byte/packet counters of group
1047 """
1048
1049 def runTest(self):
1050# self.clear_switch()
1051 testutils.clear_switch(self,config["port_map"],logging)
1052
1053 group_add_msg1 = \
1054 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 10, buckets = [
1055 create_bucket(0, 0, 0, [
1056 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
1057 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1058 ]),
1059 create_bucket(0, 0, 0, [
1060 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
1061 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
1062 ])
1063 ])
1064
1065 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
1066
1067 group_add_msg2 = \
1068 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 20, buckets = [
1069 create_bucket(0, 0, 0, [
1070 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
1071 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1072 ]),
1073 create_bucket(0, 0, 0, [
1074 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
1075 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
1076 ])
1077 ])
1078
1079 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
1080
1081 packet_in = testutils.simple_tcp_packet(tcp_sport=1000)
1082
1083 flow_add_msg1 = \
1084 testutils.flow_msg_create(self,packet_in,ing_port = 1,action_list = [
1085 create_action(action = ofp.OFPAT_GROUP, group_id = 10)
1086 ])
1087
1088 self.send_ctrl_exp_noerror(flow_add_msg1, 'flow add 1')
1089
1090 flow_add_msg2 = \
1091 testutils.flow_msg_create(self,packet_in,ing_port = 2,action_list = [
1092 create_action(action = ofp.OFPAT_GROUP, group_id = 20)
1093 ])
1094
1095 self.send_ctrl_exp_noerror(flow_add_msg2, 'flow add 2')
1096
1097 self.send_data(packet_in, 1)
1098 self.send_data(packet_in, 1)
1099 self.send_data(packet_in, 2)
1100 self.send_data(packet_in, 2)
1101 self.send_data(packet_in, 2)
1102
1103 group_stats_req = \
1104 create_group_stats_req(ofp.OFPG_ALL)
1105
1106 response = \
1107 self.send_ctrl_exp_reply(group_stats_req,
1108 ofp.OFPT_STATS_REPLY, 'group stat')
1109
1110 exp_len = ofp.OFP_HEADER_BYTES + \
1111 ofp.OFP_STATS_REPLY_BYTES + \
1112 ofp.OFP_GROUP_STATS_BYTES + \
1113 ofp.OFP_BUCKET_COUNTER_BYTES * 2 + \
1114 ofp.OFP_GROUP_STATS_BYTES + \
1115 ofp.OFP_BUCKET_COUNTER_BYTES * 2
1116
1117 self.assertEqual(len(response), exp_len,
1118 'Received packet length does not equal expected length')
1119 # XXX Zoltan: oftest group_stats_req handling needs to be fixed
1120 # right now only the expected message length is checked
1121 # responses should be checked in Wireshark
1122
1123
1124
1125class GroupDescStats(GroupTest):
1126 """
1127 Desc stats of a group should work
1128 """
1129
1130 def runTest(self):
1131 self.clear_switch()
1132
1133 b1 = create_bucket(0, 0, 0, [
1134 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 2000),
1135 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1136 ])
1137 b2 = create_bucket(0, 0, 0, [
1138 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 3000),
1139 create_action(action = ofp.OFPAT_OUTPUT, port = 3)
1140 ])
1141 b3 = create_bucket(0, 0, 0, [
1142 create_action(action = ofp.OFPAT_SET_FIELD, tcp_sport = 4000),
1143 create_action(action = ofp.OFPAT_OUTPUT, port = 4)
1144 ])
1145
1146 group_add_msg = \
1147 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 10, buckets = [b1, b2, b3])
1148
1149 self.send_ctrl_exp_noerror(group_add_msg, 'group add')
1150
1151 group_desc_stats_req = \
1152 create_group_desc_stats_req()
1153
1154 response = \
1155 self.send_ctrl_exp_reply(group_desc_stats_req,
1156 ofp.OFPT_STATS_REPLY, 'group desc stat')
1157
1158 exp_len = ofp.OFP_HEADER_BYTES + \
1159 ofp.OFP_STATS_REPLY_BYTES + \
1160 ofp.OFP_GROUP_DESC_STATS_BYTES + \
1161 len(b1) + len(b2) + len(b3)
1162
1163 self.assertEqual(len(response), exp_len,
1164 'Received packet length does not equal expected length')
1165 # XXX Zoltan: oftest group_stats_req handling needs to be fixed
1166 # right now only the expected message length is checked
1167 # responses should be checked in Wireshark
1168
1169
1170#@todo: A flow added with group action should increase the ref counter of the ref. group
1171#@todo: A flow removed with group action should decrease the ref counter of the ref. group
1172#@todo: A group added with group action should increase the ref counter of the ref. group
1173#@todo: A group removed with group action should decrease the ref counter of the ref. group
1174
1175
1176"""
1177Flows
1178"""
1179
1180#@todo: A deletion for existing group should remove flows referring to that group
1181#@todo: A flow added referencing a nonexisting group should return an error
1182
1183"""
1184Flow select
1185"""
1186
1187class GroupFlowSelect(GroupTest):
1188 """
1189 A group action select with group id should select the correct flows only
1190 """
1191
1192 def runTest(self):
1193 self.clear_switch()
1194
1195 group_add_msg1 = \
1196 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [])
1197
1198 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
1199
1200 group_add_msg2 = \
1201 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [])
1202
1203 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
1204
1205 packet_in1 = testutils.simple_tcp_packet(tcp_sport=1000)
1206
1207 flow_add_msg1 = \
1208 testutils.flow_msg_create(self,packet_in1,ing_port = 1,action_list = [
1209 create_action(action = ofp.OFPAT_GROUP, group_id = 1),
1210 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1211 ])
1212
1213 self.send_ctrl_exp_noerror(flow_add_msg1, 'flow add 1')
1214
1215 packet_in2 = testutils.simple_tcp_packet(tcp_sport=2000)
1216
1217 flow_add_msg2 = \
1218 testutils.flow_msg_create(self,packet_in2,ing_port = 1,action_list = [
1219 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
1220 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1221 ])
1222
1223 self.send_ctrl_exp_noerror(flow_add_msg2, 'flow add 2')
1224
1225 packet_in3 = testutils.simple_tcp_packet(tcp_sport=3000)
1226
1227 flow_add_msg3 = \
1228 testutils.flow_msg_create(self,packet_in3,ing_port = 1,action_list = [
1229 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
1230 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1231 ])
1232
1233 self.send_ctrl_exp_noerror(flow_add_msg3, 'flow add 3')
1234
1235 packet_in4 = testutils.simple_tcp_packet(tcp_sport=4000)
1236
1237 flow_add_msg4 = \
1238 testutils.flow_msg_create(self,packet_in4,ing_port = 1,action_list = [
1239 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1240 ])
1241
1242 self.send_ctrl_exp_noerror(flow_add_msg4, 'flow add 4')
1243
1244 aggr_stat_req = ofp.message.aggregate_stats_request()
1245 aggr_stat_req.table_id = 0xff
1246 aggr_stat_req.out_port = ofp.OFPP_ANY
1247 aggr_stat_req.out_group = 2
1248
1249 response = \
1250 self.send_ctrl_exp_reply(aggr_stat_req,
1251 ofp.OFPT_STATS_REPLY, 'aggr stat')
1252
1253 self.assertEqual(response.stats[0].flow_count, 2,
1254 'Did not match expected flow count')
1255
1256class GroupFlowSelectAll(GroupTest):
1257 """
1258 A group action select with OFPG_ALL should ignore output group action
1259 """
1260
1261 def runTest(self):
1262 self.clear_switch()
1263
1264 group_add_msg1 = \
1265 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 1, buckets = [])
1266
1267 self.send_ctrl_exp_noerror(group_add_msg1, 'group add 1')
1268
1269 group_add_msg2 = \
1270 create_group_mod_msg(ofp.OFPGC_ADD, ofp.OFPGT_ALL, group_id = 2, buckets = [])
1271
1272 self.send_ctrl_exp_noerror(group_add_msg2, 'group add 2')
1273
1274 packet_in1 = testutils.simple_tcp_packet(tcp_sport=1000)
1275
1276 flow_add_msg1 = \
1277 testutils.flow_msg_create(self,packet_in1,ing_port = 1,action_list = [
1278 create_action(action = ofp.OFPAT_GROUP, group_id = 1),
1279 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1280 ])
1281
1282 self.send_ctrl_exp_noerror(flow_add_msg1, 'flow add 1')
1283
1284 packet_in2 = testutils.simple_tcp_packet(tcp_sport=2000)
1285
1286 flow_add_msg2 = \
1287 testutils.flow_msg_create(self,packet_in2,ing_port = 1,action_list = [
1288 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
1289 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1290 ])
1291
1292 self.send_ctrl_exp_noerror(flow_add_msg2, 'flow add 2')
1293
1294 packet_in3 = testutils.simple_tcp_packet(tcp_sport=3000)
1295
1296 flow_add_msg3 = \
1297 testutils.flow_msg_create(self,packet_in3,ing_port = 1,action_list = [
1298 create_action(action = ofp.OFPAT_GROUP, group_id = 2),
1299 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1300 ])
1301
1302 self.send_ctrl_exp_noerror(flow_add_msg3, 'flow add 3')
1303
1304 packet_in4 = testutils.simple_tcp_packet(tcp_sport=4000)
1305
1306 flow_add_msg4 = \
1307 testutils.flow_msg_create(self,packet_in4,ing_port = 1,action_list = [
1308 create_action(action = ofp.OFPAT_OUTPUT, port = 2)
1309 ])
1310
1311 self.send_ctrl_exp_noerror(flow_add_msg4, 'flow add 4')
1312
1313 aggr_stat_req = ofp.message.aggregate_stats_request()
1314 aggr_stat_req.table_id = 0xff
1315 aggr_stat_req.out_port = ofp.OFPP_ANY
1316 aggr_stat_req.out_group = ofp.OFPG_ANY
1317
1318 response = \
1319 self.send_ctrl_exp_reply(aggr_stat_req,
1320 ofp.OFPT_STATS_REPLY, 'group desc stat')
1321
1322 self.assertEqual(response.stats[0].flow_count, 4,
1323 'Did not match expected flow count')
1324
1325
1326
1327
1328if __name__ == "__main__":
1329 print "Please run through oft script: ./oft --test_spec=basic"