blob: 490a40ca3473785026cff2d844e8cd5426ac6a2b [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() {
Kent Hagermane6ff1012020-07-14 15:07:53 -040048 _, _ = 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 }
kdarapu3248f9a2019-10-03 13:54:52 +0530137 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000138 name string
139 schedQueue schedQueue
140 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530141 }{
142 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000143 {"CreateSchedulerQueues-1", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, flowmetadata}, false},
144 {"CreateSchedulerQueues-2", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
145 {"CreateSchedulerQueues-3", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, flowmetadata}, true},
146 {"CreateSchedulerQueues-4", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, flowmetadata}, true},
147 {"CreateSchedulerQueues-5", schedQueue{tp_pb.Direction_UPSTREAM, 2, 2, 2, 64, 2, tprofile, 2, flowmetadata}, true},
148 {"CreateSchedulerQueues-6", schedQueue{tp_pb.Direction_DOWNSTREAM, 2, 2, 2, 65, 2, tprofile2, 2, flowmetadata}, true},
149 {"CreateSchedulerQueues-13", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530150 //Negative testcases
Gamze Abakafee36392019-10-03 11:17:24 +0000151 {"CreateSchedulerQueues-7", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, &voltha.FlowMetadata{}}, true},
152 {"CreateSchedulerQueues-8", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, &voltha.FlowMetadata{}}, true},
153 {"CreateSchedulerQueues-9", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, &voltha.FlowMetadata{}}, true},
154 {"CreateSchedulerQueues-10", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, &voltha.FlowMetadata{}}, true},
155 {"CreateSchedulerQueues-11", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, &voltha.FlowMetadata{}}, true},
156 {"CreateSchedulerQueues-12", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, nil}, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530157 }
npujarec5762e2020-01-01 14:08:48 +0530158 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
159 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530160 for _, tt := range tests {
161 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530162 if err := flowMgr.CreateSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530163 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
164 }
165 })
166 }
167}
168
169func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
170
kdarapub26b4502019-10-05 03:02:33 +0530171 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530172 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
Girish Gowdra54934262019-11-13 14:19:55 +0530173 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
kdarapu3248f9a2019-10-03 13:54:52 +0530174 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
175 }
176 tprofile.UsScheduler.Direction = "UPSTREAM"
177 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
178 tprofile.UsScheduler.QSchedPolicy = "WRR"
179
180 tprofile2 := tprofile
181 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
182 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
183 tprofile2.DsScheduler.QSchedPolicy = "WRR"
184 //defTprofile := &tp.DefaultTechProfile{}
kdarapu3248f9a2019-10-03 13:54:52 +0530185 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000186 name string
187 schedQueue schedQueue
188 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530189 }{
190 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000191 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, nil}, false},
192 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530193 // negative test cases
Gamze Abakafee36392019-10-03 11:17:24 +0000194 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
195 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530196 }
npujarec5762e2020-01-01 14:08:48 +0530197 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
198 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530199 for _, tt := range tests {
200 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530201 if err := flowMgr.RemoveSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530202 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
203 }
204 })
205 }
kdarapub26b4502019-10-05 03:02:33 +0530206
kdarapu3248f9a2019-10-03 13:54:52 +0530207}
208
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700209func TestOpenOltFlowMgr_createTcontGemports(t *testing.T) {
210 // flowMgr := newMockFlowmgr()
211 bands := make([]*ofp.OfpMeterBandHeader, 2)
212 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
213 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
214 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
215 flowmetadata := &voltha.FlowMetadata{
216 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
217 }
218 type args struct {
219 intfID uint32
220 onuID uint32
221 uniID uint32
222 uni string
223 uniPort uint32
224 TpID uint32
225 UsMeterID uint32
226 DsMeterID uint32
227 flowMetadata *voltha.FlowMetadata
228 }
229 tests := []struct {
230 name string
231 args args
232 }{
233 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 64, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
234 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 65, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
235 }
236 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
237 defer cancel()
238 for _, tt := range tests {
239 t.Run(tt.name, func(t *testing.T) {
240 _, _, 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)
241 switch tpInst := tpInst.(type) {
242 case *tp.TechProfile:
243 if tt.args.TpID != 64 {
244 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
245 }
246 case *tp.EponProfile:
247 if tt.args.TpID != 65 {
248 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
249 }
250 default:
251 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
252 }
253 })
254 }
255}
256
kdarapu3248f9a2019-10-03 13:54:52 +0530257func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530259 // flowMgr := newMockFlowmgr()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000260 logger.Debug(ctx, "Info Warning Error: Starting RemoveFlow() test")
kdarapu3248f9a2019-10-03 13:54:52 +0530261 fa := &fu.FlowArgs{
262 MatchFields: []*ofp.OfpOxmOfbField{
263 fu.InPort(2),
264 fu.Metadata_ofp(2),
265 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
266 },
267 Actions: []*ofp.OfpAction{
268 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
269 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
270 fu.Output(1),
271 },
272 }
divyadesaid26f6b12020-03-19 06:30:28 +0000273 ofpstats, _ := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530274 ofpstats.Cookie = ofpstats.Id
kdarapub26b4502019-10-05 03:02:33 +0530275 lldpFa := &fu.FlowArgs{
276 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
277 MatchFields: []*ofp.OfpOxmOfbField{
278 fu.InPort(1),
279 fu.EthType(0x88CC),
280 fu.TunnelId(536870912),
281 },
282 Actions: []*ofp.OfpAction{
283 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
284 },
285 }
divyadesaid26f6b12020-03-19 06:30:28 +0000286 lldpofpstats, _ := fu.MkFlowStat(lldpFa)
kdarapub26b4502019-10-05 03:02:33 +0530287 //lldpofpstats.Cookie = lldpofpstats.Id
288
289 dhcpFa := &fu.FlowArgs{
290 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
291 MatchFields: []*ofp.OfpOxmOfbField{
292 fu.InPort(1),
293 fu.UdpSrc(67),
294 //fu.TunnelId(536870912),
295 fu.IpProto(17),
296 },
297 Actions: []*ofp.OfpAction{
298 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
299 },
300 }
divyadesaid26f6b12020-03-19 06:30:28 +0000301 dhcpofpstats, _ := fu.MkFlowStat(dhcpFa)
kdarapub26b4502019-10-05 03:02:33 +0530302 //dhcpofpstats.Cookie = dhcpofpstats.Id
Esin Karamanccb714b2019-11-29 15:02:06 +0000303
304 //multicast flow
305 multicastFa := &fu.FlowArgs{
306 MatchFields: []*ofp.OfpOxmOfbField{
307 fu.InPort(65536),
308 fu.VlanVid(660), //vlan
309 fu.Metadata_ofp(uint64(66)), //inner vlan
310 fu.EthType(0x800), //ipv4
311 fu.Ipv4Dst(3809869825), //227.22.0.1
312 },
313 Actions: []*ofp.OfpAction{
314 fu.Group(1),
315 },
316 }
divyadesaid26f6b12020-03-19 06:30:28 +0000317 multicastOfpStats, _ := fu.MkFlowStat(multicastFa)
Esin Karamanccb714b2019-11-29 15:02:06 +0000318 multicastOfpStats.Id = 1
319
kdarapu3248f9a2019-10-03 13:54:52 +0530320 type args struct {
321 flow *ofp.OfpFlowStats
322 }
323 tests := []struct {
324 name string
325 args args
326 }{
327 // TODO: Add test cases.
328 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530329 {"RemoveFlow", args{flow: lldpofpstats}},
330 {"RemoveFlow", args{flow: dhcpofpstats}},
Esin Karamanccb714b2019-11-29 15:02:06 +0000331 {"RemoveFlow", args{flow: multicastOfpStats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530332 }
npujarec5762e2020-01-01 14:08:48 +0530333 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
334 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530335 for _, tt := range tests {
336 t.Run(tt.name, func(t *testing.T) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400337 if err := flowMgr.RemoveFlow(ctx, tt.args.flow); err != nil {
338 logger.Warn(ctx, err)
339 }
kdarapu3248f9a2019-10-03 13:54:52 +0530340 })
341 }
kdarapub26b4502019-10-05 03:02:33 +0530342 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530343}
344
345func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530346 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530347 kw := make(map[string]uint64)
348 kw["table_id"] = 1
349 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530350 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
351
352 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530353 fa := &fu.FlowArgs{
354 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530355 fu.InPort(536870912),
356 fu.Metadata_ofp(1),
357 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
358 },
359 Actions: []*ofp.OfpAction{
360 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
361 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
362 fu.Output(65536),
363 fu.PushVlan(0x8100),
364 },
365 KV: kw,
366 }
367
368 // Downstream flow
369 fa3 := &fu.FlowArgs{
370 MatchFields: []*ofp.OfpOxmOfbField{
371 fu.InPort(65536),
372 fu.Metadata_ofp(1),
373 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
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) | 101)),
378 fu.PopVlan(),
379 fu.Output(536870912),
380 },
381 KV: kw,
382 }
383
384 fa2 := &fu.FlowArgs{
385 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530386 fu.InPort(1000),
387 fu.Metadata_ofp(1),
388 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
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.Output(65533),
394 },
395 KV: kw,
396 }
397
kdarapub26b4502019-10-05 03:02:33 +0530398 // TODO Add LLDP flow
399 // TODO Add DHCP flow
400
401 // Flows for negative scenarios
402 // Failure in formulateActionInfoFromFlow()
403 fa4 := &fu.FlowArgs{
404 MatchFields: []*ofp.OfpOxmOfbField{
405 fu.InPort(1000),
406 fu.Metadata_ofp(1),
407 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
408 },
409 Actions: []*ofp.OfpAction{
410 fu.Experimenter(257, []byte{1, 2, 3, 4}),
411 },
412 KV: kw,
413 }
414
415 // Invalid Output
416 fa5 := &fu.FlowArgs{
417 MatchFields: []*ofp.OfpOxmOfbField{
418 fu.InPort(1000),
419 fu.Metadata_ofp(1),
420 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
421 },
422 Actions: []*ofp.OfpAction{
423 fu.Output(0),
424 },
425 KV: kw,
426 }
427
428 // Tech-Profile-ID update (not supported)
429 kw6 := make(map[string]uint64)
430 kw6["table_id"] = 1
431 kw6["meter_id"] = 1
432 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
433 fa6 := &fu.FlowArgs{
434 MatchFields: []*ofp.OfpOxmOfbField{
435 fu.InPort(536870912),
436 fu.TunnelId(16),
437 fu.Metadata_ofp(1),
438 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
439 },
440 Actions: []*ofp.OfpAction{
441 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
442 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
443 fu.Output(65535),
444 },
445 KV: kw6,
446 }
447
448 lldpFa := &fu.FlowArgs{
449 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
450 MatchFields: []*ofp.OfpOxmOfbField{
451 fu.InPort(1),
452 fu.EthType(0x88CC),
453 fu.TunnelId(536870912),
454 },
455 Actions: []*ofp.OfpAction{
456 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
457 },
458 }
459
460 dhcpFa := &fu.FlowArgs{
461 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
462 MatchFields: []*ofp.OfpOxmOfbField{
463 fu.InPort(1),
464 fu.UdpSrc(67),
465 //fu.TunnelId(536870912),
466 fu.IpProto(17),
467 },
468 Actions: []*ofp.OfpAction{
469 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
470 },
471 }
472 igmpFa := &fu.FlowArgs{
473 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
474 MatchFields: []*ofp.OfpOxmOfbField{
475 fu.InPort(1),
476 fu.UdpSrc(67),
477 //fu.TunnelId(536870912),
478 fu.IpProto(2),
479 },
480 Actions: []*ofp.OfpAction{
481 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
482 },
483 }
484
485 fa9 := &fu.FlowArgs{
486 MatchFields: []*ofp.OfpOxmOfbField{
487 fu.InPort(536870912),
488 fu.TunnelId(16),
489 fu.Metadata_ofp(1),
490 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
491 fu.VlanPcp(1000),
492 fu.UdpDst(65535),
493 fu.UdpSrc(536870912),
494 fu.Ipv4Dst(65535),
495 fu.Ipv4Src(536870912),
496 },
497 Actions: []*ofp.OfpAction{
498 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
499 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
500 fu.Output(65535),
501 },
502 KV: kw6,
503 }
504
505 fa10 := &fu.FlowArgs{
506 MatchFields: []*ofp.OfpOxmOfbField{
507 fu.InPort(65533),
508 // fu.TunnelId(16),
509 fu.Metadata_ofp(1),
510 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
511 fu.VlanPcp(1000),
512 fu.UdpDst(65535),
513 fu.UdpSrc(536870912),
514 fu.Ipv4Dst(65535),
515 fu.Ipv4Src(536870912),
516 },
517 Actions: []*ofp.OfpAction{
518 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
519 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
520 fu.Output(65535),
521 },
522 KV: kw6,
523 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000524 //multicast flow
525 fa11 := &fu.FlowArgs{
526 MatchFields: []*ofp.OfpOxmOfbField{
527 fu.InPort(65536),
528 fu.VlanVid(660), //vlan
529 fu.Metadata_ofp(uint64(66)), //inner vlan
530 fu.EthType(0x800), //ipv4
531 fu.Ipv4Dst(3809869825), //227.22.0.1
532 },
533 Actions: []*ofp.OfpAction{
534 fu.Group(1),
535 },
536 KV: kw6,
537 }
divyadesaid26f6b12020-03-19 06:30:28 +0000538 ofpstats, _ := fu.MkFlowStat(fa)
539 ofpstats2, _ := fu.MkFlowStat(fa2)
540 ofpstats3, _ := fu.MkFlowStat(fa3)
541 ofpstats4, _ := fu.MkFlowStat(fa4)
542 ofpstats5, _ := fu.MkFlowStat(fa5)
543 ofpstats6, _ := fu.MkFlowStat(fa6)
544 ofpstats7, _ := fu.MkFlowStat(lldpFa)
545 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
546 ofpstats9, _ := fu.MkFlowStat(fa9)
547 ofpstats10, _ := fu.MkFlowStat(fa10)
548 igmpstats, _ := fu.MkFlowStat(igmpFa)
549 ofpstats11, _ := fu.MkFlowStat(fa11)
kdarapub26b4502019-10-05 03:02:33 +0530550
Gamze Abakafee36392019-10-03 11:17:24 +0000551 fmt.Println(ofpstats6, ofpstats9, ofpstats10)
552
kdarapu3248f9a2019-10-03 13:54:52 +0530553 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
kdarapu3248f9a2019-10-03 13:54:52 +0530554 flowMetadata := &voltha.FlowMetadata{
555 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
556 }
557 type args struct {
558 flow *ofp.OfpFlowStats
559 flowMetadata *voltha.FlowMetadata
560 }
561 tests := []struct {
562 name string
563 args args
564 }{
565 // TODO: Add test cases.
566 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530567 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
568 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
569 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
570 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000571 //{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530572 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
573 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000574 //{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530575 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000576 //{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530577 //ofpstats10
Esin Karamanccb714b2019-11-29 15:02:06 +0000578 {"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
kdarapu3248f9a2019-10-03 13:54:52 +0530579 }
npujarec5762e2020-01-01 14:08:48 +0530580 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
581 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530582 for _, tt := range tests {
583 t.Run(tt.name, func(t *testing.T) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400584 _ = flowMgr.AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
585 // TODO: actually verify test cases
kdarapu3248f9a2019-10-03 13:54:52 +0530586 })
587 }
588}
589
590func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700591 flwMgr := newMockFlowmgr()
592
npujarec5762e2020-01-01 14:08:48 +0530593 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
594 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530595
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700596 wg := sync.WaitGroup{}
597
598 intfCount := 16
599 onuCount := 32
600
601 for i := 0; i < intfCount; i++ {
602 for j := 0; j < onuCount; j++ {
603 wg.Add(1)
604 go func(i uint32, j uint32) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400605 // TODO: actually verify success
606 _ = flwMgr.UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700607 wg.Done()
608 }(uint32(i), uint32(j))
609 }
610
611 }
612
613 wg.Wait()
614}
615
616func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
617 flowMgr = newMockFlowmgr()
618 intfNum := 16
619 onuNum := 32
620
621 // clean the flowMgr
622 flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, intfNum)
623
624 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
625 defer cancel()
626
627 // Create OnuInfo
628 for i := 0; i < intfNum; i++ {
629 for o := 0; o < onuNum; o++ {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400630 // TODO: actually verify success
631 _ = flowMgr.UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700632 }
633 }
634
635 // Add gemPorts to OnuInfo in parallel threads
636 wg := sync.WaitGroup{}
637
638 for o := 0; o < onuNum; o++ {
639 for i := 0; i < intfNum; i++ {
640 wg.Add(1)
641 go func(intfId uint32, onuId uint32) {
642 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId))
643
644 flowMgr.addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
645 wg.Done()
646 }(uint32(i), uint32(o))
647 }
648 }
649
650 wg.Wait()
651
652 // check that each entry of onuGemInfo has the correct number of ONUs
653 for i := 0; i < intfNum; i++ {
654 lenofOnu := len(flowMgr.onuGemInfo[uint32(i)])
655 if onuNum != lenofOnu {
656 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
657 }
658
659 for o := 0; o < onuNum; o++ {
660 lenOfGemPorts := len(flowMgr.onuGemInfo[uint32(i)][o].GemPorts)
661 // check that each onuEntry has 1 gemPort
662 if lenOfGemPorts != 1 {
663 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
664 }
665
666 // check that the value of the gemport is correct
667 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o))
668 currentValue := flowMgr.onuGemInfo[uint32(i)][o].GemPorts[0]
669 if uint32(gemID) != currentValue {
670 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
671 }
672 }
kdarapu3248f9a2019-10-03 13:54:52 +0530673 }
674}
675
serkant.uluderya96af4932020-02-20 16:58:48 -0800676func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700677 flwMgr := newMockFlowmgr()
serkant.uluderya96af4932020-02-20 16:58:48 -0800678 type args struct {
679 intfID uint32
680 onuID uint32
681 gemPortIDs []uint32
682 gemPortIDsToBeDeleted []uint32
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700683 gemPortIDsRemaining []uint32
serkant.uluderya96af4932020-02-20 16:58:48 -0800684 serialNum string
685 finalLength int
686 }
687 tests := []struct {
688 name string
689 args args
690 }{
691 // Add/Delete single gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700692 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800693 // Delete all gemports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700694 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800695 // Try to delete when there is no gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700696 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800697 // Try to delete non-existent gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700698 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800699 // Try to delete two of the gem ports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700700 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800701 }
702 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
703 defer cancel()
704 for _, tt := range tests {
705 t.Run(tt.name, func(t *testing.T) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400706 // TODO: should check returned errors are as expected?
707 _ = flwMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
serkant.uluderya96af4932020-02-20 16:58:48 -0800708 for _, gemPort := range tt.args.gemPortIDs {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700709 flwMgr.addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
serkant.uluderya96af4932020-02-20 16:58:48 -0800710 }
711 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700712 flwMgr.deleteGemPortFromLocalCache(ctx, tt.args.intfID, tt.args.onuID, gemPortDeleted)
serkant.uluderya96af4932020-02-20 16:58:48 -0800713 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700714 lenofGemPorts := len(flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts)
serkant.uluderya96af4932020-02-20 16:58:48 -0800715 if lenofGemPorts != tt.args.finalLength {
716 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
717 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700718 gemPorts := flwMgr.onuGemInfo[tt.args.intfID][0].GemPorts
719 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
720 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
721 }
serkant.uluderya96af4932020-02-20 16:58:48 -0800722
723 })
724 }
725}
726
kdarapu3248f9a2019-10-03 13:54:52 +0530727func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700728 flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530729 type args struct {
730 packetIn *openoltpb2.PacketIndication
731 }
732 tests := []struct {
733 name string
734 args args
735 want uint32
736 wantErr bool
737 }{
738 // TODO: Add test cases.
739 {"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 +0000740 {"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 +0530741 // Negative Test cases.
742 {"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 +0000743 {"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 +0530744 }
npujarec5762e2020-01-01 14:08:48 +0530745 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
746 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530747 for _, tt := range tests {
748 t.Run(tt.name, func(t *testing.T) {
749
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700750 got, err := flwMgr.GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
kdarapu3248f9a2019-10-03 13:54:52 +0530751 if (err != nil) != tt.wantErr {
752 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
753 return
754 }
755 if got != tt.want {
756 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
757 }
758 })
759 }
760}
761
762func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530763 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530764
Esin Karaman7fb80c22020-07-16 14:23:33 +0000765 //untagged packet in hex string
766 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
767 untagged, err := hex.DecodeString(untaggedStr)
768 if err != nil {
769 t.Error("Unable to parse hex string", err)
770 panic(err)
771 }
772 //single-tagged packet in hex string. vlanID.pbit: 540.0
773 singleTaggedStr := "01005e0000010025ba48172481000225080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
774 singleTagged, err := hex.DecodeString(singleTaggedStr)
775 if err != nil {
776 t.Error("Unable to parse hex string", err)
777 panic(err)
778 }
779 //double-tagged packet in hex string. vlanID.pbit: 210.0-48.7
780 doubleTaggedStr := "01005e000016deadbeefba11810002108100e030080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
781 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
782 if err != nil {
783 t.Error("Unable to parse hex string", err)
784 panic(err)
785 }
786
kdarapu3248f9a2019-10-03 13:54:52 +0530787 type args struct {
788 intfID uint32
789 onuID uint32
790 portNum uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000791 packet []byte
kdarapu3248f9a2019-10-03 13:54:52 +0530792 }
793 tests := []struct {
794 name string
795 args args
796 want uint32
797 wantErr bool
798 }{
799 // TODO: Add test cases.
Esin Karaman7fb80c22020-07-16 14:23:33 +0000800 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: untagged}, 3, false},
801 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 4, packet: singleTagged}, 4, false},
802 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: doubleTagged}, 2, false},
803 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 10, portNum: 10, packet: untagged}, 2, true},
804 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530805 }
Esin Karaman7fb80c22020-07-16 14:23:33 +0000806
npujarec5762e2020-01-01 14:08:48 +0530807 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
808 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530809 for _, tt := range tests {
810 t.Run(tt.name, func(t *testing.T) {
811
Esin Karaman7fb80c22020-07-16 14:23:33 +0000812 got, err := flowMgr.GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum, tt.args.packet)
813 if tt.wantErr {
814 if err == nil {
815 //error expected but got value
816 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
817 }
818 } else {
819 if err != nil {
820 //error is not expected but got error
821 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
822 return
823 }
824 if got != tt.want {
825 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
826 }
kdarapu3248f9a2019-10-03 13:54:52 +0530827 }
kdarapu3248f9a2019-10-03 13:54:52 +0530828 })
829 }
830}
831
832func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530833 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530834 type args struct {
835 intfID uint32
836 onuID uint32
837 uniID uint32
838 sn string
Gamze Abakafee36392019-10-03 11:17:24 +0000839 tpID uint32
kdarapu3248f9a2019-10-03 13:54:52 +0530840 }
841 tests := []struct {
842 name string
843 args args
844 wantErr bool
845 }{
846 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000847 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530848 }
npujarec5762e2020-01-01 14:08:48 +0530849 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
850 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530851 for _, tt := range tests {
852 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530853 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 +0530854 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
855 }
856 })
857 }
858}
kdarapub26b4502019-10-05 03:02:33 +0530859
860func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000861 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530862 // flowMgr := newMockFlowmgr()
863 kw := make(map[string]uint64)
864 kw["table_id"] = 1
865 kw["meter_id"] = 1
866 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
867
868 // Upstream flow
869 fa := &fu.FlowArgs{
870 MatchFields: []*ofp.OfpOxmOfbField{
871 fu.InPort(536870912),
872 fu.Metadata_ofp(1),
873 fu.IpProto(17), // dhcp
Gamze Abakafee36392019-10-03 11:17:24 +0000874 fu.VlanPcp(0),
kdarapub26b4502019-10-05 03:02:33 +0530875 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
876 },
877 Actions: []*ofp.OfpAction{
878 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
879 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
880 fu.Output(65536),
881 fu.PushVlan(0x8100),
882 },
883 KV: kw,
884 }
885
886 // EAPOL
887 fa2 := &fu.FlowArgs{
888 MatchFields: []*ofp.OfpOxmOfbField{
889 fu.InPort(536870912),
890 fu.Metadata_ofp(1),
891 fu.EthType(0x888E),
892 fu.VlanPcp(1),
893 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
894 },
895 Actions: []*ofp.OfpAction{
896 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
897 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
898 fu.Output(65536),
899 fu.PushVlan(0x8100),
900 },
901 KV: kw,
902 }
903
904 // HSIA
905 fa3 := &fu.FlowArgs{
906 MatchFields: []*ofp.OfpOxmOfbField{
907 fu.InPort(536870912),
908 fu.Metadata_ofp(1),
909 //fu.EthType(0x8100),
910 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
911 },
912 Actions: []*ofp.OfpAction{
913 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
914 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
915 fu.Output(65536),
916 fu.PushVlan(0x8100),
917 },
918 KV: kw,
919 }
920
921 fa4 := &fu.FlowArgs{
922 MatchFields: []*ofp.OfpOxmOfbField{
923 fu.InPort(65535),
924 fu.Metadata_ofp(1),
925 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
926 fu.VlanPcp(1),
927 },
928 Actions: []*ofp.OfpAction{
929 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
930 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
931 fu.Output(536870912),
932 fu.PopVlan(),
933 },
934 KV: kw,
935 }
936
937 classifierInfo := make(map[string]interface{})
938 actionInfo := make(map[string]interface{})
939 classifierInfo2 := make(map[string]interface{})
940 actionInfo2 := make(map[string]interface{})
941 classifierInfo3 := make(map[string]interface{})
942 actionInfo3 := make(map[string]interface{})
943 classifierInfo4 := make(map[string]interface{})
944 actionInfo4 := make(map[string]interface{})
divyadesaid26f6b12020-03-19 06:30:28 +0000945 flowState, _ := fu.MkFlowStat(fa)
946 flowState2, _ := fu.MkFlowStat(fa2)
947 flowState3, _ := fu.MkFlowStat(fa3)
948 flowState4, _ := fu.MkFlowStat(fa4)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000949 formulateClassifierInfoFromFlow(ctx, classifierInfo, flowState)
950 formulateClassifierInfoFromFlow(ctx, classifierInfo2, flowState2)
951 formulateClassifierInfoFromFlow(ctx, classifierInfo3, flowState3)
952 formulateClassifierInfoFromFlow(ctx, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530953
Neha Sharma96b7bf22020-06-15 10:37:32 +0000954 err := formulateActionInfoFromFlow(ctx, actionInfo, classifierInfo, flowState)
kdarapub26b4502019-10-05 03:02:33 +0530955 if err != nil {
956 // Error logging is already done in the called function
957 // So just return in case of error
958 return
959 }
960
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961 err = formulateActionInfoFromFlow(ctx, actionInfo2, classifierInfo2, flowState2)
kdarapub26b4502019-10-05 03:02:33 +0530962 if err != nil {
963 // Error logging is already done in the called function
964 // So just return in case of error
965 return
966 }
967
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 err = formulateActionInfoFromFlow(ctx, actionInfo3, classifierInfo3, flowState3)
kdarapub26b4502019-10-05 03:02:33 +0530969 if err != nil {
970 // Error logging is already done in the called function
971 // So just return in case of error
972 return
973 }
974
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975 err = formulateActionInfoFromFlow(ctx, actionInfo4, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530976 if err != nil {
977 // Error logging is already done in the called function
978 // So just return in case of error
979 return
980 }
981
982 //ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
983 //flowMetadata := &voltha.FlowMetadata{
984 // Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
985 //}
986
987 TpInst := &tp.TechProfile{
988 Name: "Test-Tech-Profile",
989 SubscriberIdentifier: "257",
990 ProfileType: "Mock",
991 Version: 1,
992 NumGemPorts: 4,
kdarapub26b4502019-10-05 03:02:33 +0530993 InstanceCtrl: tp.InstanceControl{
994 Onu: "1",
995 Uni: "16",
996 },
997 }
998
kdarapub26b4502019-10-05 03:02:33 +0530999 type args struct {
1000 args map[string]uint32
1001 classifierInfo map[string]interface{}
1002 actionInfo map[string]interface{}
1003 flow *ofp.OfpFlowStats
1004 gemPort uint32
1005 intfID uint32
1006 onuID uint32
1007 uniID uint32
1008 portNo uint32
1009 TpInst *tp.TechProfile
1010 allocID []uint32
1011 gemPorts []uint32
1012 TpID uint32
1013 uni string
1014 }
1015 tests := []struct {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001016 name string
1017 args args
kdarapub26b4502019-10-05 03:02:33 +05301018 }{
1019 {
1020 name: "checkAndAddFlow-1",
1021 args: args{
1022 args: nil,
1023 classifierInfo: classifierInfo,
1024 actionInfo: actionInfo,
1025 flow: flowState,
1026 gemPort: 1,
1027 intfID: 1,
1028 onuID: 1,
1029 uniID: 16,
1030 portNo: 1,
1031 TpInst: TpInst,
1032 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1033 gemPorts: []uint32{1, 2, 3, 4},
1034 TpID: 64,
1035 uni: "16",
1036 },
1037 },
1038 {
1039 name: "checkAndAddFlow-2",
1040 args: args{
1041 args: nil,
1042 classifierInfo: classifierInfo2,
1043 actionInfo: actionInfo2,
1044 flow: flowState2,
1045 gemPort: 1,
1046 intfID: 1,
1047 onuID: 1,
1048 uniID: 16,
1049 portNo: 1,
1050 TpInst: TpInst,
1051 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1052 gemPorts: []uint32{1, 2, 3, 4},
1053 TpID: 64,
1054 uni: "16",
1055 },
1056 },
1057 {
1058 name: "checkAndAddFlow-3",
1059 args: args{
1060 args: nil,
1061 classifierInfo: classifierInfo3,
1062 actionInfo: actionInfo3,
1063 flow: flowState3,
1064 gemPort: 1,
1065 intfID: 1,
1066 onuID: 1,
1067 uniID: 16,
1068 portNo: 1,
1069 TpInst: TpInst,
1070 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1071 gemPorts: []uint32{1, 2, 3, 4},
1072 TpID: 64,
1073 uni: "16",
1074 },
1075 },
1076 {
1077 name: "checkAndAddFlow-4",
1078 args: args{
1079 args: nil,
1080 classifierInfo: classifierInfo4,
1081 actionInfo: actionInfo4,
1082 flow: flowState4,
1083 gemPort: 1,
1084 intfID: 1,
1085 onuID: 1,
1086 uniID: 16,
1087 portNo: 1,
1088 TpInst: TpInst,
1089 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1090 gemPorts: []uint32{1, 2, 3, 4},
1091 TpID: 64,
1092 uni: "16",
1093 },
1094 },
1095 }
npujarec5762e2020-01-01 14:08:48 +05301096 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1097 defer cancel()
kdarapub26b4502019-10-05 03:02:33 +05301098 for _, tt := range tests {
1099 t.Run(tt.name, func(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301100 flowMgr.checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
Gamze Abakafee36392019-10-03 11:17:24 +00001101 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
kdarapub26b4502019-10-05 03:02:33 +05301102 })
1103 }
1104}
Esin Karamanccb714b2019-11-29 15:02:06 +00001105
Esin Karamand519bbf2020-07-01 11:16:03 +00001106func TestOpenOltFlowMgr_TestMulticastFlowAndGroup(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301107 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1108 defer cancel()
Esin Karamanccb714b2019-11-29 15:02:06 +00001109 //create group
1110 group := newGroup(2, []uint32{1})
Esin Karamand519bbf2020-07-01 11:16:03 +00001111 err := flowMgr.AddGroup(ctx, group)
1112 if err != nil {
1113 t.Error("group-add failed", err)
1114 return
1115 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001116 //create multicast flow
1117 multicastFlowArgs := &fu.FlowArgs{
1118 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karamand519bbf2020-07-01 11:16:03 +00001119 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +00001120 fu.VlanVid(660), //vlan
1121 fu.Metadata_ofp(uint64(66)), //inner vlan
1122 fu.EthType(0x800), //ipv4
1123 fu.Ipv4Dst(3809869825), //227.22.0.1
1124 },
1125 Actions: []*ofp.OfpAction{
1126 fu.Group(1),
1127 },
1128 }
divyadesaid26f6b12020-03-19 06:30:28 +00001129 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
Esin Karamand519bbf2020-07-01 11:16:03 +00001130 fmt.Println(ofpStats.Id)
1131 err = flowMgr.AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
1132 if err != nil {
1133 t.Error("Multicast flow-add failed", err)
1134 return
1135 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001136
1137 //add bucket to the group
1138 group = newGroup(2, []uint32{1, 2})
Esin Karamand519bbf2020-07-01 11:16:03 +00001139 err = flowMgr.ModifyGroup(ctx, group)
1140 if err != nil {
1141 t.Error("modify-group failed", err)
1142 return
1143 }
1144 //remove the multicast flow
1145 err = flowMgr.RemoveFlow(ctx, ofpStats)
1146 if err != nil {
1147 t.Error("Multicast flow-remove failed", err)
1148 return
1149 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001150
Esin Karamand519bbf2020-07-01 11:16:03 +00001151 //remove the group
1152 err = flowMgr.DeleteGroup(ctx, group)
1153 if err != nil {
1154 t.Error("delete-group failed", err)
1155 return
1156 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001157}