blob: 1721be72780a7cab0936e298d61b15b95f5f30dd [file] [log] [blame]
Scott Baker456b8932019-10-24 10:36:39 -07001/*
2 * Copyright 2019-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 */
16package flows
17
18import (
Scott Bakerce767002019-10-23 13:30:24 -070019 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Bakerf1b096c2019-11-01 12:36:30 -070020 ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
Scott Baker456b8932019-10-24 10:36:39 -070021 "github.com/stretchr/testify/assert"
22 "google.golang.org/grpc/codes"
23 "google.golang.org/grpc/status"
24 "strings"
25 "testing"
26)
27
28var (
29 timeoutError error
30 taskFailureError error
31)
32
33func init() {
34 log.AddPackage(log.JSON, log.WarnLevel, nil)
35 timeoutError = status.Errorf(codes.Aborted, "timeout")
36 taskFailureError = status.Error(codes.Internal, "test failure task")
37 timeoutError = status.Errorf(codes.Aborted, "timeout")
38}
39
40func TestFlowsAndGroups_AddFlow(t *testing.T) {
41 fg := NewFlowsAndGroups()
42 allFlows := fg.ListFlows()
43 assert.Equal(t, 0, len(allFlows))
44 fg.AddFlow(nil)
45 allFlows = fg.ListFlows()
46 assert.Equal(t, 0, len(allFlows))
47
48 var fa *FlowArgs
49 fa = &FlowArgs{
50 KV: OfpFlowModArgs{"priority": 500},
51 MatchFields: []*ofp.OfpOxmOfbField{
52 InPort(1),
53 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1),
54 TunnelId(uint64(1)),
55 EthType(0x0800),
56 Ipv4Dst(0xffffffff),
57 IpProto(17),
58 UdpSrc(68),
59 UdpDst(67),
60 },
61 Actions: []*ofp.OfpAction{
62 PushVlan(0x8100),
63 SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
64 Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
65 },
66 }
67 flow := MkFlowStat(fa)
68 fg.AddFlow(flow)
69
70 allFlows = fg.ListFlows()
71 assert.Equal(t, 1, len(allFlows))
72 assert.True(t, FlowMatch(flow, allFlows[0]))
73}
74
75func TestFlowsAndGroups_AddGroup(t *testing.T) {
76 var ga *GroupArgs
77
78 fg := NewFlowsAndGroups()
79 allGroups := fg.ListGroups()
80 assert.Equal(t, 0, len(allGroups))
81 fg.AddGroup(nil)
82 allGroups = fg.ListGroups()
83 assert.Equal(t, 0, len(allGroups))
84
85 ga = &GroupArgs{
86 GroupId: 10,
87 Buckets: []*ofp.OfpBucket{
88 {Actions: []*ofp.OfpAction{
89 PopVlan(),
90 Output(1),
91 },
92 },
93 },
94 }
95 group := MkGroupStat(ga)
96 fg.AddGroup(group)
97
98 allGroups = fg.ListGroups()
99 assert.Equal(t, 1, len(allGroups))
100 assert.Equal(t, ga.GroupId, allGroups[0].Desc.GroupId)
101}
102
103func TestFlowsAndGroups_Copy(t *testing.T) {
104 fg := NewFlowsAndGroups()
105 var fa *FlowArgs
106 var ga *GroupArgs
107
108 fa = &FlowArgs{
109 KV: OfpFlowModArgs{"priority": 500},
110 MatchFields: []*ofp.OfpOxmOfbField{
111 InPort(2),
112 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
113 },
114 Actions: []*ofp.OfpAction{
115 SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 10)),
116 Output(1),
117 },
118 }
119 flow := MkFlowStat(fa)
120 fg.AddFlow(flow)
121
122 ga = &GroupArgs{
123 GroupId: 10,
124 Buckets: []*ofp.OfpBucket{
125 {Actions: []*ofp.OfpAction{
126 PopVlan(),
127 Output(1),
128 },
129 },
130 },
131 }
132 group := MkGroupStat(ga)
133 fg.AddGroup(group)
134
135 fgCopy := fg.Copy()
136
137 allFlows := fgCopy.ListFlows()
138 assert.Equal(t, 1, len(allFlows))
139 assert.True(t, FlowMatch(flow, allFlows[0]))
140
141 allGroups := fgCopy.ListGroups()
142 assert.Equal(t, 1, len(allGroups))
143 assert.Equal(t, ga.GroupId, allGroups[0].Desc.GroupId)
144
145 fg = NewFlowsAndGroups()
146 fgCopy = fg.Copy()
147 allFlows = fgCopy.ListFlows()
148 allGroups = fgCopy.ListGroups()
149 assert.Equal(t, 0, len(allFlows))
150 assert.Equal(t, 0, len(allGroups))
151}
152
153func TestFlowsAndGroups_GetFlow(t *testing.T) {
154 fg := NewFlowsAndGroups()
155 var fa1 *FlowArgs
156 var fa2 *FlowArgs
157 var ga *GroupArgs
158
159 fa1 = &FlowArgs{
160 KV: OfpFlowModArgs{"priority": 500},
161 MatchFields: []*ofp.OfpOxmOfbField{
162 InPort(2),
163 Metadata_ofp((1000 << 32) | 1),
164 VlanPcp(0),
165 },
166 Actions: []*ofp.OfpAction{
167 PopVlan(),
168 },
169 }
170 flow1 := MkFlowStat(fa1)
171
172 fa2 = &FlowArgs{
173 KV: OfpFlowModArgs{"priority": 1500},
174 MatchFields: []*ofp.OfpOxmOfbField{
175 InPort(5),
176 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
177 },
178 Actions: []*ofp.OfpAction{
179 PushVlan(0x8100),
180 SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
181 SetField(VlanPcp(0)),
182 Output(2),
183 },
184 }
185 flow2 := MkFlowStat(fa2)
186
187 fg.AddFlow(flow1)
188 fg.AddFlow(flow2)
189
190 ga = &GroupArgs{
191 GroupId: 10,
192 Buckets: []*ofp.OfpBucket{
193 {Actions: []*ofp.OfpAction{
194 PopVlan(),
195 Output(1),
196 },
197 },
198 },
199 }
200 group := MkGroupStat(ga)
201 fg.AddGroup(group)
202
203 gf1 := fg.GetFlow(0)
204 assert.True(t, FlowMatch(flow1, gf1))
205
206 gf2 := fg.GetFlow(1)
207 assert.True(t, FlowMatch(flow2, gf2))
208
209 gf3 := fg.GetFlow(2)
210 assert.Nil(t, gf3)
211
212 allFlows := fg.ListFlows()
213 assert.True(t, FlowMatch(flow1, allFlows[0]))
214 assert.True(t, FlowMatch(flow2, allFlows[1]))
215}
216
217func TestFlowsAndGroups_String(t *testing.T) {
218 fg := NewFlowsAndGroups()
219 var fa *FlowArgs
220 var ga *GroupArgs
221
222 str := fg.String()
223 assert.True(t, str == "")
224
225 fa = &FlowArgs{
226 KV: OfpFlowModArgs{"priority": 500},
227 MatchFields: []*ofp.OfpOxmOfbField{
228 InPort(2),
229 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
230 VlanPcp(0),
231 EthType(0x800),
232 Ipv4Dst(0xe00a0a0a),
233 },
234 Actions: []*ofp.OfpAction{
235 Group(10),
236 },
237 }
238 flow := MkFlowStat(fa)
239 fg.AddFlow(flow)
240
241 ga = &GroupArgs{
242 GroupId: 10,
243 Buckets: []*ofp.OfpBucket{
244 {Actions: []*ofp.OfpAction{
245 PopVlan(),
246 Output(1),
247 },
248 },
249 },
250 }
251 group := MkGroupStat(ga)
252 fg.AddGroup(group)
253
254 str = fg.String()
255 assert.True(t, strings.Contains(str, "id: 1143307409938767207"))
256 assert.True(t, strings.Contains(str, "group_id: 10"))
257 assert.True(t, strings.Contains(str, "oxm_class: OFPXMC_OPENFLOW_BASICOFPXMC_OPENFLOW_BASIC"))
258 assert.True(t, strings.Contains(str, "type: OFPXMT_OFB_VLAN_VIDOFPXMT_OFB_VLAN_VID"))
259 assert.True(t, strings.Contains(str, "vlan_vid: 4096"))
260 assert.True(t, strings.Contains(str, "buckets:"))
261}
262
263func TestFlowsAndGroups_AddFrom(t *testing.T) {
264 fg := NewFlowsAndGroups()
265 var fa *FlowArgs
266 var ga *GroupArgs
267
268 str := fg.String()
269 assert.True(t, str == "")
270
271 fa = &FlowArgs{
272 KV: OfpFlowModArgs{"priority": 500},
273 MatchFields: []*ofp.OfpOxmOfbField{
274 InPort(2),
275 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
276 Metadata_ofp(1000),
277 TunnelId(uint64(1)),
278 VlanPcp(0),
279 },
280 Actions: []*ofp.OfpAction{
281 PopVlan(),
282 Output(1),
283 },
284 }
285 flow := MkFlowStat(fa)
286 fg.AddFlow(flow)
287
288 ga = &GroupArgs{
289 GroupId: 10,
290 Buckets: []*ofp.OfpBucket{
291 {Actions: []*ofp.OfpAction{
292 PopVlan(),
293 Output(1),
294 },
295 },
296 },
297 }
298 group := MkGroupStat(ga)
299 fg.AddGroup(group)
300
301 fg1 := NewFlowsAndGroups()
302 fg1.AddFrom(fg)
303
304 allFlows := fg1.ListFlows()
305 allGroups := fg1.ListGroups()
306 assert.Equal(t, 1, len(allFlows))
307 assert.Equal(t, 1, len(allGroups))
308 assert.True(t, FlowMatch(flow, allFlows[0]))
309 assert.Equal(t, group.Desc.GroupId, allGroups[0].Desc.GroupId)
310}
311
312func TestDeviceRules_AddFlow(t *testing.T) {
313 dr := NewDeviceRules()
314 rules := dr.GetRules()
315 assert.True(t, len(rules) == 0)
316
317 dr.AddFlow("123456", nil)
318 rules = dr.GetRules()
319 assert.True(t, len(rules) == 1)
320 val, ok := rules["123456"]
321 assert.True(t, ok)
322 assert.Equal(t, 0, len(val.ListFlows()))
323 assert.Equal(t, 0, len(val.ListGroups()))
324
325 var fa *FlowArgs
326 fa = &FlowArgs{
327 KV: OfpFlowModArgs{"priority": 500},
328 MatchFields: []*ofp.OfpOxmOfbField{
329 InPort(2),
330 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
331 Metadata_ofp(1000),
332 TunnelId(uint64(1)),
333 VlanPcp(0),
334 },
335 Actions: []*ofp.OfpAction{
336 PopVlan(),
337 Output(1),
338 },
339 }
340 flow := MkFlowStat(fa)
341 dr.AddFlow("123456", flow)
342 rules = dr.GetRules()
343 assert.True(t, len(rules) == 1)
344 val, ok = rules["123456"]
345 assert.True(t, ok)
346 assert.Equal(t, 1, len(val.ListFlows()))
347 assert.True(t, FlowMatch(flow, val.ListFlows()[0]))
348 assert.Equal(t, 0, len(val.ListGroups()))
349}
350
351func TestDeviceRules_AddFlowsAndGroup(t *testing.T) {
352 fg := NewFlowsAndGroups()
353 var fa *FlowArgs
354 var ga *GroupArgs
355
356 str := fg.String()
357 assert.True(t, str == "")
358
359 fa = &FlowArgs{
360 KV: OfpFlowModArgs{"priority": 2000},
361 MatchFields: []*ofp.OfpOxmOfbField{
362 InPort(2),
363 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
364 Metadata_ofp(1000),
365 TunnelId(uint64(1)),
366 VlanPcp(0),
367 },
368 Actions: []*ofp.OfpAction{
369 PopVlan(),
370 Output(1),
371 },
372 }
373 flow := MkFlowStat(fa)
374 fg.AddFlow(flow)
375
376 ga = &GroupArgs{
377 GroupId: 10,
378 Buckets: []*ofp.OfpBucket{
379 {Actions: []*ofp.OfpAction{
380 PopVlan(),
381 Output(1),
382 },
383 },
384 },
385 }
386 group := MkGroupStat(ga)
387 fg.AddGroup(group)
388
389 dr := NewDeviceRules()
390 dr.AddFlowsAndGroup("123456", fg)
391 rules := dr.GetRules()
392 assert.True(t, len(rules) == 1)
393 val, ok := rules["123456"]
394 assert.True(t, ok)
395 assert.Equal(t, 1, len(val.ListFlows()))
396 assert.Equal(t, 1, len(val.ListGroups()))
397 assert.True(t, FlowMatch(flow, val.ListFlows()[0]))
398 assert.Equal(t, 10, int(val.ListGroups()[0].Desc.GroupId))
399}
400
401func TestFlowHasOutPort(t *testing.T) {
402 var flow *ofp.OfpFlowStats
403 assert.False(t, FlowHasOutPort(flow, 1))
404
405 fa := &FlowArgs{
406 KV: OfpFlowModArgs{"priority": 2000},
407 MatchFields: []*ofp.OfpOxmOfbField{
408 InPort(2),
409 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
410 Metadata_ofp(1000),
411 TunnelId(uint64(1)),
412 VlanPcp(0),
413 },
414 Actions: []*ofp.OfpAction{
415 PopVlan(),
416 Output(1),
417 },
418 }
419 flow = MkFlowStat(fa)
420 assert.True(t, FlowHasOutPort(flow, 1))
421 assert.False(t, FlowHasOutPort(flow, 2))
422
423 fa = &FlowArgs{
424 KV: OfpFlowModArgs{"priority": 2000},
425 MatchFields: []*ofp.OfpOxmOfbField{
426 InPort(2),
427 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
428 },
429 }
430 flow = MkFlowStat(fa)
431 assert.False(t, FlowHasOutPort(flow, 1))
432}
433
434func TestFlowHasOutGroup(t *testing.T) {
435 var flow *ofp.OfpFlowStats
436 assert.False(t, FlowHasOutGroup(flow, 10))
437
438 fa := &FlowArgs{
439 KV: OfpFlowModArgs{"priority": 500},
440 MatchFields: []*ofp.OfpOxmOfbField{
441 InPort(2),
442 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
443 VlanPcp(0),
444 EthType(0x800),
445 Ipv4Dst(0xe00a0a0a),
446 },
447 Actions: []*ofp.OfpAction{
448 Group(10),
449 },
450 }
451 flow = MkFlowStat(fa)
452 assert.True(t, FlowHasOutGroup(flow, 10))
453 assert.False(t, FlowHasOutGroup(flow, 11))
454
455 fa = &FlowArgs{
456 KV: OfpFlowModArgs{"priority": 500},
457 MatchFields: []*ofp.OfpOxmOfbField{
458 InPort(2),
459 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
460 VlanPcp(0),
461 EthType(0x800),
462 Ipv4Dst(0xe00a0a0a),
463 },
464 Actions: []*ofp.OfpAction{
465 Output(1),
466 },
467 }
468 flow = MkFlowStat(fa)
469 assert.False(t, FlowHasOutGroup(flow, 1))
470}
471
472func TestMatchFlow(t *testing.T) {
473 assert.False(t, FlowMatch(nil, nil))
474 fa := &FlowArgs{
475 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
476 MatchFields: []*ofp.OfpOxmOfbField{
477 InPort(2),
478 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
479 VlanPcp(0),
480 EthType(0x800),
481 Ipv4Dst(0xe00a0a0a),
482 },
483 Actions: []*ofp.OfpAction{
484 Group(10),
485 },
486 }
487 flow1 := MkFlowStat(fa)
488 assert.False(t, FlowMatch(flow1, nil))
489
490 fa = &FlowArgs{
491 KV: OfpFlowModArgs{"priority": 500},
492 MatchFields: []*ofp.OfpOxmOfbField{
493 InPort(2),
494 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
495 VlanPcp(0),
496 EthType(0x800),
497 Ipv4Dst(0xe00a0a0a),
498 },
499 Actions: []*ofp.OfpAction{
500 Group(10),
501 },
502 }
503 flow2 := MkFlowStat(fa)
504 assert.False(t, FlowMatch(flow1, flow2))
505 assert.False(t, FlowMatch(nil, flow2))
506
507 fa = &FlowArgs{
508 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
509 MatchFields: []*ofp.OfpOxmOfbField{
510 InPort(2),
511 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
512 VlanPcp(0),
513 EthType(0x800),
514 Ipv4Dst(0xe00a0a0a),
515 },
516 }
517 flow2 = MkFlowStat(fa)
518 assert.True(t, FlowMatch(flow1, flow2))
519
520 fa = &FlowArgs{
521 KV: OfpFlowModArgs{"priority": 501, "table_id": 1, "cookie": 38268468, "flags": 12},
522 MatchFields: []*ofp.OfpOxmOfbField{
523 InPort(2),
524 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
525 VlanPcp(0),
526 EthType(0x800),
527 Ipv4Dst(0xe00a0a0a),
528 },
529 Actions: []*ofp.OfpAction{
530 Group(10),
531 },
532 }
533 flow2 = MkFlowStat(fa)
534 assert.False(t, FlowMatch(flow1, flow2))
535
536 fa = &FlowArgs{
537 KV: OfpFlowModArgs{"priority": 500, "table_id": 2, "cookie": 38268468, "flags": 12},
538 MatchFields: []*ofp.OfpOxmOfbField{
539 InPort(2),
540 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
541 VlanPcp(0),
542 EthType(0x800),
543 Ipv4Dst(0xe00a0a0a),
544 },
545 }
546 flow2 = MkFlowStat(fa)
547 assert.False(t, FlowMatch(flow1, flow2))
548
549 fa = &FlowArgs{
550 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268467, "flags": 12},
551 MatchFields: []*ofp.OfpOxmOfbField{
552 InPort(2),
553 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
554 VlanPcp(0),
555 EthType(0x800),
556 Ipv4Dst(0xe00a0a0a),
557 },
558 }
559 flow2 = MkFlowStat(fa)
560 assert.False(t, FlowMatch(flow1, flow2))
561
562 fa = &FlowArgs{
563 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 14},
564 MatchFields: []*ofp.OfpOxmOfbField{
565 InPort(2),
566 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
567 VlanPcp(0),
568 EthType(0x800),
569 Ipv4Dst(0xe00a0a0a),
570 },
571 }
572 flow2 = MkFlowStat(fa)
573 assert.False(t, FlowMatch(flow1, flow2))
574
575 fa = &FlowArgs{
576 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
577 MatchFields: []*ofp.OfpOxmOfbField{
578 InPort(4),
579 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
580 VlanPcp(0),
581 EthType(0x800),
582 Ipv4Dst(0xe00a0a0a),
583 },
584 }
585 flow2 = MkFlowStat(fa)
586 assert.False(t, FlowMatch(flow1, flow2))
587
588 fa = &FlowArgs{
589 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
590 MatchFields: []*ofp.OfpOxmOfbField{
591 InPort(2),
592 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
593 VlanPcp(0),
594 EthType(0x800),
595 },
596 }
597 flow2 = MkFlowStat(fa)
598 assert.False(t, FlowMatch(flow1, flow2))
599
600 fa = &FlowArgs{
601 KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
602 MatchFields: []*ofp.OfpOxmOfbField{
603 InPort(2),
604 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
605 VlanPcp(0),
606 EthType(0x800),
607 Ipv4Dst(0xe00a0a0a),
608 },
609 Actions: []*ofp.OfpAction{
610 PopVlan(),
611 Output(1),
612 },
613 }
614 flow2 = MkFlowStat(fa)
615 assert.True(t, FlowMatch(flow1, flow2))
616}
617
618func TestFlowMatchesMod(t *testing.T) {
619 assert.False(t, FlowMatchesMod(nil, nil))
620 fa := &FlowArgs{
621 KV: OfpFlowModArgs{"priority": 500, "table_id": 1},
622 MatchFields: []*ofp.OfpOxmOfbField{
623 InPort(2),
624 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
625 VlanPcp(0),
626 EthType(0x800),
627 Ipv4Dst(0xe00a0a0a),
628 },
629 Actions: []*ofp.OfpAction{
630 Output(1),
631 Group(10),
632 },
633 }
634 flow := MkFlowStat(fa)
635 assert.False(t, FlowMatchesMod(flow, nil))
636
637 fa = &FlowArgs{
638 KV: OfpFlowModArgs{"priority": 500, "table_id": 1},
639 MatchFields: []*ofp.OfpOxmOfbField{
640 InPort(2),
641 VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
642 VlanPcp(0),
643 EthType(0x800),
644 Ipv4Dst(0xe00a0a0a),
645 },
646 Actions: []*ofp.OfpAction{
647 PopVlan(),
648 Output(1),
649 },
650 }
651 flowMod := MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
652 assert.False(t, FlowMatchesMod(nil, flowMod))
653 assert.False(t, FlowMatchesMod(flow, flowMod))
654 assert.True(t, FlowMatch(flow, FlowStatsEntryFromFlowModMessage(flowMod)))
655
656 fa = &FlowArgs{
657 KV: OfpFlowModArgs{"table_id": uint64(ofp.OfpTable_OFPTT_ALL),
658 "cookie_mask": 0,
659 "out_port": uint64(ofp.OfpPortNo_OFPP_ANY),
660 "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
661 },
662 }
663 flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
664 assert.True(t, FlowMatchesMod(flow, flowMod))
665
666 fa = &FlowArgs{
667 KV: OfpFlowModArgs{"table_id": 1,
668 "cookie_mask": 0,
669 "out_port": uint64(ofp.OfpPortNo_OFPP_ANY),
670 "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
671 },
672 }
673 flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
674 assert.True(t, FlowMatchesMod(flow, flowMod))
675
676 fa = &FlowArgs{
677 KV: OfpFlowModArgs{"table_id": 1,
678 "cookie_mask": 0,
679 "out_port": 1,
680 "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
681 },
682 }
683 flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
684 assert.True(t, FlowMatchesMod(flow, flowMod))
685
686 fa = &FlowArgs{
687 KV: OfpFlowModArgs{"table_id": 1,
688 "cookie_mask": 0,
689 "out_port": 1,
690 "out_group": 10,
691 },
692 }
693 flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
694 assert.True(t, FlowMatchesMod(flow, flowMod))
695}