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