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