blob: b5c5220bb69c6721970731a82f93f1b4425a0bea [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 Karaman04166c82020-07-16 14:23:33 +000022 "encoding/hex"
Gamze Abakafee36392019-10-03 11:17:24 +000023 "fmt"
Matteo Scandolo60913ed2020-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 Scandolo60913ed2020-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 Scandolo60913ed2020-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) {
kdarapub26b4502019-10-05 03:02:33 +0530276 // flowMgr := newMockFlowmgr()
Girish Kumar2ad402b2020-03-20 19:45:12 +0000277 logger.Debug("Info Warning Error: Starting RemoveFlow() test")
kdarapu3248f9a2019-10-03 13:54:52 +0530278 fa := &fu.FlowArgs{
279 MatchFields: []*ofp.OfpOxmOfbField{
280 fu.InPort(2),
281 fu.Metadata_ofp(2),
282 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
283 },
284 Actions: []*ofp.OfpAction{
285 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
286 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
287 fu.Output(1),
288 },
289 }
divyadesaid26f6b12020-03-19 06:30:28 +0000290 ofpstats, _ := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530291 ofpstats.Cookie = ofpstats.Id
kdarapub26b4502019-10-05 03:02:33 +0530292 lldpFa := &fu.FlowArgs{
293 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
294 MatchFields: []*ofp.OfpOxmOfbField{
295 fu.InPort(1),
296 fu.EthType(0x88CC),
297 fu.TunnelId(536870912),
298 },
299 Actions: []*ofp.OfpAction{
300 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
301 },
302 }
divyadesaid26f6b12020-03-19 06:30:28 +0000303 lldpofpstats, _ := fu.MkFlowStat(lldpFa)
kdarapub26b4502019-10-05 03:02:33 +0530304 //lldpofpstats.Cookie = lldpofpstats.Id
305
306 dhcpFa := &fu.FlowArgs{
307 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
308 MatchFields: []*ofp.OfpOxmOfbField{
309 fu.InPort(1),
310 fu.UdpSrc(67),
311 //fu.TunnelId(536870912),
312 fu.IpProto(17),
313 },
314 Actions: []*ofp.OfpAction{
315 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
316 },
317 }
divyadesaid26f6b12020-03-19 06:30:28 +0000318 dhcpofpstats, _ := fu.MkFlowStat(dhcpFa)
kdarapub26b4502019-10-05 03:02:33 +0530319 //dhcpofpstats.Cookie = dhcpofpstats.Id
Esin Karamanccb714b2019-11-29 15:02:06 +0000320
321 //multicast flow
322 multicastFa := &fu.FlowArgs{
323 MatchFields: []*ofp.OfpOxmOfbField{
324 fu.InPort(65536),
325 fu.VlanVid(660), //vlan
326 fu.Metadata_ofp(uint64(66)), //inner vlan
327 fu.EthType(0x800), //ipv4
328 fu.Ipv4Dst(3809869825), //227.22.0.1
329 },
330 Actions: []*ofp.OfpAction{
331 fu.Group(1),
332 },
333 }
divyadesaid26f6b12020-03-19 06:30:28 +0000334 multicastOfpStats, _ := fu.MkFlowStat(multicastFa)
Esin Karamanccb714b2019-11-29 15:02:06 +0000335 multicastOfpStats.Id = 1
336
kdarapu3248f9a2019-10-03 13:54:52 +0530337 type args struct {
338 flow *ofp.OfpFlowStats
339 }
340 tests := []struct {
341 name string
342 args args
343 }{
344 // TODO: Add test cases.
345 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530346 {"RemoveFlow", args{flow: lldpofpstats}},
347 {"RemoveFlow", args{flow: dhcpofpstats}},
Esin Karamanccb714b2019-11-29 15:02:06 +0000348 {"RemoveFlow", args{flow: multicastOfpStats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530349 }
npujarec5762e2020-01-01 14:08:48 +0530350 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
351 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530352 for _, tt := range tests {
353 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530354 flowMgr.RemoveFlow(ctx, tt.args.flow)
kdarapu3248f9a2019-10-03 13:54:52 +0530355 })
356 }
kdarapub26b4502019-10-05 03:02:33 +0530357 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530358}
359
360func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530361 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530362 kw := make(map[string]uint64)
363 kw["table_id"] = 1
364 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530365 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
366
367 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530368 fa := &fu.FlowArgs{
369 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530370 fu.InPort(536870912),
371 fu.Metadata_ofp(1),
372 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
373 },
374 Actions: []*ofp.OfpAction{
375 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
376 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
377 fu.Output(65536),
378 fu.PushVlan(0x8100),
379 },
380 KV: kw,
381 }
382
383 // Downstream flow
384 fa3 := &fu.FlowArgs{
385 MatchFields: []*ofp.OfpOxmOfbField{
386 fu.InPort(65536),
387 fu.Metadata_ofp(1),
388 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
389 },
390 Actions: []*ofp.OfpAction{
391 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
392 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
393 fu.PopVlan(),
394 fu.Output(536870912),
395 },
396 KV: kw,
397 }
398
399 fa2 := &fu.FlowArgs{
400 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530401 fu.InPort(1000),
402 fu.Metadata_ofp(1),
403 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
404 },
405 Actions: []*ofp.OfpAction{
406 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
407 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
408 fu.Output(65533),
409 },
410 KV: kw,
411 }
412
kdarapub26b4502019-10-05 03:02:33 +0530413 // TODO Add LLDP flow
414 // TODO Add DHCP flow
415
416 // Flows for negative scenarios
417 // Failure in formulateActionInfoFromFlow()
418 fa4 := &fu.FlowArgs{
419 MatchFields: []*ofp.OfpOxmOfbField{
420 fu.InPort(1000),
421 fu.Metadata_ofp(1),
422 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
423 },
424 Actions: []*ofp.OfpAction{
425 fu.Experimenter(257, []byte{1, 2, 3, 4}),
426 },
427 KV: kw,
428 }
429
430 // Invalid Output
431 fa5 := &fu.FlowArgs{
432 MatchFields: []*ofp.OfpOxmOfbField{
433 fu.InPort(1000),
434 fu.Metadata_ofp(1),
435 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
436 },
437 Actions: []*ofp.OfpAction{
438 fu.Output(0),
439 },
440 KV: kw,
441 }
442
443 // Tech-Profile-ID update (not supported)
444 kw6 := make(map[string]uint64)
445 kw6["table_id"] = 1
446 kw6["meter_id"] = 1
447 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
448 fa6 := &fu.FlowArgs{
449 MatchFields: []*ofp.OfpOxmOfbField{
450 fu.InPort(536870912),
451 fu.TunnelId(16),
452 fu.Metadata_ofp(1),
453 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
454 },
455 Actions: []*ofp.OfpAction{
456 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
457 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
458 fu.Output(65535),
459 },
460 KV: kw6,
461 }
462
463 lldpFa := &fu.FlowArgs{
464 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
465 MatchFields: []*ofp.OfpOxmOfbField{
466 fu.InPort(1),
467 fu.EthType(0x88CC),
468 fu.TunnelId(536870912),
469 },
470 Actions: []*ofp.OfpAction{
471 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
472 },
473 }
474
475 dhcpFa := &fu.FlowArgs{
476 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
477 MatchFields: []*ofp.OfpOxmOfbField{
478 fu.InPort(1),
479 fu.UdpSrc(67),
480 //fu.TunnelId(536870912),
481 fu.IpProto(17),
482 },
483 Actions: []*ofp.OfpAction{
484 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
485 },
486 }
487 igmpFa := &fu.FlowArgs{
488 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
489 MatchFields: []*ofp.OfpOxmOfbField{
490 fu.InPort(1),
491 fu.UdpSrc(67),
492 //fu.TunnelId(536870912),
493 fu.IpProto(2),
494 },
495 Actions: []*ofp.OfpAction{
496 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
497 },
498 }
499
500 fa9 := &fu.FlowArgs{
501 MatchFields: []*ofp.OfpOxmOfbField{
502 fu.InPort(536870912),
503 fu.TunnelId(16),
504 fu.Metadata_ofp(1),
505 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
506 fu.VlanPcp(1000),
507 fu.UdpDst(65535),
508 fu.UdpSrc(536870912),
509 fu.Ipv4Dst(65535),
510 fu.Ipv4Src(536870912),
511 },
512 Actions: []*ofp.OfpAction{
513 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
514 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
515 fu.Output(65535),
516 },
517 KV: kw6,
518 }
519
520 fa10 := &fu.FlowArgs{
521 MatchFields: []*ofp.OfpOxmOfbField{
522 fu.InPort(65533),
523 // fu.TunnelId(16),
524 fu.Metadata_ofp(1),
525 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
526 fu.VlanPcp(1000),
527 fu.UdpDst(65535),
528 fu.UdpSrc(536870912),
529 fu.Ipv4Dst(65535),
530 fu.Ipv4Src(536870912),
531 },
532 Actions: []*ofp.OfpAction{
533 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
534 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
535 fu.Output(65535),
536 },
537 KV: kw6,
538 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000539 //multicast flow
540 fa11 := &fu.FlowArgs{
541 MatchFields: []*ofp.OfpOxmOfbField{
542 fu.InPort(65536),
543 fu.VlanVid(660), //vlan
544 fu.Metadata_ofp(uint64(66)), //inner vlan
545 fu.EthType(0x800), //ipv4
546 fu.Ipv4Dst(3809869825), //227.22.0.1
547 },
548 Actions: []*ofp.OfpAction{
549 fu.Group(1),
550 },
551 KV: kw6,
552 }
divyadesaid26f6b12020-03-19 06:30:28 +0000553 ofpstats, _ := fu.MkFlowStat(fa)
554 ofpstats2, _ := fu.MkFlowStat(fa2)
555 ofpstats3, _ := fu.MkFlowStat(fa3)
556 ofpstats4, _ := fu.MkFlowStat(fa4)
557 ofpstats5, _ := fu.MkFlowStat(fa5)
558 ofpstats6, _ := fu.MkFlowStat(fa6)
559 ofpstats7, _ := fu.MkFlowStat(lldpFa)
560 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
561 ofpstats9, _ := fu.MkFlowStat(fa9)
562 ofpstats10, _ := fu.MkFlowStat(fa10)
563 igmpstats, _ := fu.MkFlowStat(igmpFa)
564 ofpstats11, _ := fu.MkFlowStat(fa11)
kdarapub26b4502019-10-05 03:02:33 +0530565
Gamze Abakafee36392019-10-03 11:17:24 +0000566 fmt.Println(ofpstats6, ofpstats9, ofpstats10)
567
kdarapu3248f9a2019-10-03 13:54:52 +0530568 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
kdarapu3248f9a2019-10-03 13:54:52 +0530569 flowMetadata := &voltha.FlowMetadata{
570 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
571 }
572 type args struct {
573 flow *ofp.OfpFlowStats
574 flowMetadata *voltha.FlowMetadata
575 }
576 tests := []struct {
577 name string
578 args args
579 }{
580 // TODO: Add test cases.
581 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530582 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
583 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
584 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
585 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000586 //{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530587 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
588 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000589 //{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530590 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000591 //{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530592 //ofpstats10
Esin Karamanccb714b2019-11-29 15:02:06 +0000593 {"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
kdarapu3248f9a2019-10-03 13:54:52 +0530594 }
npujarec5762e2020-01-01 14:08:48 +0530595 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
596 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530597 for _, tt := range tests {
598 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530599 flowMgr.AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
kdarapu3248f9a2019-10-03 13:54:52 +0530600 })
601 }
602}
603
604func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700605 flwMgr := newMockFlowmgr()
606
npujarec5762e2020-01-01 14:08:48 +0530607 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
608 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530609
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700610 wg := sync.WaitGroup{}
611
612 intfCount := 16
613 onuCount := 32
614
615 for i := 0; i < intfCount; i++ {
616 for j := 0; j < onuCount; j++ {
617 wg.Add(1)
618 go func(i uint32, j uint32) {
619 flwMgr.UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
620 wg.Done()
621 }(uint32(i), uint32(j))
622 }
623
624 }
625
626 wg.Wait()
627}
628
629func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
630 flowMgr = newMockFlowmgr()
631 intfNum := 16
632 onuNum := 32
633
634 // clean the flowMgr
635 flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, intfNum)
636
637 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
638 defer cancel()
639
640 // Create OnuInfo
641 for i := 0; i < intfNum; i++ {
642 for o := 0; o < onuNum; o++ {
643 flowMgr.UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o))
644 }
645 }
646
647 // Add gemPorts to OnuInfo in parallel threads
648 wg := sync.WaitGroup{}
649
650 for o := 0; o < onuNum; o++ {
651 for i := 0; i < intfNum; i++ {
652 wg.Add(1)
653 go func(intfId uint32, onuId uint32) {
654 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId))
655
656 flowMgr.addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
657 wg.Done()
658 }(uint32(i), uint32(o))
659 }
660 }
661
662 wg.Wait()
663
664 // check that each entry of onuGemInfo has the correct number of ONUs
665 for i := 0; i < intfNum; i++ {
666 lenofOnu := len(flowMgr.onuGemInfo[uint32(i)])
667 if onuNum != lenofOnu {
668 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
669 }
670
671 for o := 0; o < onuNum; o++ {
672 lenOfGemPorts := len(flowMgr.onuGemInfo[uint32(i)][o].GemPorts)
673 // check that each onuEntry has 1 gemPort
674 if lenOfGemPorts != 1 {
675 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
676 }
677
678 // check that the value of the gemport is correct
679 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o))
680 currentValue := flowMgr.onuGemInfo[uint32(i)][o].GemPorts[0]
681 if uint32(gemID) != currentValue {
682 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
683 }
684 }
kdarapu3248f9a2019-10-03 13:54:52 +0530685 }
686}
687
serkant.uluderya96af4932020-02-20 16:58:48 -0800688func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700689 flwMgr := newMockFlowmgr()
serkant.uluderya96af4932020-02-20 16:58:48 -0800690 type args struct {
691 intfID uint32
692 onuID uint32
693 gemPortIDs []uint32
694 gemPortIDsToBeDeleted []uint32
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700695 gemPortIDsRemaining []uint32
serkant.uluderya96af4932020-02-20 16:58:48 -0800696 serialNum string
697 finalLength int
698 }
699 tests := []struct {
700 name string
701 args args
702 }{
703 // Add/Delete single gem port
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700704 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800705 // Delete all gemports
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700706 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800707 // Try to delete when there is no gem port
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700708 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800709 // Try to delete non-existent gem port
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700710 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800711 // Try to delete two of the gem ports
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700712 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800713 }
714 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
715 defer cancel()
716 for _, tt := range tests {
717 t.Run(tt.name, func(t *testing.T) {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700718 flwMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
serkant.uluderya96af4932020-02-20 16:58:48 -0800719 for _, gemPort := range tt.args.gemPortIDs {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700720 flwMgr.addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
serkant.uluderya96af4932020-02-20 16:58:48 -0800721 }
722 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700723 flwMgr.deleteGemPortFromLocalCache(tt.args.intfID, tt.args.onuID, gemPortDeleted)
serkant.uluderya96af4932020-02-20 16:58:48 -0800724 }
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700725 lenofGemPorts := len(flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts)
serkant.uluderya96af4932020-02-20 16:58:48 -0800726 if lenofGemPorts != tt.args.finalLength {
727 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
728 }
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700729 gemPorts := flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts
730 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
731 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
732 }
serkant.uluderya96af4932020-02-20 16:58:48 -0800733
734 })
735 }
736}
737
kdarapu3248f9a2019-10-03 13:54:52 +0530738func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700739 flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530740 type args struct {
741 packetIn *openoltpb2.PacketIndication
742 }
743 tests := []struct {
744 name string
745 args args
746 want uint32
747 wantErr bool
748 }{
749 // TODO: Add test cases.
750 {"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 +0000751 {"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 +0530752 // Negative Test cases.
753 {"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 +0000754 {"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 +0530755 }
npujarec5762e2020-01-01 14:08:48 +0530756 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
757 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530758 for _, tt := range tests {
759 t.Run(tt.name, func(t *testing.T) {
760
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700761 got, err := flwMgr.GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
kdarapu3248f9a2019-10-03 13:54:52 +0530762 if (err != nil) != tt.wantErr {
763 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
764 return
765 }
766 if got != tt.want {
767 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
768 }
769 })
770 }
771}
772
773func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530774 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530775
Esin Karaman04166c82020-07-16 14:23:33 +0000776 //untagged packet in hex string
777 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
778 untagged, err := hex.DecodeString(untaggedStr)
779 if err != nil {
780 t.Error("Unable to parse hex string", err)
781 panic(err)
782 }
783 //single-tagged packet in hex string. vlanID.pbit: 540.0
784 singleTaggedStr := "01005e0000010025ba48172481000225080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
785 singleTagged, err := hex.DecodeString(singleTaggedStr)
786 if err != nil {
787 t.Error("Unable to parse hex string", err)
788 panic(err)
789 }
790 //double-tagged packet in hex string. vlanID.pbit: 210.0-48.7
791 doubleTaggedStr := "01005e000016deadbeefba11810002108100e030080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
792 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
793 if err != nil {
794 t.Error("Unable to parse hex string", err)
795 panic(err)
796 }
797
kdarapu3248f9a2019-10-03 13:54:52 +0530798 type args struct {
799 intfID uint32
800 onuID uint32
801 portNum uint32
Esin Karaman04166c82020-07-16 14:23:33 +0000802 packet []byte
kdarapu3248f9a2019-10-03 13:54:52 +0530803 }
804 tests := []struct {
805 name string
806 args args
807 want uint32
808 wantErr bool
809 }{
810 // TODO: Add test cases.
Esin Karaman04166c82020-07-16 14:23:33 +0000811 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: untagged}, 3, false},
812 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 4, packet: singleTagged}, 4, false},
813 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: doubleTagged}, 2, false},
814 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 10, portNum: 10, packet: untagged}, 2, true},
815 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530816 }
Esin Karaman04166c82020-07-16 14:23:33 +0000817
npujarec5762e2020-01-01 14:08:48 +0530818 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
819 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530820 for _, tt := range tests {
821 t.Run(tt.name, func(t *testing.T) {
822
Esin Karaman04166c82020-07-16 14:23:33 +0000823 got, err := flowMgr.GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum, tt.args.packet)
824 if tt.wantErr {
825 if err == nil {
826 //error expected but got value
827 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
828 }
829 } else {
830 if err != nil {
831 //error is not expected but got error
832 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
833 return
834 }
835 if got != tt.want {
836 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
837 }
kdarapu3248f9a2019-10-03 13:54:52 +0530838 }
kdarapu3248f9a2019-10-03 13:54:52 +0530839 })
840 }
841}
842
843func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530844 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530845 type args struct {
846 intfID uint32
847 onuID uint32
848 uniID uint32
849 sn string
Gamze Abakafee36392019-10-03 11:17:24 +0000850 tpID uint32
kdarapu3248f9a2019-10-03 13:54:52 +0530851 }
852 tests := []struct {
853 name string
854 args args
855 wantErr bool
856 }{
857 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000858 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530859 }
npujarec5762e2020-01-01 14:08:48 +0530860 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
861 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530862 for _, tt := range tests {
863 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530864 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 +0530865 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
866 }
867 })
868 }
869}
kdarapub26b4502019-10-05 03:02:33 +0530870
871func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
872 // flowMgr := newMockFlowmgr()
873 kw := make(map[string]uint64)
874 kw["table_id"] = 1
875 kw["meter_id"] = 1
876 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
877
878 // Upstream flow
879 fa := &fu.FlowArgs{
880 MatchFields: []*ofp.OfpOxmOfbField{
881 fu.InPort(536870912),
882 fu.Metadata_ofp(1),
883 fu.IpProto(17), // dhcp
Gamze Abakafee36392019-10-03 11:17:24 +0000884 fu.VlanPcp(0),
kdarapub26b4502019-10-05 03:02:33 +0530885 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
886 },
887 Actions: []*ofp.OfpAction{
888 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
889 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
890 fu.Output(65536),
891 fu.PushVlan(0x8100),
892 },
893 KV: kw,
894 }
895
896 // EAPOL
897 fa2 := &fu.FlowArgs{
898 MatchFields: []*ofp.OfpOxmOfbField{
899 fu.InPort(536870912),
900 fu.Metadata_ofp(1),
901 fu.EthType(0x888E),
902 fu.VlanPcp(1),
903 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
904 },
905 Actions: []*ofp.OfpAction{
906 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
907 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
908 fu.Output(65536),
909 fu.PushVlan(0x8100),
910 },
911 KV: kw,
912 }
913
914 // HSIA
915 fa3 := &fu.FlowArgs{
916 MatchFields: []*ofp.OfpOxmOfbField{
917 fu.InPort(536870912),
918 fu.Metadata_ofp(1),
919 //fu.EthType(0x8100),
920 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
921 },
922 Actions: []*ofp.OfpAction{
923 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
924 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
925 fu.Output(65536),
926 fu.PushVlan(0x8100),
927 },
928 KV: kw,
929 }
930
931 fa4 := &fu.FlowArgs{
932 MatchFields: []*ofp.OfpOxmOfbField{
933 fu.InPort(65535),
934 fu.Metadata_ofp(1),
935 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
936 fu.VlanPcp(1),
937 },
938 Actions: []*ofp.OfpAction{
939 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
940 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
941 fu.Output(536870912),
942 fu.PopVlan(),
943 },
944 KV: kw,
945 }
946
947 classifierInfo := make(map[string]interface{})
948 actionInfo := make(map[string]interface{})
949 classifierInfo2 := make(map[string]interface{})
950 actionInfo2 := make(map[string]interface{})
951 classifierInfo3 := make(map[string]interface{})
952 actionInfo3 := make(map[string]interface{})
953 classifierInfo4 := make(map[string]interface{})
954 actionInfo4 := make(map[string]interface{})
divyadesaid26f6b12020-03-19 06:30:28 +0000955 flowState, _ := fu.MkFlowStat(fa)
956 flowState2, _ := fu.MkFlowStat(fa2)
957 flowState3, _ := fu.MkFlowStat(fa3)
958 flowState4, _ := fu.MkFlowStat(fa4)
kdarapub26b4502019-10-05 03:02:33 +0530959 formulateClassifierInfoFromFlow(classifierInfo, flowState)
960 formulateClassifierInfoFromFlow(classifierInfo2, flowState2)
961 formulateClassifierInfoFromFlow(classifierInfo3, flowState3)
962 formulateClassifierInfoFromFlow(classifierInfo4, flowState4)
963
964 err := formulateActionInfoFromFlow(actionInfo, classifierInfo, flowState)
965 if err != nil {
966 // Error logging is already done in the called function
967 // So just return in case of error
968 return
969 }
970
971 err = formulateActionInfoFromFlow(actionInfo2, classifierInfo2, flowState2)
972 if err != nil {
973 // Error logging is already done in the called function
974 // So just return in case of error
975 return
976 }
977
978 err = formulateActionInfoFromFlow(actionInfo3, classifierInfo3, flowState3)
979 if err != nil {
980 // Error logging is already done in the called function
981 // So just return in case of error
982 return
983 }
984
985 err = formulateActionInfoFromFlow(actionInfo4, classifierInfo4, flowState4)
986 if err != nil {
987 // Error logging is already done in the called function
988 // So just return in case of error
989 return
990 }
991
992 //ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
993 //flowMetadata := &voltha.FlowMetadata{
994 // Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
995 //}
996
997 TpInst := &tp.TechProfile{
998 Name: "Test-Tech-Profile",
999 SubscriberIdentifier: "257",
1000 ProfileType: "Mock",
1001 Version: 1,
1002 NumGemPorts: 4,
kdarapub26b4502019-10-05 03:02:33 +05301003 InstanceCtrl: tp.InstanceControl{
1004 Onu: "1",
1005 Uni: "16",
1006 },
1007 }
1008
1009 type fields struct {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301010 techprofile []tp.TechProfileIf
1011 deviceHandler *DeviceHandler
1012 resourceMgr *rsrcMgr.OpenOltResourceMgr
kdarapub26b4502019-10-05 03:02:33 +05301013 }
1014 type args struct {
1015 args map[string]uint32
1016 classifierInfo map[string]interface{}
1017 actionInfo map[string]interface{}
1018 flow *ofp.OfpFlowStats
1019 gemPort uint32
1020 intfID uint32
1021 onuID uint32
1022 uniID uint32
1023 portNo uint32
1024 TpInst *tp.TechProfile
1025 allocID []uint32
1026 gemPorts []uint32
1027 TpID uint32
1028 uni string
1029 }
1030 tests := []struct {
1031 name string
1032 fields fields
1033 args args
1034 }{
1035 {
1036 name: "checkAndAddFlow-1",
1037 args: args{
1038 args: nil,
1039 classifierInfo: classifierInfo,
1040 actionInfo: actionInfo,
1041 flow: flowState,
1042 gemPort: 1,
1043 intfID: 1,
1044 onuID: 1,
1045 uniID: 16,
1046 portNo: 1,
1047 TpInst: TpInst,
1048 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1049 gemPorts: []uint32{1, 2, 3, 4},
1050 TpID: 64,
1051 uni: "16",
1052 },
1053 },
1054 {
1055 name: "checkAndAddFlow-2",
1056 args: args{
1057 args: nil,
1058 classifierInfo: classifierInfo2,
1059 actionInfo: actionInfo2,
1060 flow: flowState2,
1061 gemPort: 1,
1062 intfID: 1,
1063 onuID: 1,
1064 uniID: 16,
1065 portNo: 1,
1066 TpInst: TpInst,
1067 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1068 gemPorts: []uint32{1, 2, 3, 4},
1069 TpID: 64,
1070 uni: "16",
1071 },
1072 },
1073 {
1074 name: "checkAndAddFlow-3",
1075 args: args{
1076 args: nil,
1077 classifierInfo: classifierInfo3,
1078 actionInfo: actionInfo3,
1079 flow: flowState3,
1080 gemPort: 1,
1081 intfID: 1,
1082 onuID: 1,
1083 uniID: 16,
1084 portNo: 1,
1085 TpInst: TpInst,
1086 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1087 gemPorts: []uint32{1, 2, 3, 4},
1088 TpID: 64,
1089 uni: "16",
1090 },
1091 },
1092 {
1093 name: "checkAndAddFlow-4",
1094 args: args{
1095 args: nil,
1096 classifierInfo: classifierInfo4,
1097 actionInfo: actionInfo4,
1098 flow: flowState4,
1099 gemPort: 1,
1100 intfID: 1,
1101 onuID: 1,
1102 uniID: 16,
1103 portNo: 1,
1104 TpInst: TpInst,
1105 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1106 gemPorts: []uint32{1, 2, 3, 4},
1107 TpID: 64,
1108 uni: "16",
1109 },
1110 },
1111 }
npujarec5762e2020-01-01 14:08:48 +05301112 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1113 defer cancel()
kdarapub26b4502019-10-05 03:02:33 +05301114 for _, tt := range tests {
1115 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301116 flowMgr.checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
Gamze Abakafee36392019-10-03 11:17:24 +00001117 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
kdarapub26b4502019-10-05 03:02:33 +05301118 })
1119 }
1120}
Esin Karamanccb714b2019-11-29 15:02:06 +00001121
1122func TestOpenOltFlowMgr_TestMulticastFlow(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301123 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1124 defer cancel()
Esin Karamanccb714b2019-11-29 15:02:06 +00001125 //create group
1126 group := newGroup(2, []uint32{1})
npujarec5762e2020-01-01 14:08:48 +05301127 flowMgr.AddGroup(ctx, group)
Esin Karamanccb714b2019-11-29 15:02:06 +00001128
1129 //create multicast flow
1130 multicastFlowArgs := &fu.FlowArgs{
1131 MatchFields: []*ofp.OfpOxmOfbField{
1132 fu.InPort(65536),
1133 fu.VlanVid(660), //vlan
1134 fu.Metadata_ofp(uint64(66)), //inner vlan
1135 fu.EthType(0x800), //ipv4
1136 fu.Ipv4Dst(3809869825), //227.22.0.1
1137 },
1138 Actions: []*ofp.OfpAction{
1139 fu.Group(1),
1140 },
1141 }
divyadesaid26f6b12020-03-19 06:30:28 +00001142 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
npujarec5762e2020-01-01 14:08:48 +05301143 flowMgr.AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
Esin Karamanccb714b2019-11-29 15:02:06 +00001144
1145 //add bucket to the group
1146 group = newGroup(2, []uint32{1, 2})
1147
npujarec5762e2020-01-01 14:08:48 +05301148 flowMgr.ModifyGroup(ctx, group)
Esin Karamanccb714b2019-11-29 15:02:06 +00001149}