blob: 4b70e41a71e74ca29a0da8b09e48b0aa46620434 [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001/*
2 * Copyright 2020-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
17//Package core provides the utility for olt devices, flows and statistics
18package core
19
20import (
21 "context"
22 "encoding/hex"
23 "fmt"
24 "reflect"
25 "strconv"
26 "sync"
27 "testing"
28 "time"
29
30 "github.com/opencord/voltha-protos/v3/go/voltha"
31
32 "github.com/opencord/voltha-lib-go/v3/pkg/db"
33 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
34 "github.com/opencord/voltha-lib-go/v3/pkg/log"
35 tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
36 "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
37 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
38 "github.com/opencord/voltha-openolt-adapter/pkg/mocks"
39 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
40 "github.com/opencord/voltha-protos/v3/go/openolt"
41 openoltpb2 "github.com/opencord/voltha-protos/v3/go/openolt"
42 tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
43)
44
45var flowMgr *OpenOltFlowMgr
46
47func init() {
48 _, _ = log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
49 flowMgr = newMockFlowmgr()
50}
51func newMockResourceMgr() *resourcemanager.OpenOltResourceMgr {
52 ranges := []*openolt.DeviceInfo_DeviceResourceRanges{
53 {
54 IntfIds: []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
55 Technology: "Default",
56 },
57 }
58
59 deviceinfo := &openolt.DeviceInfo{Vendor: "openolt", Model: "openolt", HardwareVersion: "1.0", FirmwareVersion: "1.0",
60 DeviceId: "olt", DeviceSerialNumber: "openolt", PonPorts: 16, Technology: "Default",
61 OnuIdStart: 1, OnuIdEnd: 1, AllocIdStart: 1, AllocIdEnd: 1,
62 GemportIdStart: 1, GemportIdEnd: 1, FlowIdStart: 1, FlowIdEnd: 1,
63 Ranges: ranges,
64 }
65 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
66 defer cancel()
67 rsrMgr := resourcemanager.NewResourceMgr(ctx, "olt", "127.0.0.1:2379", "etcd", "olt", deviceinfo)
68 for key := range rsrMgr.ResourceMgrs {
69 rsrMgr.ResourceMgrs[key].KVStore = &db.Backend{}
70 rsrMgr.ResourceMgrs[key].KVStore.Client = &mocks.MockKVClient{}
71 rsrMgr.ResourceMgrs[key].TechProfileMgr = mocks.MockTechProfile{TpID: key}
72 }
73 return rsrMgr
74}
75
76func newMockFlowmgr() *OpenOltFlowMgr {
77 rMgr := newMockResourceMgr()
78 dh := newMockDeviceHandler()
79
80 rMgr.KVStore = &db.Backend{}
81 rMgr.KVStore.Client = &mocks.MockKVClient{}
82
83 dh.resourceMgr = rMgr
84 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
85 defer cancel()
86 flwMgr := NewFlowManager(ctx, dh, rMgr)
87
88 onuGemInfo1 := make([]rsrcMgr.OnuGemInfo, 2)
89 onuGemInfo2 := make([]rsrcMgr.OnuGemInfo, 2)
90 onuGemInfo1[0] = rsrcMgr.OnuGemInfo{OnuID: 1, SerialNumber: "1", IntfID: 1, GemPorts: []uint32{1}}
91 onuGemInfo2[1] = rsrcMgr.OnuGemInfo{OnuID: 2, SerialNumber: "2", IntfID: 2, GemPorts: []uint32{2}}
92 flwMgr.onuGemInfo[1] = onuGemInfo1
93 flwMgr.onuGemInfo[2] = onuGemInfo2
94
95 packetInGemPort := make(map[rsrcMgr.PacketInInfoKey]uint32)
96 packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: 1, OnuID: 1, LogicalPort: 1}] = 1
97 packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: 2, OnuID: 2, LogicalPort: 2}] = 2
98
99 flwMgr.packetInGemPort = packetInGemPort
100 tps := make(map[uint32]tp.TechProfileIf)
101 for key := range rMgr.ResourceMgrs {
102 tps[key] = mocks.MockTechProfile{TpID: key}
103 }
104 flwMgr.techprofile = tps
105
106 interface2mcastQeueuMap := make(map[uint32]*queueInfoBrief)
107 interface2mcastQeueuMap[0] = &queueInfoBrief{
108 gemPortID: 4000,
109 servicePriority: 3,
110 }
111 flwMgr.interfaceToMcastQueueMap = interface2mcastQeueuMap
112 return flwMgr
113}
114
115func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
116
117 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
118 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
119 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
120 }
121 tprofile.UsScheduler.Direction = "UPSTREAM"
122 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
123 tprofile.UsScheduler.QSchedPolicy = "WRR"
124
125 tprofile2 := tprofile
126 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
127 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
128 tprofile2.DsScheduler.QSchedPolicy = "WRR"
129 bands := make([]*ofp.OfpMeterBandHeader, 2)
130 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
131 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
132 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
133 flowmetadata := &voltha.FlowMetadata{
134 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
135 }
136 tests := []struct {
137 name string
138 schedQueue schedQueue
139 wantErr bool
140 }{
141 // TODO: Add test cases.
142 {"CreateSchedulerQueues-1", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, flowmetadata}, false},
143 {"CreateSchedulerQueues-2", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
144 {"CreateSchedulerQueues-3", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, flowmetadata}, true},
145 {"CreateSchedulerQueues-4", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, flowmetadata}, true},
146 {"CreateSchedulerQueues-5", schedQueue{tp_pb.Direction_UPSTREAM, 2, 2, 2, 64, 2, tprofile, 2, flowmetadata}, true},
147 {"CreateSchedulerQueues-6", schedQueue{tp_pb.Direction_DOWNSTREAM, 2, 2, 2, 65, 2, tprofile2, 2, flowmetadata}, true},
148 {"CreateSchedulerQueues-13", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
149 //Negative testcases
150 {"CreateSchedulerQueues-7", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, &voltha.FlowMetadata{}}, true},
151 {"CreateSchedulerQueues-8", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, &voltha.FlowMetadata{}}, true},
152 {"CreateSchedulerQueues-9", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, &voltha.FlowMetadata{}}, true},
153 {"CreateSchedulerQueues-10", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, &voltha.FlowMetadata{}}, true},
154 {"CreateSchedulerQueues-11", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, &voltha.FlowMetadata{}}, true},
155 {"CreateSchedulerQueues-12", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, nil}, true},
156 }
157 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
158 defer cancel()
159 for _, tt := range tests {
160 t.Run(tt.name, func(t *testing.T) {
161 if err := flowMgr.CreateSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
162 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
163 }
164 })
165 }
166}
167
168func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
169
170 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
171 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
172 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
173 }
174 tprofile.UsScheduler.Direction = "UPSTREAM"
175 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
176 tprofile.UsScheduler.QSchedPolicy = "WRR"
177
178 tprofile2 := tprofile
179 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
180 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
181 tprofile2.DsScheduler.QSchedPolicy = "WRR"
182 tests := []struct {
183 name string
184 schedQueue schedQueue
185 wantErr bool
186 }{
187 // TODO: Add test cases.
188 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, nil}, false},
189 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
190 // negative test cases
191 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
192 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
193 }
194 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
195 defer cancel()
196 for _, tt := range tests {
197 t.Run(tt.name, func(t *testing.T) {
198 if err := flowMgr.RemoveSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
199 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
200 }
201 })
202 }
203
204}
205
206func TestOpenOltFlowMgr_createTcontGemports(t *testing.T) {
207 bands := make([]*ofp.OfpMeterBandHeader, 2)
208 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
209 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
210 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
211 flowmetadata := &voltha.FlowMetadata{
212 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
213 }
214 type args struct {
215 intfID uint32
216 onuID uint32
217 uniID uint32
218 uni string
219 uniPort uint32
220 TpID uint32
221 UsMeterID uint32
222 DsMeterID uint32
223 flowMetadata *voltha.FlowMetadata
224 }
225 tests := []struct {
226 name string
227 args args
228 }{
229 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 64, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
230 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 65, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
231 }
232 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
233 defer cancel()
234 for _, tt := range tests {
235 t.Run(tt.name, func(t *testing.T) {
236 _, _, tpInst := flowMgr.createTcontGemports(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.uni, tt.args.uniPort, tt.args.TpID, tt.args.UsMeterID, tt.args.DsMeterID, tt.args.flowMetadata)
237 switch tpInst := tpInst.(type) {
238 case *tp.TechProfile:
239 if tt.args.TpID != 64 {
240 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
241 }
242 case *tp.EponProfile:
243 if tt.args.TpID != 65 {
244 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
245 }
246 default:
247 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
248 }
249 })
250 }
251}
252
253func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
254 ctx := context.Background()
255 logger.Debug(ctx, "Info Warning Error: Starting RemoveFlow() test")
256 fa := &fu.FlowArgs{
257 MatchFields: []*ofp.OfpOxmOfbField{
258 fu.InPort(2),
259 fu.Metadata_ofp(2),
260 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
261 },
262 Actions: []*ofp.OfpAction{
263 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
264 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
265 fu.Output(1),
266 },
267 }
268 ofpstats, _ := fu.MkFlowStat(fa)
269 ofpstats.Cookie = ofpstats.Id
270 lldpFa := &fu.FlowArgs{
271 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
272 MatchFields: []*ofp.OfpOxmOfbField{
273 fu.InPort(1),
274 fu.EthType(0x88CC),
275 fu.TunnelId(536870912),
276 },
277 Actions: []*ofp.OfpAction{
278 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
279 },
280 }
281 lldpofpstats, _ := fu.MkFlowStat(lldpFa)
282
283 dhcpFa := &fu.FlowArgs{
284 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
285 MatchFields: []*ofp.OfpOxmOfbField{
286 fu.InPort(1),
287 fu.UdpSrc(67),
288 //fu.TunnelId(536870912),
289 fu.IpProto(17),
290 },
291 Actions: []*ofp.OfpAction{
292 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
293 },
294 }
295 dhcpofpstats, _ := fu.MkFlowStat(dhcpFa)
296
297 multicastFa := &fu.FlowArgs{
298 MatchFields: []*ofp.OfpOxmOfbField{
299 fu.InPort(65536),
300 fu.VlanVid(660), //vlan
301 fu.Metadata_ofp(uint64(66)), //inner vlan
302 fu.EthType(0x800), //ipv4
303 fu.Ipv4Dst(3809869825), //227.22.0.1
304 },
305 Actions: []*ofp.OfpAction{
306 fu.Group(1),
307 },
308 }
309 multicastOfpStats, _ := fu.MkFlowStat(multicastFa)
310 multicastOfpStats.Id = 1
311
312 type args struct {
313 flow *ofp.OfpFlowStats
314 }
315 tests := []struct {
316 name string
317 args args
318 }{
319 // TODO: Add test cases.
320 {"RemoveFlow", args{flow: ofpstats}},
321 {"RemoveFlow", args{flow: lldpofpstats}},
322 {"RemoveFlow", args{flow: dhcpofpstats}},
323 {"RemoveFlow", args{flow: multicastOfpStats}},
324 }
325 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
326 defer cancel()
327 for _, tt := range tests {
328 t.Run(tt.name, func(t *testing.T) {
329 if err := flowMgr.RemoveFlow(ctx, tt.args.flow); err != nil {
330 logger.Warn(ctx, err)
331 }
332 })
333 }
334}
335
336func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
337 kw := make(map[string]uint64)
338 kw["table_id"] = 1
339 kw["meter_id"] = 1
340 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
341
342 fa := &fu.FlowArgs{
343 MatchFields: []*ofp.OfpOxmOfbField{
344 fu.InPort(536870912),
345 fu.Metadata_ofp(1),
346 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
347 },
348 Actions: []*ofp.OfpAction{
349 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
350 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
351 fu.Output(65536),
352 fu.PushVlan(0x8100),
353 },
354 KV: kw,
355 }
356
357 fa3 := &fu.FlowArgs{
358 MatchFields: []*ofp.OfpOxmOfbField{
359 fu.InPort(65536),
360 fu.Metadata_ofp(1),
361 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
362 },
363 Actions: []*ofp.OfpAction{
364 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
365 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
366 fu.PopVlan(),
367 fu.Output(536870912),
368 },
369 KV: kw,
370 }
371
372 fa2 := &fu.FlowArgs{
373 MatchFields: []*ofp.OfpOxmOfbField{
374 fu.InPort(1000),
375 fu.Metadata_ofp(1),
376 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
377 },
378 Actions: []*ofp.OfpAction{
379 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
380 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
381 fu.Output(65533),
382 },
383 KV: kw,
384 }
385
386
387 fa4 := &fu.FlowArgs{
388 MatchFields: []*ofp.OfpOxmOfbField{
389 fu.InPort(1000),
390 fu.Metadata_ofp(1),
391 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
392 },
393 Actions: []*ofp.OfpAction{
394 fu.Experimenter(257, []byte{1, 2, 3, 4}),
395 },
396 KV: kw,
397 }
398
399 fa5 := &fu.FlowArgs{
400 MatchFields: []*ofp.OfpOxmOfbField{
401 fu.InPort(1000),
402 fu.Metadata_ofp(1),
403 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
404 },
405 Actions: []*ofp.OfpAction{
406 fu.Output(0),
407 },
408 KV: kw,
409 }
410
411 kw6 := make(map[string]uint64)
412 kw6["table_id"] = 1
413 kw6["meter_id"] = 1
414 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
415 fa6 := &fu.FlowArgs{
416 MatchFields: []*ofp.OfpOxmOfbField{
417 fu.InPort(536870912),
418 fu.TunnelId(16),
419 fu.Metadata_ofp(1),
420 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
421 },
422 Actions: []*ofp.OfpAction{
423 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
424 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
425 fu.Output(65535),
426 },
427 KV: kw6,
428 }
429
430 lldpFa := &fu.FlowArgs{
431 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
432 MatchFields: []*ofp.OfpOxmOfbField{
433 fu.InPort(1),
434 fu.EthType(0x88CC),
435 fu.TunnelId(536870912),
436 },
437 Actions: []*ofp.OfpAction{
438 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
439 },
440 }
441
442 dhcpFa := &fu.FlowArgs{
443 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
444 MatchFields: []*ofp.OfpOxmOfbField{
445 fu.InPort(1),
446 fu.UdpSrc(67),
447 //fu.TunnelId(536870912),
448 fu.IpProto(17),
449 },
450 Actions: []*ofp.OfpAction{
451 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
452 },
453 }
454 igmpFa := &fu.FlowArgs{
455 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
456 MatchFields: []*ofp.OfpOxmOfbField{
457 fu.InPort(1),
458 fu.UdpSrc(67),
459 //fu.TunnelId(536870912),
460 fu.IpProto(2),
461 },
462 Actions: []*ofp.OfpAction{
463 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
464 },
465 }
466
467 fa9 := &fu.FlowArgs{
468 MatchFields: []*ofp.OfpOxmOfbField{
469 fu.InPort(536870912),
470 fu.TunnelId(16),
471 fu.Metadata_ofp(1),
472 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
473 fu.VlanPcp(1000),
474 fu.UdpDst(65535),
475 fu.UdpSrc(536870912),
476 fu.Ipv4Dst(65535),
477 fu.Ipv4Src(536870912),
478 },
479 Actions: []*ofp.OfpAction{
480 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
481 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
482 fu.Output(65535),
483 },
484 KV: kw6,
485 }
486
487 fa10 := &fu.FlowArgs{
488 MatchFields: []*ofp.OfpOxmOfbField{
489 fu.InPort(65533),
490 // fu.TunnelId(16),
491 fu.Metadata_ofp(1),
492 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
493 fu.VlanPcp(1000),
494 fu.UdpDst(65535),
495 fu.UdpSrc(536870912),
496 fu.Ipv4Dst(65535),
497 fu.Ipv4Src(536870912),
498 },
499 Actions: []*ofp.OfpAction{
500 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
501 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
502 fu.Output(65535),
503 },
504 KV: kw6,
505 }
506 fa11 := &fu.FlowArgs{
507 MatchFields: []*ofp.OfpOxmOfbField{
508 fu.InPort(65536),
509 fu.VlanVid(660), //vlan
510 fu.Metadata_ofp(uint64(66)), //inner vlan
511 fu.EthType(0x800), //ipv4
512 fu.Ipv4Dst(3809869825), //227.22.0.1
513 },
514 Actions: []*ofp.OfpAction{
515 fu.Group(1),
516 },
517 KV: kw6,
518 }
519 ofpstats, _ := fu.MkFlowStat(fa)
520 ofpstats2, _ := fu.MkFlowStat(fa2)
521 ofpstats3, _ := fu.MkFlowStat(fa3)
522 ofpstats4, _ := fu.MkFlowStat(fa4)
523 ofpstats5, _ := fu.MkFlowStat(fa5)
524 ofpstats6, _ := fu.MkFlowStat(fa6)
525 ofpstats7, _ := fu.MkFlowStat(lldpFa)
526 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
527 ofpstats9, _ := fu.MkFlowStat(fa9)
528 ofpstats10, _ := fu.MkFlowStat(fa10)
529 igmpstats, _ := fu.MkFlowStat(igmpFa)
530 ofpstats11, _ := fu.MkFlowStat(fa11)
531
532 fmt.Println(ofpstats6, ofpstats9, ofpstats10)
533
534 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
535 flowMetadata := &voltha.FlowMetadata{
536 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
537 }
538 type args struct {
539 flow *ofp.OfpFlowStats
540 flowMetadata *voltha.FlowMetadata
541 }
542 tests := []struct {
543 name string
544 args args
545 }{
546 // TODO: Add test cases.
547 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
548 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
549 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
550 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
551 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
552 //{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
553 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
554 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
555 //{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
556 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
557 //{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
558 //ofpstats10
559 {"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
560 }
561 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
562 defer cancel()
563 for _, tt := range tests {
564 t.Run(tt.name, func(t *testing.T) {
565 _ = flowMgr.AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
566 // TODO: actually verify test cases
567 })
568 }
569}
570
571func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
572 flwMgr := newMockFlowmgr()
573
574 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
575 defer cancel()
576
577 wg := sync.WaitGroup{}
578
579 intfCount := 16
580 onuCount := 32
581
582 for i := 0; i < intfCount; i++ {
583 for j := 0; j < onuCount; j++ {
584 wg.Add(1)
585 go func(i uint32, j uint32) {
586 // TODO: actually verify success
587 _ = flwMgr.UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
588 wg.Done()
589 }(uint32(i), uint32(j))
590 }
591
592 }
593
594 wg.Wait()
595}
596
597func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
598 flowMgr = newMockFlowmgr()
599 intfNum := 16
600 onuNum := 32
601
602 flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, intfNum)
603
604 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
605 defer cancel()
606
607 for i := 0; i < intfNum; i++ {
608 for o := 0; o < onuNum; o++ {
609 // TODO: actually verify success
610 _ = flowMgr.UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o))
611 }
612 }
613
614 wg := sync.WaitGroup{}
615
616 for o := 0; o < onuNum; o++ {
617 for i := 0; i < intfNum; i++ {
618 wg.Add(1)
619 go func(intfId uint32, onuId uint32) {
620 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId))
621
622 flowMgr.addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
623 wg.Done()
624 }(uint32(i), uint32(o))
625 }
626 }
627
628 wg.Wait()
629
630 for i := 0; i < intfNum; i++ {
631 lenofOnu := len(flowMgr.onuGemInfo[uint32(i)])
632 if onuNum != lenofOnu {
633 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
634 }
635
636 for o := 0; o < onuNum; o++ {
637 lenOfGemPorts := len(flowMgr.onuGemInfo[uint32(i)][o].GemPorts)
638 // check that each onuEntry has 1 gemPort
639 if lenOfGemPorts != 1 {
640 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
641 }
642
643 // check that the value of the gemport is correct
644 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o))
645 currentValue := flowMgr.onuGemInfo[uint32(i)][o].GemPorts[0]
646 if uint32(gemID) != currentValue {
647 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
648 }
649 }
650 }
651}
652
653func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
654 flwMgr := newMockFlowmgr()
655 type args struct {
656 intfID uint32
657 onuID uint32
658 gemPortIDs []uint32
659 gemPortIDsToBeDeleted []uint32
660 gemPortIDsRemaining []uint32
661 serialNum string
662 finalLength int
663 }
664 tests := []struct {
665 name string
666 args args
667 }{
668 // Add/Delete single gem port
669 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
670 // Delete all gemports
671 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
672 // Try to delete when there is no gem port
673 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
674 // Try to delete non-existent gem port
675 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
676 // Try to delete two of the gem ports
677 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
678 }
679 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
680 defer cancel()
681 for _, tt := range tests {
682 t.Run(tt.name, func(t *testing.T) {
683 // TODO: should check returned errors are as expected?
684 _ = flwMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
685 for _, gemPort := range tt.args.gemPortIDs {
686 flwMgr.addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
687 }
688 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
689 flwMgr.deleteGemPortFromLocalCache(ctx, tt.args.intfID, tt.args.onuID, gemPortDeleted)
690 }
691 lenofGemPorts := len(flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts)
692 if lenofGemPorts != tt.args.finalLength {
693 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
694 }
695 gemPorts := flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts
696 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
697 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
698 }
699
700 })
701 }
702}
703
704func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
705 flwMgr := newMockFlowmgr()
706 type args struct {
707 packetIn *openoltpb2.PacketIndication
708 }
709 tests := []struct {
710 name string
711 args args
712 want uint32
713 wantErr bool
714 }{
715 // TODO: Add test cases.
716 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
717 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1048577, false},
718 // Negative Test cases.
719 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
720 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 4112, false},
721 }
722 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
723 defer cancel()
724 for _, tt := range tests {
725 t.Run(tt.name, func(t *testing.T) {
726
727 got, err := flwMgr.GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
728 if (err != nil) != tt.wantErr {
729 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
730 return
731 }
732 if got != tt.want {
733 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
734 }
735 })
736 }
737}
738
739func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
740
741 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
742 untagged, err := hex.DecodeString(untaggedStr)
743 if err != nil {
744 t.Error("Unable to parse hex string", err)
745 panic(err)
746 }
747 singleTaggedStr := "01005e0000010025ba48172481000225080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
748 singleTagged, err := hex.DecodeString(singleTaggedStr)
749 if err != nil {
750 t.Error("Unable to parse hex string", err)
751 panic(err)
752 }
753 doubleTaggedStr := "01005e000016deadbeefba11810002108100e030080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
754 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
755 if err != nil {
756 t.Error("Unable to parse hex string", err)
757 panic(err)
758 }
759
760 type args struct {
761 intfID uint32
762 onuID uint32
763 portNum uint32
764 packet []byte
765 }
766 tests := []struct {
767 name string
768 args args
769 want uint32
770 wantErr bool
771 }{
772 // TODO: Add test cases.
773 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: untagged}, 3, false},
774 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 4, packet: singleTagged}, 4, false},
775 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: doubleTagged}, 2, false},
776 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 10, portNum: 10, packet: untagged}, 2, true},
777 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
778 }
779
780 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
781 defer cancel()
782 for _, tt := range tests {
783 t.Run(tt.name, func(t *testing.T) {
784
785 got, err := flowMgr.GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum, tt.args.packet)
786 if tt.wantErr {
787 if err == nil {
788 //error expected but got value
789 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
790 }
791 } else {
792 if err != nil {
793 //error is not expected but got error
794 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
795 return
796 }
797 if got != tt.want {
798 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
799 }
800 }
801 })
802 }
803}
804
805func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
806 type args struct {
807 intfID uint32
808 onuID uint32
809 uniID uint32
810 sn string
811 tpID uint32
812 }
813 tests := []struct {
814 name string
815 args args
816 wantErr bool
817 }{
818 // TODO: Add test cases.
819 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
820 }
821 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
822 defer cancel()
823 for _, tt := range tests {
824 t.Run(tt.name, func(t *testing.T) {
825 if err := flowMgr.DeleteTechProfileInstance(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.sn, tt.args.tpID); (err != nil) != tt.wantErr {
826 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
827 }
828 })
829 }
830}
831
832func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
833 ctx := context.Background()
834 kw := make(map[string]uint64)
835 kw["table_id"] = 1
836 kw["meter_id"] = 1
837 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
838
839 fa := &fu.FlowArgs{
840 MatchFields: []*ofp.OfpOxmOfbField{
841 fu.InPort(536870912),
842 fu.Metadata_ofp(1),
843 fu.IpProto(17), // dhcp
844 fu.VlanPcp(0),
845 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
846 },
847 Actions: []*ofp.OfpAction{
848 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
849 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
850 fu.Output(65536),
851 fu.PushVlan(0x8100),
852 },
853 KV: kw,
854 }
855
856 fa2 := &fu.FlowArgs{
857 MatchFields: []*ofp.OfpOxmOfbField{
858 fu.InPort(536870912),
859 fu.Metadata_ofp(1),
860 fu.EthType(0x888E),
861 fu.VlanPcp(1),
862 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
863 },
864 Actions: []*ofp.OfpAction{
865 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
866 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
867 fu.Output(65536),
868 fu.PushVlan(0x8100),
869 },
870 KV: kw,
871 }
872
873 fa3 := &fu.FlowArgs{
874 MatchFields: []*ofp.OfpOxmOfbField{
875 fu.InPort(536870912),
876 fu.Metadata_ofp(1),
877 //fu.EthType(0x8100),
878 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
879 },
880 Actions: []*ofp.OfpAction{
881 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
882 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
883 fu.Output(65536),
884 fu.PushVlan(0x8100),
885 },
886 KV: kw,
887 }
888
889 fa4 := &fu.FlowArgs{
890 MatchFields: []*ofp.OfpOxmOfbField{
891 fu.InPort(65535),
892 fu.Metadata_ofp(1),
893 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
894 fu.VlanPcp(1),
895 },
896 Actions: []*ofp.OfpAction{
897 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
898 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
899 fu.Output(536870912),
900 fu.PopVlan(),
901 },
902 KV: kw,
903 }
904
905 classifierInfo := make(map[string]interface{})
906 actionInfo := make(map[string]interface{})
907 classifierInfo2 := make(map[string]interface{})
908 actionInfo2 := make(map[string]interface{})
909 classifierInfo3 := make(map[string]interface{})
910 actionInfo3 := make(map[string]interface{})
911 classifierInfo4 := make(map[string]interface{})
912 actionInfo4 := make(map[string]interface{})
913 flowState, _ := fu.MkFlowStat(fa)
914 flowState2, _ := fu.MkFlowStat(fa2)
915 flowState3, _ := fu.MkFlowStat(fa3)
916 flowState4, _ := fu.MkFlowStat(fa4)
917 formulateClassifierInfoFromFlow(ctx, classifierInfo, flowState)
918 formulateClassifierInfoFromFlow(ctx, classifierInfo2, flowState2)
919 formulateClassifierInfoFromFlow(ctx, classifierInfo3, flowState3)
920 formulateClassifierInfoFromFlow(ctx, classifierInfo4, flowState4)
921
922 err := formulateActionInfoFromFlow(ctx, actionInfo, classifierInfo, flowState)
923 if err != nil {
924 // Error logging is already done in the called function
925 // So just return in case of error
926 return
927 }
928
929 err = formulateActionInfoFromFlow(ctx, actionInfo2, classifierInfo2, flowState2)
930 if err != nil {
931 // Error logging is already done in the called function
932 // So just return in case of error
933 return
934 }
935
936 err = formulateActionInfoFromFlow(ctx, actionInfo3, classifierInfo3, flowState3)
937 if err != nil {
938 // Error logging is already done in the called function
939 // So just return in case of error
940 return
941 }
942
943 err = formulateActionInfoFromFlow(ctx, actionInfo4, classifierInfo4, flowState4)
944 if err != nil {
945 // Error logging is already done in the called function
946 // So just return in case of error
947 return
948 }
949
950
951 TpInst := &tp.TechProfile{
952 Name: "Test-Tech-Profile",
953 SubscriberIdentifier: "257",
954 ProfileType: "Mock",
955 Version: 1,
956 NumGemPorts: 4,
957 InstanceCtrl: tp.InstanceControl{
958 Onu: "1",
959 Uni: "16",
960 },
961 }
962
963 type args struct {
964 args map[string]uint32
965 classifierInfo map[string]interface{}
966 actionInfo map[string]interface{}
967 flow *ofp.OfpFlowStats
968 gemPort uint32
969 intfID uint32
970 onuID uint32
971 uniID uint32
972 portNo uint32
973 TpInst *tp.TechProfile
974 allocID []uint32
975 gemPorts []uint32
976 TpID uint32
977 uni string
978 }
979 tests := []struct {
980 name string
981 args args
982 }{
983 {
984 name: "checkAndAddFlow-1",
985 args: args{
986 args: nil,
987 classifierInfo: classifierInfo,
988 actionInfo: actionInfo,
989 flow: flowState,
990 gemPort: 1,
991 intfID: 1,
992 onuID: 1,
993 uniID: 16,
994 portNo: 1,
995 TpInst: TpInst,
996 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
997 gemPorts: []uint32{1, 2, 3, 4},
998 TpID: 64,
999 uni: "16",
1000 },
1001 },
1002 {
1003 name: "checkAndAddFlow-2",
1004 args: args{
1005 args: nil,
1006 classifierInfo: classifierInfo2,
1007 actionInfo: actionInfo2,
1008 flow: flowState2,
1009 gemPort: 1,
1010 intfID: 1,
1011 onuID: 1,
1012 uniID: 16,
1013 portNo: 1,
1014 TpInst: TpInst,
1015 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1016 gemPorts: []uint32{1, 2, 3, 4},
1017 TpID: 64,
1018 uni: "16",
1019 },
1020 },
1021 {
1022 name: "checkAndAddFlow-3",
1023 args: args{
1024 args: nil,
1025 classifierInfo: classifierInfo3,
1026 actionInfo: actionInfo3,
1027 flow: flowState3,
1028 gemPort: 1,
1029 intfID: 1,
1030 onuID: 1,
1031 uniID: 16,
1032 portNo: 1,
1033 TpInst: TpInst,
1034 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1035 gemPorts: []uint32{1, 2, 3, 4},
1036 TpID: 64,
1037 uni: "16",
1038 },
1039 },
1040 {
1041 name: "checkAndAddFlow-4",
1042 args: args{
1043 args: nil,
1044 classifierInfo: classifierInfo4,
1045 actionInfo: actionInfo4,
1046 flow: flowState4,
1047 gemPort: 1,
1048 intfID: 1,
1049 onuID: 1,
1050 uniID: 16,
1051 portNo: 1,
1052 TpInst: TpInst,
1053 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1054 gemPorts: []uint32{1, 2, 3, 4},
1055 TpID: 64,
1056 uni: "16",
1057 },
1058 },
1059 }
1060 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1061 defer cancel()
1062 for _, tt := range tests {
1063 t.Run(tt.name, func(t *testing.T) {
1064 flowMgr.checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
1065 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
1066 })
1067 }
1068}
1069
1070func TestOpenOltFlowMgr_TestMulticastFlowAndGroup(t *testing.T) {
1071 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1072 defer cancel()
1073 group := newGroup(2, []uint32{1})
1074 err := flowMgr.AddGroup(ctx, group)
1075 if err != nil {
1076 t.Error("group-add failed", err)
1077 return
1078 }
1079 multicastFlowArgs := &fu.FlowArgs{
1080 MatchFields: []*ofp.OfpOxmOfbField{
1081 fu.InPort(1048576),
1082 fu.VlanVid(660), //vlan
1083 fu.Metadata_ofp(uint64(66)), //inner vlan
1084 fu.EthType(0x800), //ipv4
1085 fu.Ipv4Dst(3809869825), //227.22.0.1
1086 },
1087 Actions: []*ofp.OfpAction{
1088 fu.Group(1),
1089 },
1090 }
1091 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
1092 fmt.Println(ofpStats.Id)
1093 err = flowMgr.AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
1094 if err != nil {
1095 t.Error("Multicast flow-add failed", err)
1096 return
1097 }
1098
1099 group = newGroup(2, []uint32{1, 2})
1100 err = flowMgr.ModifyGroup(ctx, group)
1101 if err != nil {
1102 t.Error("modify-group failed", err)
1103 return
1104 }
1105 err = flowMgr.RemoveFlow(ctx, ofpStats)
1106 if err != nil {
1107 t.Error("Multicast flow-remove failed", err)
1108 return
1109 }
1110
1111 err = flowMgr.DeleteGroup(ctx, group)
1112 if err != nil {
1113 t.Error("delete-group failed", err)
1114 return
1115 }
1116}