blob: c13bd5e797eb3704a8734fb10f685a6eccddf76f [file] [log] [blame]
kdarapu3248f9a2019-10-03 13:54:52 +05301/*
2 * Copyright 2018-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
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
kdarapu3248f9a2019-10-03 13:54:52 +053019
20import (
npujarec5762e2020-01-01 14:08:48 +053021 "context"
Esin Karaman7fb80c22020-07-16 14:23:33 +000022 "encoding/hex"
Gamze Abakafee36392019-10-03 11:17:24 +000023 "fmt"
Matteo Scandoloabf9c512020-06-23 19:31:14 -070024 "reflect"
25 "strconv"
26 "sync"
kdarapu3248f9a2019-10-03 13:54:52 +053027 "testing"
npujarec5762e2020-01-01 14:08:48 +053028 "time"
kdarapu3248f9a2019-10-03 13:54:52 +053029
Esin Karamanccb714b2019-11-29 15:02:06 +000030 "github.com/opencord/voltha-protos/v3/go/voltha"
kdarapub26b4502019-10-05 03:02:33 +053031
Esin Karamanccb714b2019-11-29 15:02:06 +000032 "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"
Scott Bakerdbd960e2020-02-28 08:57:51 -080036 "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"
Esin Karamanccb714b2019-11-29 15:02:06 +000039 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"
kdarapu3248f9a2019-10-03 13:54:52 +053043)
44
kdarapub26b4502019-10-05 03:02:33 +053045var flowMgr *OpenOltFlowMgr
46
kdarapu3248f9a2019-10-03 13:54:52 +053047func init() {
48 log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
kdarapub26b4502019-10-05 03:02:33 +053049 flowMgr = newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +053050}
51func newMockResourceMgr() *resourcemanager.OpenOltResourceMgr {
52 ranges := []*openolt.DeviceInfo_DeviceResourceRanges{
Matteo Scandoloabf9c512020-06-23 19:31:14 -070053 {
54 IntfIds: []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
55 Technology: "Default",
56 },
57 }
kdarapu3248f9a2019-10-03 13:54:52 +053058
59 deviceinfo := &openolt.DeviceInfo{Vendor: "openolt", Model: "openolt", HardwareVersion: "1.0", FirmwareVersion: "1.0",
Matteo Scandoloabf9c512020-06-23 19:31:14 -070060 DeviceId: "olt", DeviceSerialNumber: "openolt", PonPorts: 16, Technology: "Default",
kdarapu3248f9a2019-10-03 13:54:52 +053061 OnuIdStart: 1, OnuIdEnd: 1, AllocIdStart: 1, AllocIdEnd: 1,
62 GemportIdStart: 1, GemportIdEnd: 1, FlowIdStart: 1, FlowIdEnd: 1,
63 Ranges: ranges,
64 }
npujarec5762e2020-01-01 14:08:48 +053065 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)
kdarapub26b4502019-10-05 03:02:33 +053068 for key := range rsrMgr.ResourceMgrs {
sbarbaria8910ba2019-11-05 10:12:23 -050069 rsrMgr.ResourceMgrs[key].KVStore = &db.Backend{}
kdarapub26b4502019-10-05 03:02:33 +053070 rsrMgr.ResourceMgrs[key].KVStore.Client = &mocks.MockKVClient{}
71 rsrMgr.ResourceMgrs[key].TechProfileMgr = mocks.MockTechProfile{TpID: key}
72 }
kdarapu3248f9a2019-10-03 13:54:52 +053073 return rsrMgr
74}
75
76func newMockFlowmgr() *OpenOltFlowMgr {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053077 rMgr := newMockResourceMgr()
kdarapu3248f9a2019-10-03 13:54:52 +053078 dh := newMockDeviceHandler()
79
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053080 rMgr.KVStore = &db.Backend{}
81 rMgr.KVStore.Client = &mocks.MockKVClient{}
kdarapu3248f9a2019-10-03 13:54:52 +053082
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053083 dh.resourceMgr = rMgr
npujarec5762e2020-01-01 14:08:48 +053084 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
85 defer cancel()
86 flwMgr := NewFlowManager(ctx, dh, rMgr)
kdarapu3248f9a2019-10-03 13:54:52 +053087
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053088 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
kdarapu3248f9a2019-10-03 13:54:52 +053094
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053095 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
kdarapu3248f9a2019-10-03 13:54:52 +053098
99 flwMgr.packetInGemPort = packetInGemPort
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000100 tps := make(map[uint32]tp.TechProfileIf)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530101 for key := range rMgr.ResourceMgrs {
kdarapub26b4502019-10-05 03:02:33 +0530102 tps[key] = mocks.MockTechProfile{TpID: key}
kdarapu3248f9a2019-10-03 13:54:52 +0530103 }
104 flwMgr.techprofile = tps
Esin Karamanccb714b2019-11-29 15:02:06 +0000105
106 interface2mcastQeueuMap := make(map[uint32]*queueInfoBrief)
107 interface2mcastQeueuMap[0] = &queueInfoBrief{
108 gemPortID: 4000,
109 servicePriority: 3,
110 }
111 flwMgr.interfaceToMcastQueueMap = interface2mcastQeueuMap
kdarapu3248f9a2019-10-03 13:54:52 +0530112 return flwMgr
113}
kdarapub26b4502019-10-05 03:02:33 +0530114
kdarapu3248f9a2019-10-03 13:54:52 +0530115func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530116 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530117
118 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
Girish Gowdra54934262019-11-13 14:19:55 +0530119 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
kdarapu3248f9a2019-10-03 13:54:52 +0530120 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
121 }
122 tprofile.UsScheduler.Direction = "UPSTREAM"
123 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
124 tprofile.UsScheduler.QSchedPolicy = "WRR"
125
126 tprofile2 := tprofile
127 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
128 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
129 tprofile2.DsScheduler.QSchedPolicy = "WRR"
130 bands := make([]*ofp.OfpMeterBandHeader, 2)
131 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
132 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
133 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
134 flowmetadata := &voltha.FlowMetadata{
135 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
136 }
137 type args struct {
138 Dir tp_pb.Direction
139 IntfID uint32
140 OnuID uint32
141 UniID uint32
142 UniPort uint32
143 TpInst *tp.TechProfile
144 MeterID uint32
145 flowMetadata *voltha.FlowMetadata
146 }
147 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000148 name string
149 schedQueue schedQueue
150 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530151 }{
152 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000153 {"CreateSchedulerQueues-1", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, flowmetadata}, false},
154 {"CreateSchedulerQueues-2", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
155 {"CreateSchedulerQueues-3", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, flowmetadata}, true},
156 {"CreateSchedulerQueues-4", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, flowmetadata}, true},
157 {"CreateSchedulerQueues-5", schedQueue{tp_pb.Direction_UPSTREAM, 2, 2, 2, 64, 2, tprofile, 2, flowmetadata}, true},
158 {"CreateSchedulerQueues-6", schedQueue{tp_pb.Direction_DOWNSTREAM, 2, 2, 2, 65, 2, tprofile2, 2, flowmetadata}, true},
159 {"CreateSchedulerQueues-13", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530160 //Negative testcases
Gamze Abakafee36392019-10-03 11:17:24 +0000161 {"CreateSchedulerQueues-7", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, &voltha.FlowMetadata{}}, true},
162 {"CreateSchedulerQueues-8", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, &voltha.FlowMetadata{}}, true},
163 {"CreateSchedulerQueues-9", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, &voltha.FlowMetadata{}}, true},
164 {"CreateSchedulerQueues-10", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, &voltha.FlowMetadata{}}, true},
165 {"CreateSchedulerQueues-11", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, &voltha.FlowMetadata{}}, true},
166 {"CreateSchedulerQueues-12", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, nil}, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530167 }
npujarec5762e2020-01-01 14:08:48 +0530168 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
169 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530170 for _, tt := range tests {
171 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530172 if err := flowMgr.CreateSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530173 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
174 }
175 })
176 }
177}
178
179func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
180
kdarapub26b4502019-10-05 03:02:33 +0530181 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530182 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
Girish Gowdra54934262019-11-13 14:19:55 +0530183 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
kdarapu3248f9a2019-10-03 13:54:52 +0530184 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
185 }
186 tprofile.UsScheduler.Direction = "UPSTREAM"
187 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
188 tprofile.UsScheduler.QSchedPolicy = "WRR"
189
190 tprofile2 := tprofile
191 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
192 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
193 tprofile2.DsScheduler.QSchedPolicy = "WRR"
194 //defTprofile := &tp.DefaultTechProfile{}
195 type args struct {
196 Dir tp_pb.Direction
197 IntfID uint32
198 OnuID uint32
199 UniID uint32
200 UniPort uint32
201 TpInst *tp.TechProfile
202 }
203 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000204 name string
205 schedQueue schedQueue
206 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530207 }{
208 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000209 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, nil}, false},
210 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530211 // negative test cases
Gamze Abakafee36392019-10-03 11:17:24 +0000212 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
213 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530214 }
npujarec5762e2020-01-01 14:08:48 +0530215 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
216 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530217 for _, tt := range tests {
218 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530219 if err := flowMgr.RemoveSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530220 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
221 }
222 })
223 }
kdarapub26b4502019-10-05 03:02:33 +0530224
kdarapu3248f9a2019-10-03 13:54:52 +0530225}
226
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700227func TestOpenOltFlowMgr_createTcontGemports(t *testing.T) {
228 // flowMgr := newMockFlowmgr()
229 bands := make([]*ofp.OfpMeterBandHeader, 2)
230 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
231 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
232 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
233 flowmetadata := &voltha.FlowMetadata{
234 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
235 }
236 type args struct {
237 intfID uint32
238 onuID uint32
239 uniID uint32
240 uni string
241 uniPort uint32
242 TpID uint32
243 UsMeterID uint32
244 DsMeterID uint32
245 flowMetadata *voltha.FlowMetadata
246 }
247 tests := []struct {
248 name string
249 args args
250 }{
251 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 64, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
252 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 65, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
253 }
254 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
255 defer cancel()
256 for _, tt := range tests {
257 t.Run(tt.name, func(t *testing.T) {
258 _, _, 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)
259 switch tpInst := tpInst.(type) {
260 case *tp.TechProfile:
261 if tt.args.TpID != 64 {
262 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
263 }
264 case *tp.EponProfile:
265 if tt.args.TpID != 65 {
266 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
267 }
268 default:
269 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
270 }
271 })
272 }
273}
274
kdarapu3248f9a2019-10-03 13:54:52 +0530275func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000276 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530277 // flowMgr := newMockFlowmgr()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000278 logger.Debug(ctx, "Info Warning Error: Starting RemoveFlow() test")
kdarapu3248f9a2019-10-03 13:54:52 +0530279 fa := &fu.FlowArgs{
280 MatchFields: []*ofp.OfpOxmOfbField{
281 fu.InPort(2),
282 fu.Metadata_ofp(2),
283 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
284 },
285 Actions: []*ofp.OfpAction{
286 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
287 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
288 fu.Output(1),
289 },
290 }
divyadesaid26f6b12020-03-19 06:30:28 +0000291 ofpstats, _ := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530292 ofpstats.Cookie = ofpstats.Id
kdarapub26b4502019-10-05 03:02:33 +0530293 lldpFa := &fu.FlowArgs{
294 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
295 MatchFields: []*ofp.OfpOxmOfbField{
296 fu.InPort(1),
297 fu.EthType(0x88CC),
298 fu.TunnelId(536870912),
299 },
300 Actions: []*ofp.OfpAction{
301 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
302 },
303 }
divyadesaid26f6b12020-03-19 06:30:28 +0000304 lldpofpstats, _ := fu.MkFlowStat(lldpFa)
kdarapub26b4502019-10-05 03:02:33 +0530305 //lldpofpstats.Cookie = lldpofpstats.Id
306
307 dhcpFa := &fu.FlowArgs{
308 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
309 MatchFields: []*ofp.OfpOxmOfbField{
310 fu.InPort(1),
311 fu.UdpSrc(67),
312 //fu.TunnelId(536870912),
313 fu.IpProto(17),
314 },
315 Actions: []*ofp.OfpAction{
316 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
317 },
318 }
divyadesaid26f6b12020-03-19 06:30:28 +0000319 dhcpofpstats, _ := fu.MkFlowStat(dhcpFa)
kdarapub26b4502019-10-05 03:02:33 +0530320 //dhcpofpstats.Cookie = dhcpofpstats.Id
Esin Karamanccb714b2019-11-29 15:02:06 +0000321
322 //multicast flow
323 multicastFa := &fu.FlowArgs{
324 MatchFields: []*ofp.OfpOxmOfbField{
325 fu.InPort(65536),
326 fu.VlanVid(660), //vlan
327 fu.Metadata_ofp(uint64(66)), //inner vlan
328 fu.EthType(0x800), //ipv4
329 fu.Ipv4Dst(3809869825), //227.22.0.1
330 },
331 Actions: []*ofp.OfpAction{
332 fu.Group(1),
333 },
334 }
divyadesaid26f6b12020-03-19 06:30:28 +0000335 multicastOfpStats, _ := fu.MkFlowStat(multicastFa)
Esin Karamanccb714b2019-11-29 15:02:06 +0000336 multicastOfpStats.Id = 1
337
kdarapu3248f9a2019-10-03 13:54:52 +0530338 type args struct {
339 flow *ofp.OfpFlowStats
340 }
341 tests := []struct {
342 name string
343 args args
344 }{
345 // TODO: Add test cases.
346 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530347 {"RemoveFlow", args{flow: lldpofpstats}},
348 {"RemoveFlow", args{flow: dhcpofpstats}},
Esin Karamanccb714b2019-11-29 15:02:06 +0000349 {"RemoveFlow", args{flow: multicastOfpStats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530350 }
npujarec5762e2020-01-01 14:08:48 +0530351 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
352 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530353 for _, tt := range tests {
354 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530355 flowMgr.RemoveFlow(ctx, tt.args.flow)
kdarapu3248f9a2019-10-03 13:54:52 +0530356 })
357 }
kdarapub26b4502019-10-05 03:02:33 +0530358 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530359}
360
361func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530362 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530363 kw := make(map[string]uint64)
364 kw["table_id"] = 1
365 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530366 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
367
368 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530369 fa := &fu.FlowArgs{
370 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530371 fu.InPort(536870912),
372 fu.Metadata_ofp(1),
373 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
374 },
375 Actions: []*ofp.OfpAction{
376 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
377 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
378 fu.Output(65536),
379 fu.PushVlan(0x8100),
380 },
381 KV: kw,
382 }
383
384 // Downstream flow
385 fa3 := &fu.FlowArgs{
386 MatchFields: []*ofp.OfpOxmOfbField{
387 fu.InPort(65536),
388 fu.Metadata_ofp(1),
389 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
390 },
391 Actions: []*ofp.OfpAction{
392 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
393 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
394 fu.PopVlan(),
395 fu.Output(536870912),
396 },
397 KV: kw,
398 }
399
400 fa2 := &fu.FlowArgs{
401 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530402 fu.InPort(1000),
403 fu.Metadata_ofp(1),
404 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
405 },
406 Actions: []*ofp.OfpAction{
407 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
408 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
409 fu.Output(65533),
410 },
411 KV: kw,
412 }
413
kdarapub26b4502019-10-05 03:02:33 +0530414 // TODO Add LLDP flow
415 // TODO Add DHCP flow
416
417 // Flows for negative scenarios
418 // Failure in formulateActionInfoFromFlow()
419 fa4 := &fu.FlowArgs{
420 MatchFields: []*ofp.OfpOxmOfbField{
421 fu.InPort(1000),
422 fu.Metadata_ofp(1),
423 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
424 },
425 Actions: []*ofp.OfpAction{
426 fu.Experimenter(257, []byte{1, 2, 3, 4}),
427 },
428 KV: kw,
429 }
430
431 // Invalid Output
432 fa5 := &fu.FlowArgs{
433 MatchFields: []*ofp.OfpOxmOfbField{
434 fu.InPort(1000),
435 fu.Metadata_ofp(1),
436 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
437 },
438 Actions: []*ofp.OfpAction{
439 fu.Output(0),
440 },
441 KV: kw,
442 }
443
444 // Tech-Profile-ID update (not supported)
445 kw6 := make(map[string]uint64)
446 kw6["table_id"] = 1
447 kw6["meter_id"] = 1
448 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
449 fa6 := &fu.FlowArgs{
450 MatchFields: []*ofp.OfpOxmOfbField{
451 fu.InPort(536870912),
452 fu.TunnelId(16),
453 fu.Metadata_ofp(1),
454 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
455 },
456 Actions: []*ofp.OfpAction{
457 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
458 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
459 fu.Output(65535),
460 },
461 KV: kw6,
462 }
463
464 lldpFa := &fu.FlowArgs{
465 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
466 MatchFields: []*ofp.OfpOxmOfbField{
467 fu.InPort(1),
468 fu.EthType(0x88CC),
469 fu.TunnelId(536870912),
470 },
471 Actions: []*ofp.OfpAction{
472 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
473 },
474 }
475
476 dhcpFa := &fu.FlowArgs{
477 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
478 MatchFields: []*ofp.OfpOxmOfbField{
479 fu.InPort(1),
480 fu.UdpSrc(67),
481 //fu.TunnelId(536870912),
482 fu.IpProto(17),
483 },
484 Actions: []*ofp.OfpAction{
485 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
486 },
487 }
488 igmpFa := &fu.FlowArgs{
489 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
490 MatchFields: []*ofp.OfpOxmOfbField{
491 fu.InPort(1),
492 fu.UdpSrc(67),
493 //fu.TunnelId(536870912),
494 fu.IpProto(2),
495 },
496 Actions: []*ofp.OfpAction{
497 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
498 },
499 }
500
501 fa9 := &fu.FlowArgs{
502 MatchFields: []*ofp.OfpOxmOfbField{
503 fu.InPort(536870912),
504 fu.TunnelId(16),
505 fu.Metadata_ofp(1),
506 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
507 fu.VlanPcp(1000),
508 fu.UdpDst(65535),
509 fu.UdpSrc(536870912),
510 fu.Ipv4Dst(65535),
511 fu.Ipv4Src(536870912),
512 },
513 Actions: []*ofp.OfpAction{
514 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
515 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
516 fu.Output(65535),
517 },
518 KV: kw6,
519 }
520
521 fa10 := &fu.FlowArgs{
522 MatchFields: []*ofp.OfpOxmOfbField{
523 fu.InPort(65533),
524 // fu.TunnelId(16),
525 fu.Metadata_ofp(1),
526 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
527 fu.VlanPcp(1000),
528 fu.UdpDst(65535),
529 fu.UdpSrc(536870912),
530 fu.Ipv4Dst(65535),
531 fu.Ipv4Src(536870912),
532 },
533 Actions: []*ofp.OfpAction{
534 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
535 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
536 fu.Output(65535),
537 },
538 KV: kw6,
539 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000540 //multicast flow
541 fa11 := &fu.FlowArgs{
542 MatchFields: []*ofp.OfpOxmOfbField{
543 fu.InPort(65536),
544 fu.VlanVid(660), //vlan
545 fu.Metadata_ofp(uint64(66)), //inner vlan
546 fu.EthType(0x800), //ipv4
547 fu.Ipv4Dst(3809869825), //227.22.0.1
548 },
549 Actions: []*ofp.OfpAction{
550 fu.Group(1),
551 },
552 KV: kw6,
553 }
divyadesaid26f6b12020-03-19 06:30:28 +0000554 ofpstats, _ := fu.MkFlowStat(fa)
555 ofpstats2, _ := fu.MkFlowStat(fa2)
556 ofpstats3, _ := fu.MkFlowStat(fa3)
557 ofpstats4, _ := fu.MkFlowStat(fa4)
558 ofpstats5, _ := fu.MkFlowStat(fa5)
559 ofpstats6, _ := fu.MkFlowStat(fa6)
560 ofpstats7, _ := fu.MkFlowStat(lldpFa)
561 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
562 ofpstats9, _ := fu.MkFlowStat(fa9)
563 ofpstats10, _ := fu.MkFlowStat(fa10)
564 igmpstats, _ := fu.MkFlowStat(igmpFa)
565 ofpstats11, _ := fu.MkFlowStat(fa11)
kdarapub26b4502019-10-05 03:02:33 +0530566
Gamze Abakafee36392019-10-03 11:17:24 +0000567 fmt.Println(ofpstats6, ofpstats9, ofpstats10)
568
kdarapu3248f9a2019-10-03 13:54:52 +0530569 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
kdarapu3248f9a2019-10-03 13:54:52 +0530570 flowMetadata := &voltha.FlowMetadata{
571 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
572 }
573 type args struct {
574 flow *ofp.OfpFlowStats
575 flowMetadata *voltha.FlowMetadata
576 }
577 tests := []struct {
578 name string
579 args args
580 }{
581 // TODO: Add test cases.
582 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530583 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
584 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
585 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
586 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000587 //{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530588 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
589 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000590 //{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530591 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000592 //{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530593 //ofpstats10
Esin Karamanccb714b2019-11-29 15:02:06 +0000594 {"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
kdarapu3248f9a2019-10-03 13:54:52 +0530595 }
npujarec5762e2020-01-01 14:08:48 +0530596 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
597 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530598 for _, tt := range tests {
599 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530600 flowMgr.AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
kdarapu3248f9a2019-10-03 13:54:52 +0530601 })
602 }
603}
604
605func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700606 flwMgr := newMockFlowmgr()
607
npujarec5762e2020-01-01 14:08:48 +0530608 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
609 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530610
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700611 wg := sync.WaitGroup{}
612
613 intfCount := 16
614 onuCount := 32
615
616 for i := 0; i < intfCount; i++ {
617 for j := 0; j < onuCount; j++ {
618 wg.Add(1)
619 go func(i uint32, j uint32) {
620 flwMgr.UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
621 wg.Done()
622 }(uint32(i), uint32(j))
623 }
624
625 }
626
627 wg.Wait()
628}
629
630func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
631 flowMgr = newMockFlowmgr()
632 intfNum := 16
633 onuNum := 32
634
635 // clean the flowMgr
636 flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, intfNum)
637
638 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
639 defer cancel()
640
641 // Create OnuInfo
642 for i := 0; i < intfNum; i++ {
643 for o := 0; o < onuNum; o++ {
644 flowMgr.UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o))
645 }
646 }
647
648 // Add gemPorts to OnuInfo in parallel threads
649 wg := sync.WaitGroup{}
650
651 for o := 0; o < onuNum; o++ {
652 for i := 0; i < intfNum; i++ {
653 wg.Add(1)
654 go func(intfId uint32, onuId uint32) {
655 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId))
656
657 flowMgr.addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
658 wg.Done()
659 }(uint32(i), uint32(o))
660 }
661 }
662
663 wg.Wait()
664
665 // check that each entry of onuGemInfo has the correct number of ONUs
666 for i := 0; i < intfNum; i++ {
667 lenofOnu := len(flowMgr.onuGemInfo[uint32(i)])
668 if onuNum != lenofOnu {
669 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
670 }
671
672 for o := 0; o < onuNum; o++ {
673 lenOfGemPorts := len(flowMgr.onuGemInfo[uint32(i)][o].GemPorts)
674 // check that each onuEntry has 1 gemPort
675 if lenOfGemPorts != 1 {
676 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
677 }
678
679 // check that the value of the gemport is correct
680 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o))
681 currentValue := flowMgr.onuGemInfo[uint32(i)][o].GemPorts[0]
682 if uint32(gemID) != currentValue {
683 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
684 }
685 }
kdarapu3248f9a2019-10-03 13:54:52 +0530686 }
687}
688
serkant.uluderya96af4932020-02-20 16:58:48 -0800689func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700690 flwMgr := newMockFlowmgr()
serkant.uluderya96af4932020-02-20 16:58:48 -0800691 type args struct {
692 intfID uint32
693 onuID uint32
694 gemPortIDs []uint32
695 gemPortIDsToBeDeleted []uint32
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700696 gemPortIDsRemaining []uint32
serkant.uluderya96af4932020-02-20 16:58:48 -0800697 serialNum string
698 finalLength int
699 }
700 tests := []struct {
701 name string
702 args args
703 }{
704 // Add/Delete single gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700705 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800706 // Delete all gemports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700707 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800708 // Try to delete when there is no gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700709 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800710 // Try to delete non-existent gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700711 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800712 // Try to delete two of the gem ports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700713 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800714 }
715 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
716 defer cancel()
717 for _, tt := range tests {
718 t.Run(tt.name, func(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700719 flwMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
serkant.uluderya96af4932020-02-20 16:58:48 -0800720 for _, gemPort := range tt.args.gemPortIDs {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700721 flwMgr.addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
serkant.uluderya96af4932020-02-20 16:58:48 -0800722 }
723 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700724 flwMgr.deleteGemPortFromLocalCache(ctx, tt.args.intfID, tt.args.onuID, gemPortDeleted)
serkant.uluderya96af4932020-02-20 16:58:48 -0800725 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700726 lenofGemPorts := len(flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts)
serkant.uluderya96af4932020-02-20 16:58:48 -0800727 if lenofGemPorts != tt.args.finalLength {
728 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
729 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700730 gemPorts := flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts
731 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
732 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
733 }
serkant.uluderya96af4932020-02-20 16:58:48 -0800734
735 })
736 }
737}
738
kdarapu3248f9a2019-10-03 13:54:52 +0530739func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700740 flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530741 type args struct {
742 packetIn *openoltpb2.PacketIndication
743 }
744 tests := []struct {
745 name string
746 args args
747 want uint32
748 wantErr bool
749 }{
750 // TODO: Add test cases.
751 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000752 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1048577, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530753 // Negative Test cases.
754 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000755 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 4112, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530756 }
npujarec5762e2020-01-01 14:08:48 +0530757 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
758 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530759 for _, tt := range tests {
760 t.Run(tt.name, func(t *testing.T) {
761
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700762 got, err := flwMgr.GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
kdarapu3248f9a2019-10-03 13:54:52 +0530763 if (err != nil) != tt.wantErr {
764 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
765 return
766 }
767 if got != tt.want {
768 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
769 }
770 })
771 }
772}
773
774func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530775 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530776
Esin Karaman7fb80c22020-07-16 14:23:33 +0000777 //untagged packet in hex string
778 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
779 untagged, err := hex.DecodeString(untaggedStr)
780 if err != nil {
781 t.Error("Unable to parse hex string", err)
782 panic(err)
783 }
784 //single-tagged packet in hex string. vlanID.pbit: 540.0
785 singleTaggedStr := "01005e0000010025ba48172481000225080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
786 singleTagged, err := hex.DecodeString(singleTaggedStr)
787 if err != nil {
788 t.Error("Unable to parse hex string", err)
789 panic(err)
790 }
791 //double-tagged packet in hex string. vlanID.pbit: 210.0-48.7
792 doubleTaggedStr := "01005e000016deadbeefba11810002108100e030080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
793 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
794 if err != nil {
795 t.Error("Unable to parse hex string", err)
796 panic(err)
797 }
798
kdarapu3248f9a2019-10-03 13:54:52 +0530799 type args struct {
800 intfID uint32
801 onuID uint32
802 portNum uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000803 packet []byte
kdarapu3248f9a2019-10-03 13:54:52 +0530804 }
805 tests := []struct {
806 name string
807 args args
808 want uint32
809 wantErr bool
810 }{
811 // TODO: Add test cases.
Esin Karaman7fb80c22020-07-16 14:23:33 +0000812 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: untagged}, 3, false},
813 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 4, packet: singleTagged}, 4, false},
814 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: doubleTagged}, 2, false},
815 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 10, portNum: 10, packet: untagged}, 2, true},
816 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530817 }
Esin Karaman7fb80c22020-07-16 14:23:33 +0000818
npujarec5762e2020-01-01 14:08:48 +0530819 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
820 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530821 for _, tt := range tests {
822 t.Run(tt.name, func(t *testing.T) {
823
Esin Karaman7fb80c22020-07-16 14:23:33 +0000824 got, err := flowMgr.GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum, tt.args.packet)
825 if tt.wantErr {
826 if err == nil {
827 //error expected but got value
828 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
829 }
830 } else {
831 if err != nil {
832 //error is not expected but got error
833 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
834 return
835 }
836 if got != tt.want {
837 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
838 }
kdarapu3248f9a2019-10-03 13:54:52 +0530839 }
kdarapu3248f9a2019-10-03 13:54:52 +0530840 })
841 }
842}
843
844func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530845 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530846 type args struct {
847 intfID uint32
848 onuID uint32
849 uniID uint32
850 sn string
Gamze Abakafee36392019-10-03 11:17:24 +0000851 tpID uint32
kdarapu3248f9a2019-10-03 13:54:52 +0530852 }
853 tests := []struct {
854 name string
855 args args
856 wantErr bool
857 }{
858 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000859 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530860 }
npujarec5762e2020-01-01 14:08:48 +0530861 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
862 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530863 for _, tt := range tests {
864 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530865 if err := flowMgr.DeleteTechProfileInstance(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.sn, tt.args.tpID); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530866 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
867 }
868 })
869 }
870}
kdarapub26b4502019-10-05 03:02:33 +0530871
872func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000873 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530874 // flowMgr := newMockFlowmgr()
875 kw := make(map[string]uint64)
876 kw["table_id"] = 1
877 kw["meter_id"] = 1
878 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
879
880 // Upstream flow
881 fa := &fu.FlowArgs{
882 MatchFields: []*ofp.OfpOxmOfbField{
883 fu.InPort(536870912),
884 fu.Metadata_ofp(1),
885 fu.IpProto(17), // dhcp
Gamze Abakafee36392019-10-03 11:17:24 +0000886 fu.VlanPcp(0),
kdarapub26b4502019-10-05 03:02:33 +0530887 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
888 },
889 Actions: []*ofp.OfpAction{
890 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
891 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
892 fu.Output(65536),
893 fu.PushVlan(0x8100),
894 },
895 KV: kw,
896 }
897
898 // EAPOL
899 fa2 := &fu.FlowArgs{
900 MatchFields: []*ofp.OfpOxmOfbField{
901 fu.InPort(536870912),
902 fu.Metadata_ofp(1),
903 fu.EthType(0x888E),
904 fu.VlanPcp(1),
905 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
906 },
907 Actions: []*ofp.OfpAction{
908 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
909 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
910 fu.Output(65536),
911 fu.PushVlan(0x8100),
912 },
913 KV: kw,
914 }
915
916 // HSIA
917 fa3 := &fu.FlowArgs{
918 MatchFields: []*ofp.OfpOxmOfbField{
919 fu.InPort(536870912),
920 fu.Metadata_ofp(1),
921 //fu.EthType(0x8100),
922 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
923 },
924 Actions: []*ofp.OfpAction{
925 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
926 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
927 fu.Output(65536),
928 fu.PushVlan(0x8100),
929 },
930 KV: kw,
931 }
932
933 fa4 := &fu.FlowArgs{
934 MatchFields: []*ofp.OfpOxmOfbField{
935 fu.InPort(65535),
936 fu.Metadata_ofp(1),
937 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
938 fu.VlanPcp(1),
939 },
940 Actions: []*ofp.OfpAction{
941 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
942 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
943 fu.Output(536870912),
944 fu.PopVlan(),
945 },
946 KV: kw,
947 }
948
949 classifierInfo := make(map[string]interface{})
950 actionInfo := make(map[string]interface{})
951 classifierInfo2 := make(map[string]interface{})
952 actionInfo2 := make(map[string]interface{})
953 classifierInfo3 := make(map[string]interface{})
954 actionInfo3 := make(map[string]interface{})
955 classifierInfo4 := make(map[string]interface{})
956 actionInfo4 := make(map[string]interface{})
divyadesaid26f6b12020-03-19 06:30:28 +0000957 flowState, _ := fu.MkFlowStat(fa)
958 flowState2, _ := fu.MkFlowStat(fa2)
959 flowState3, _ := fu.MkFlowStat(fa3)
960 flowState4, _ := fu.MkFlowStat(fa4)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961 formulateClassifierInfoFromFlow(ctx, classifierInfo, flowState)
962 formulateClassifierInfoFromFlow(ctx, classifierInfo2, flowState2)
963 formulateClassifierInfoFromFlow(ctx, classifierInfo3, flowState3)
964 formulateClassifierInfoFromFlow(ctx, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530965
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966 err := formulateActionInfoFromFlow(ctx, actionInfo, classifierInfo, flowState)
kdarapub26b4502019-10-05 03:02:33 +0530967 if err != nil {
968 // Error logging is already done in the called function
969 // So just return in case of error
970 return
971 }
972
Neha Sharma96b7bf22020-06-15 10:37:32 +0000973 err = formulateActionInfoFromFlow(ctx, actionInfo2, classifierInfo2, flowState2)
kdarapub26b4502019-10-05 03:02:33 +0530974 if err != nil {
975 // Error logging is already done in the called function
976 // So just return in case of error
977 return
978 }
979
Neha Sharma96b7bf22020-06-15 10:37:32 +0000980 err = formulateActionInfoFromFlow(ctx, actionInfo3, classifierInfo3, flowState3)
kdarapub26b4502019-10-05 03:02:33 +0530981 if err != nil {
982 // Error logging is already done in the called function
983 // So just return in case of error
984 return
985 }
986
Neha Sharma96b7bf22020-06-15 10:37:32 +0000987 err = formulateActionInfoFromFlow(ctx, actionInfo4, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530988 if err != nil {
989 // Error logging is already done in the called function
990 // So just return in case of error
991 return
992 }
993
994 //ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
995 //flowMetadata := &voltha.FlowMetadata{
996 // Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
997 //}
998
999 TpInst := &tp.TechProfile{
1000 Name: "Test-Tech-Profile",
1001 SubscriberIdentifier: "257",
1002 ProfileType: "Mock",
1003 Version: 1,
1004 NumGemPorts: 4,
kdarapub26b4502019-10-05 03:02:33 +05301005 InstanceCtrl: tp.InstanceControl{
1006 Onu: "1",
1007 Uni: "16",
1008 },
1009 }
1010
1011 type fields struct {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301012 techprofile []tp.TechProfileIf
1013 deviceHandler *DeviceHandler
1014 resourceMgr *rsrcMgr.OpenOltResourceMgr
kdarapub26b4502019-10-05 03:02:33 +05301015 }
1016 type args struct {
1017 args map[string]uint32
1018 classifierInfo map[string]interface{}
1019 actionInfo map[string]interface{}
1020 flow *ofp.OfpFlowStats
1021 gemPort uint32
1022 intfID uint32
1023 onuID uint32
1024 uniID uint32
1025 portNo uint32
1026 TpInst *tp.TechProfile
1027 allocID []uint32
1028 gemPorts []uint32
1029 TpID uint32
1030 uni string
1031 }
1032 tests := []struct {
1033 name string
1034 fields fields
1035 args args
1036 }{
1037 {
1038 name: "checkAndAddFlow-1",
1039 args: args{
1040 args: nil,
1041 classifierInfo: classifierInfo,
1042 actionInfo: actionInfo,
1043 flow: flowState,
1044 gemPort: 1,
1045 intfID: 1,
1046 onuID: 1,
1047 uniID: 16,
1048 portNo: 1,
1049 TpInst: TpInst,
1050 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1051 gemPorts: []uint32{1, 2, 3, 4},
1052 TpID: 64,
1053 uni: "16",
1054 },
1055 },
1056 {
1057 name: "checkAndAddFlow-2",
1058 args: args{
1059 args: nil,
1060 classifierInfo: classifierInfo2,
1061 actionInfo: actionInfo2,
1062 flow: flowState2,
1063 gemPort: 1,
1064 intfID: 1,
1065 onuID: 1,
1066 uniID: 16,
1067 portNo: 1,
1068 TpInst: TpInst,
1069 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1070 gemPorts: []uint32{1, 2, 3, 4},
1071 TpID: 64,
1072 uni: "16",
1073 },
1074 },
1075 {
1076 name: "checkAndAddFlow-3",
1077 args: args{
1078 args: nil,
1079 classifierInfo: classifierInfo3,
1080 actionInfo: actionInfo3,
1081 flow: flowState3,
1082 gemPort: 1,
1083 intfID: 1,
1084 onuID: 1,
1085 uniID: 16,
1086 portNo: 1,
1087 TpInst: TpInst,
1088 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1089 gemPorts: []uint32{1, 2, 3, 4},
1090 TpID: 64,
1091 uni: "16",
1092 },
1093 },
1094 {
1095 name: "checkAndAddFlow-4",
1096 args: args{
1097 args: nil,
1098 classifierInfo: classifierInfo4,
1099 actionInfo: actionInfo4,
1100 flow: flowState4,
1101 gemPort: 1,
1102 intfID: 1,
1103 onuID: 1,
1104 uniID: 16,
1105 portNo: 1,
1106 TpInst: TpInst,
1107 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1108 gemPorts: []uint32{1, 2, 3, 4},
1109 TpID: 64,
1110 uni: "16",
1111 },
1112 },
1113 }
npujarec5762e2020-01-01 14:08:48 +05301114 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1115 defer cancel()
kdarapub26b4502019-10-05 03:02:33 +05301116 for _, tt := range tests {
1117 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301118 flowMgr.checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
Gamze Abakafee36392019-10-03 11:17:24 +00001119 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
kdarapub26b4502019-10-05 03:02:33 +05301120 })
1121 }
1122}
Esin Karamanccb714b2019-11-29 15:02:06 +00001123
Esin Karamand519bbf2020-07-01 11:16:03 +00001124func TestOpenOltFlowMgr_TestMulticastFlowAndGroup(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301125 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1126 defer cancel()
Esin Karamanccb714b2019-11-29 15:02:06 +00001127 //create group
1128 group := newGroup(2, []uint32{1})
Esin Karamand519bbf2020-07-01 11:16:03 +00001129 err := flowMgr.AddGroup(ctx, group)
1130 if err != nil {
1131 t.Error("group-add failed", err)
1132 return
1133 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001134 //create multicast flow
1135 multicastFlowArgs := &fu.FlowArgs{
1136 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karamand519bbf2020-07-01 11:16:03 +00001137 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +00001138 fu.VlanVid(660), //vlan
1139 fu.Metadata_ofp(uint64(66)), //inner vlan
1140 fu.EthType(0x800), //ipv4
1141 fu.Ipv4Dst(3809869825), //227.22.0.1
1142 },
1143 Actions: []*ofp.OfpAction{
1144 fu.Group(1),
1145 },
1146 }
divyadesaid26f6b12020-03-19 06:30:28 +00001147 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
Esin Karamand519bbf2020-07-01 11:16:03 +00001148 fmt.Println(ofpStats.Id)
1149 err = flowMgr.AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
1150 if err != nil {
1151 t.Error("Multicast flow-add failed", err)
1152 return
1153 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001154
1155 //add bucket to the group
1156 group = newGroup(2, []uint32{1, 2})
Esin Karamand519bbf2020-07-01 11:16:03 +00001157 err = flowMgr.ModifyGroup(ctx, group)
1158 if err != nil {
1159 t.Error("modify-group failed", err)
1160 return
1161 }
1162 //remove the multicast flow
1163 err = flowMgr.RemoveFlow(ctx, ofpStats)
1164 if err != nil {
1165 t.Error("Multicast flow-remove failed", err)
1166 return
1167 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001168
Esin Karamand519bbf2020-07-01 11:16:03 +00001169 //remove the group
1170 err = flowMgr.DeleteGroup(ctx, group)
1171 if err != nil {
1172 t.Error("delete-group failed", err)
1173 return
1174 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001175}