blob: fad128a94c70867154a5b2b836d5ee5b46cc5ca7 [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
Girish Gowdraa09aeab2020-09-14 16:30:52 -070030 "github.com/opencord/voltha-protos/v4/go/voltha"
kdarapub26b4502019-10-05 03:02:33 +053031
Girish Gowdraa09aeab2020-09-14 16:30:52 -070032 "github.com/opencord/voltha-lib-go/v4/pkg/db"
33 fu "github.com/opencord/voltha-lib-go/v4/pkg/flows"
34 "github.com/opencord/voltha-lib-go/v4/pkg/log"
35 tp "github.com/opencord/voltha-lib-go/v4/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"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070039 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
40 "github.com/opencord/voltha-protos/v4/go/openolt"
41 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
42 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
kdarapu3248f9a2019-10-03 13:54:52 +053043)
44
Girish Gowdra9602eb42020-09-09 15:50:39 -070045var flowMgr []*OpenOltFlowMgr
kdarapub26b4502019-10-05 03:02:33 +053046
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",
Girish Gowdra9602eb42020-09-09 15:50:39 -070061 OnuIdStart: OnuIDStart, OnuIdEnd: OnuIDEnd, AllocIdStart: AllocIDStart, AllocIdEnd: AllocIDEnd,
62 GemportIdStart: GemIDStart, GemportIdEnd: GemIDEnd, FlowIdStart: FlowIDStart, FlowIdEnd: FlowIDEnd,
kdarapu3248f9a2019-10-03 13:54:52 +053063 Ranges: ranges,
64 }
npujarec5762e2020-01-01 14:08:48 +053065 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
66 defer cancel()
Matteo Scandolodfa7a972020-11-06 13:03:40 -080067 rsrMgr := resourcemanager.NewResourceMgr(ctx, "olt", "127.0.0.1:2379", "etcd", "olt", deviceinfo, "service/voltha")
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
Girish Gowdra9602eb42020-09-09 15:50:39 -070076func 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
kdarapu3248f9a2019-10-03 13:54:52 +053084
Girish Gowdra9602eb42020-09-09 15:50:39 -070085 // onuGemInfo := make([]rsrcMgr.OnuGemInfo, NumPonPorts)
86 var i uint32
kdarapu3248f9a2019-10-03 13:54:52 +053087
Girish Gowdra9602eb42020-09-09 15:50:39 -070088 for i = 0; i < NumPonPorts; i++ {
89 packetInGemPort := make(map[rsrcMgr.PacketInInfoKey]uint32)
90 packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: i, OnuID: i + 1, LogicalPort: i + 1, VlanID: uint16(i), Priority: uint8(i)}] = i + 1
kdarapu3248f9a2019-10-03 13:54:52 +053091
Girish Gowdra9602eb42020-09-09 15:50:39 -070092 dh.flowMgr[i].packetInGemPort = packetInGemPort
93 tps := make(map[uint32]tp.TechProfileIf)
94 for key := range rMgr.ResourceMgrs {
95 tps[key] = mocks.MockTechProfile{TpID: key}
96 }
97 dh.flowMgr[i].techprofile = tps
98 interface2mcastQeueuMap := make(map[uint32]*QueueInfoBrief)
99 interface2mcastQeueuMap[0] = &QueueInfoBrief{
100 gemPortID: 4000,
101 servicePriority: 3,
102 }
103 dh.flowMgr[i].grpMgr.interfaceToMcastQueueMap = interface2mcastQeueuMap
kdarapu3248f9a2019-10-03 13:54:52 +0530104 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000105
Girish Gowdra9602eb42020-09-09 15:50:39 -0700106 return dh.flowMgr
kdarapu3248f9a2019-10-03 13:54:52 +0530107}
kdarapub26b4502019-10-05 03:02:33 +0530108
kdarapu3248f9a2019-10-03 13:54:52 +0530109func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530110 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
Girish Gowdra54934262019-11-13 14:19:55 +0530111 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
kdarapu3248f9a2019-10-03 13:54:52 +0530112 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
113 }
114 tprofile.UsScheduler.Direction = "UPSTREAM"
115 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
116 tprofile.UsScheduler.QSchedPolicy = "WRR"
117
118 tprofile2 := tprofile
119 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
120 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
121 tprofile2.DsScheduler.QSchedPolicy = "WRR"
122 bands := make([]*ofp.OfpMeterBandHeader, 2)
123 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
124 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
125 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
126 flowmetadata := &voltha.FlowMetadata{
127 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
128 }
kdarapu3248f9a2019-10-03 13:54:52 +0530129 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000130 name string
131 schedQueue schedQueue
132 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530133 }{
134 // TODO: Add test cases.
Girish Gowdra9602eb42020-09-09 15:50:39 -0700135 {"CreateSchedulerQueues-1", schedQueue{tp_pb.Direction_UPSTREAM, 0, 1, 1, 64, 1, tprofile, 1, flowmetadata}, false},
136 {"CreateSchedulerQueues-2", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
137 {"CreateSchedulerQueues-3", schedQueue{tp_pb.Direction_UPSTREAM, 0, 1, 1, 64, 1, tprofile, 2, flowmetadata}, true},
138 {"CreateSchedulerQueues-4", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 2, flowmetadata}, true},
139 {"CreateSchedulerQueues-5", schedQueue{tp_pb.Direction_UPSTREAM, 1, 2, 2, 64, 2, tprofile, 2, flowmetadata}, true},
140 {"CreateSchedulerQueues-6", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 2, 2, 65, 2, tprofile2, 2, flowmetadata}, true},
141 {"CreateSchedulerQueues-13", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530142 //Negative testcases
Girish Gowdra9602eb42020-09-09 15:50:39 -0700143 {"CreateSchedulerQueues-7", schedQueue{tp_pb.Direction_UPSTREAM, 0, 1, 1, 64, 1, tprofile, 1, &voltha.FlowMetadata{}}, true},
144 {"CreateSchedulerQueues-8", schedQueue{tp_pb.Direction_UPSTREAM, 0, 1, 1, 64, 1, tprofile, 0, &voltha.FlowMetadata{}}, true},
145 {"CreateSchedulerQueues-9", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 1, &voltha.FlowMetadata{}}, true},
146 {"CreateSchedulerQueues-10", schedQueue{tp_pb.Direction_UPSTREAM, 0, 1, 1, 64, 1, tprofile, 2, &voltha.FlowMetadata{}}, true},
147 {"CreateSchedulerQueues-11", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 2, &voltha.FlowMetadata{}}, true},
148 {"CreateSchedulerQueues-12", schedQueue{tp_pb.Direction_DOWNSTREAM, 0, 1, 1, 65, 1, tprofile2, 2, nil}, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530149 }
npujarec5762e2020-01-01 14:08:48 +0530150 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
151 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530152 for _, tt := range tests {
153 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700154 if err := flowMgr[tt.schedQueue.intfID].CreateSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530155 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
156 }
157 })
158 }
159}
160
161func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530162 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
Girish Gowdra54934262019-11-13 14:19:55 +0530163 ProfileType: "pt1", NumGemPorts: 1, Version: 1,
kdarapu3248f9a2019-10-03 13:54:52 +0530164 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
165 }
166 tprofile.UsScheduler.Direction = "UPSTREAM"
167 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
168 tprofile.UsScheduler.QSchedPolicy = "WRR"
169
170 tprofile2 := tprofile
171 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
172 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
173 tprofile2.DsScheduler.QSchedPolicy = "WRR"
174 //defTprofile := &tp.DefaultTechProfile{}
kdarapu3248f9a2019-10-03 13:54:52 +0530175 tests := []struct {
Gamze Abakafee36392019-10-03 11:17:24 +0000176 name string
177 schedQueue schedQueue
178 wantErr bool
kdarapu3248f9a2019-10-03 13:54:52 +0530179 }{
180 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000181 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, nil}, false},
182 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530183 // negative test cases
Gamze Abakafee36392019-10-03 11:17:24 +0000184 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
185 {"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530186 }
npujarec5762e2020-01-01 14:08:48 +0530187 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
188 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530189 for _, tt := range tests {
190 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700191 if err := flowMgr[tt.schedQueue.intfID].RemoveSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530192 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
193 }
194 })
195 }
kdarapub26b4502019-10-05 03:02:33 +0530196
kdarapu3248f9a2019-10-03 13:54:52 +0530197}
198
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700199func TestOpenOltFlowMgr_createTcontGemports(t *testing.T) {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700200 bands := make([]*ofp.OfpMeterBandHeader, 2)
201 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
202 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
203 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
204 flowmetadata := &voltha.FlowMetadata{
205 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
206 }
207 type args struct {
208 intfID uint32
209 onuID uint32
210 uniID uint32
211 uni string
212 uniPort uint32
213 TpID uint32
214 UsMeterID uint32
215 DsMeterID uint32
216 flowMetadata *voltha.FlowMetadata
217 }
218 tests := []struct {
219 name string
220 args args
221 }{
222 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 64, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
223 {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 65, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
224 }
225 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
226 defer cancel()
227 for _, tt := range tests {
228 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700229 _, _, tpInst := flowMgr[tt.args.intfID].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)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700230 switch tpInst := tpInst.(type) {
231 case *tp.TechProfile:
232 if tt.args.TpID != 64 {
233 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
234 }
235 case *tp.EponProfile:
236 if tt.args.TpID != 65 {
237 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
238 }
239 default:
240 t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
241 }
242 })
243 }
244}
245
kdarapu3248f9a2019-10-03 13:54:52 +0530246func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 ctx := context.Background()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000248 logger.Debug(ctx, "Info Warning Error: Starting RemoveFlow() test")
kdarapu3248f9a2019-10-03 13:54:52 +0530249 fa := &fu.FlowArgs{
250 MatchFields: []*ofp.OfpOxmOfbField{
251 fu.InPort(2),
252 fu.Metadata_ofp(2),
253 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
254 },
255 Actions: []*ofp.OfpAction{
256 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
257 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
258 fu.Output(1),
259 },
260 }
divyadesaid26f6b12020-03-19 06:30:28 +0000261 ofpstats, _ := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530262 ofpstats.Cookie = ofpstats.Id
kdarapub26b4502019-10-05 03:02:33 +0530263 lldpFa := &fu.FlowArgs{
264 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
265 MatchFields: []*ofp.OfpOxmOfbField{
266 fu.InPort(1),
267 fu.EthType(0x88CC),
268 fu.TunnelId(536870912),
269 },
270 Actions: []*ofp.OfpAction{
271 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
272 },
273 }
divyadesaid26f6b12020-03-19 06:30:28 +0000274 lldpofpstats, _ := fu.MkFlowStat(lldpFa)
kdarapub26b4502019-10-05 03:02:33 +0530275 //lldpofpstats.Cookie = lldpofpstats.Id
276
277 dhcpFa := &fu.FlowArgs{
278 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
279 MatchFields: []*ofp.OfpOxmOfbField{
280 fu.InPort(1),
281 fu.UdpSrc(67),
282 //fu.TunnelId(536870912),
283 fu.IpProto(17),
284 },
285 Actions: []*ofp.OfpAction{
286 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
287 },
288 }
divyadesaid26f6b12020-03-19 06:30:28 +0000289 dhcpofpstats, _ := fu.MkFlowStat(dhcpFa)
kdarapub26b4502019-10-05 03:02:33 +0530290 //dhcpofpstats.Cookie = dhcpofpstats.Id
Esin Karamanccb714b2019-11-29 15:02:06 +0000291
292 //multicast flow
293 multicastFa := &fu.FlowArgs{
294 MatchFields: []*ofp.OfpOxmOfbField{
Girish Gowdra0aca4982021-01-04 12:44:27 -0800295 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +0000296 fu.VlanVid(660), //vlan
297 fu.Metadata_ofp(uint64(66)), //inner vlan
298 fu.EthType(0x800), //ipv4
299 fu.Ipv4Dst(3809869825), //227.22.0.1
300 },
301 Actions: []*ofp.OfpAction{
302 fu.Group(1),
303 },
304 }
divyadesaid26f6b12020-03-19 06:30:28 +0000305 multicastOfpStats, _ := fu.MkFlowStat(multicastFa)
Esin Karamanccb714b2019-11-29 15:02:06 +0000306 multicastOfpStats.Id = 1
307
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300308 pppoedFa := &fu.FlowArgs{
309 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
310 MatchFields: []*ofp.OfpOxmOfbField{
311 fu.InPort(1),
312 fu.EthType(0x8863),
313 fu.TunnelId(536870912),
314 },
315 Actions: []*ofp.OfpAction{
316 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
317 },
318 }
319 pppoedOfpStats, _ := fu.MkFlowStat(pppoedFa)
320
kdarapu3248f9a2019-10-03 13:54:52 +0530321 type args struct {
322 flow *ofp.OfpFlowStats
323 }
324 tests := []struct {
325 name string
326 args args
327 }{
328 // TODO: Add test cases.
329 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530330 {"RemoveFlow", args{flow: lldpofpstats}},
331 {"RemoveFlow", args{flow: dhcpofpstats}},
Esin Karamanccb714b2019-11-29 15:02:06 +0000332 {"RemoveFlow", args{flow: multicastOfpStats}},
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300333 {"RemoveFlow", args{flow: pppoedOfpStats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530334 }
npujarec5762e2020-01-01 14:08:48 +0530335 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
336 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530337 for _, tt := range tests {
338 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700339 if err := flowMgr[0].RemoveFlow(ctx, tt.args.flow); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400340 logger.Warn(ctx, err)
341 }
kdarapu3248f9a2019-10-03 13:54:52 +0530342 })
343 }
kdarapub26b4502019-10-05 03:02:33 +0530344 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530345}
346
347func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530348 kw := make(map[string]uint64)
349 kw["table_id"] = 1
350 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530351 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
352
353 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530354 fa := &fu.FlowArgs{
355 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530356 fu.InPort(536870912),
357 fu.Metadata_ofp(1),
358 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
359 },
360 Actions: []*ofp.OfpAction{
361 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
362 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
Girish Gowdra0aca4982021-01-04 12:44:27 -0800363 fu.Output(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530364 fu.PushVlan(0x8100),
365 },
366 KV: kw,
367 }
368
369 // Downstream flow
370 fa3 := &fu.FlowArgs{
371 MatchFields: []*ofp.OfpOxmOfbField{
Girish Gowdra0aca4982021-01-04 12:44:27 -0800372 fu.InPort(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530373 fu.Metadata_ofp(1),
374 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
375 },
376 Actions: []*ofp.OfpAction{
377 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
378 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
379 fu.PopVlan(),
380 fu.Output(536870912),
381 },
382 KV: kw,
383 }
384
385 fa2 := &fu.FlowArgs{
386 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530387 fu.InPort(1000),
388 fu.Metadata_ofp(1),
389 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
390 },
391 Actions: []*ofp.OfpAction{
392 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
393 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
394 fu.Output(65533),
395 },
396 KV: kw,
397 }
398
kdarapub26b4502019-10-05 03:02:33 +0530399 // TODO Add LLDP flow
400 // TODO Add DHCP flow
401
402 // Flows for negative scenarios
403 // Failure in formulateActionInfoFromFlow()
404 fa4 := &fu.FlowArgs{
405 MatchFields: []*ofp.OfpOxmOfbField{
406 fu.InPort(1000),
407 fu.Metadata_ofp(1),
408 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
409 },
410 Actions: []*ofp.OfpAction{
411 fu.Experimenter(257, []byte{1, 2, 3, 4}),
412 },
413 KV: kw,
414 }
415
416 // Invalid Output
417 fa5 := &fu.FlowArgs{
418 MatchFields: []*ofp.OfpOxmOfbField{
419 fu.InPort(1000),
420 fu.Metadata_ofp(1),
421 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
422 },
423 Actions: []*ofp.OfpAction{
424 fu.Output(0),
425 },
426 KV: kw,
427 }
428
429 // Tech-Profile-ID update (not supported)
430 kw6 := make(map[string]uint64)
431 kw6["table_id"] = 1
432 kw6["meter_id"] = 1
433 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
434 fa6 := &fu.FlowArgs{
435 MatchFields: []*ofp.OfpOxmOfbField{
436 fu.InPort(536870912),
437 fu.TunnelId(16),
438 fu.Metadata_ofp(1),
439 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
440 },
441 Actions: []*ofp.OfpAction{
442 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
443 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
444 fu.Output(65535),
445 },
446 KV: kw6,
447 }
448
449 lldpFa := &fu.FlowArgs{
450 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
451 MatchFields: []*ofp.OfpOxmOfbField{
452 fu.InPort(1),
453 fu.EthType(0x88CC),
454 fu.TunnelId(536870912),
455 },
456 Actions: []*ofp.OfpAction{
457 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
458 },
459 }
460
461 dhcpFa := &fu.FlowArgs{
462 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
463 MatchFields: []*ofp.OfpOxmOfbField{
464 fu.InPort(1),
465 fu.UdpSrc(67),
466 //fu.TunnelId(536870912),
467 fu.IpProto(17),
468 },
469 Actions: []*ofp.OfpAction{
470 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
471 },
472 }
473 igmpFa := &fu.FlowArgs{
474 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
475 MatchFields: []*ofp.OfpOxmOfbField{
476 fu.InPort(1),
477 fu.UdpSrc(67),
478 //fu.TunnelId(536870912),
479 fu.IpProto(2),
480 },
481 Actions: []*ofp.OfpAction{
482 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
483 },
484 }
485
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300486 pppoedFa := &fu.FlowArgs{
487 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
488 MatchFields: []*ofp.OfpOxmOfbField{
489 fu.InPort(1),
490 fu.EthType(0x8863),
491 fu.TunnelId(536870912),
492 },
493 Actions: []*ofp.OfpAction{
494 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
495 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
496 },
497 }
498
kdarapub26b4502019-10-05 03:02:33 +0530499 fa9 := &fu.FlowArgs{
500 MatchFields: []*ofp.OfpOxmOfbField{
501 fu.InPort(536870912),
502 fu.TunnelId(16),
503 fu.Metadata_ofp(1),
504 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
505 fu.VlanPcp(1000),
Girish Gowdra0aca4982021-01-04 12:44:27 -0800506 fu.UdpDst(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530507 fu.UdpSrc(536870912),
508 fu.Ipv4Dst(65535),
509 fu.Ipv4Src(536870912),
510 },
511 Actions: []*ofp.OfpAction{
512 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
513 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
514 fu.Output(65535),
515 },
516 KV: kw6,
517 }
518
519 fa10 := &fu.FlowArgs{
520 MatchFields: []*ofp.OfpOxmOfbField{
521 fu.InPort(65533),
522 // fu.TunnelId(16),
523 fu.Metadata_ofp(1),
524 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
525 fu.VlanPcp(1000),
526 fu.UdpDst(65535),
527 fu.UdpSrc(536870912),
528 fu.Ipv4Dst(65535),
529 fu.Ipv4Src(536870912),
530 },
531 Actions: []*ofp.OfpAction{
532 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
533 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
534 fu.Output(65535),
535 },
536 KV: kw6,
537 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000538 //multicast flow
539 fa11 := &fu.FlowArgs{
540 MatchFields: []*ofp.OfpOxmOfbField{
Girish Gowdra0aca4982021-01-04 12:44:27 -0800541 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +0000542 fu.VlanVid(660), //vlan
543 fu.Metadata_ofp(uint64(66)), //inner vlan
544 fu.EthType(0x800), //ipv4
545 fu.Ipv4Dst(3809869825), //227.22.0.1
546 },
547 Actions: []*ofp.OfpAction{
548 fu.Group(1),
549 },
550 KV: kw6,
551 }
divyadesaid26f6b12020-03-19 06:30:28 +0000552 ofpstats, _ := fu.MkFlowStat(fa)
553 ofpstats2, _ := fu.MkFlowStat(fa2)
554 ofpstats3, _ := fu.MkFlowStat(fa3)
555 ofpstats4, _ := fu.MkFlowStat(fa4)
556 ofpstats5, _ := fu.MkFlowStat(fa5)
557 ofpstats6, _ := fu.MkFlowStat(fa6)
558 ofpstats7, _ := fu.MkFlowStat(lldpFa)
559 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
560 ofpstats9, _ := fu.MkFlowStat(fa9)
561 ofpstats10, _ := fu.MkFlowStat(fa10)
562 igmpstats, _ := fu.MkFlowStat(igmpFa)
563 ofpstats11, _ := fu.MkFlowStat(fa11)
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300564 pppoedstats, _ := fu.MkFlowStat(pppoedFa)
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}},
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300594 {"AddFlow", args{flow: pppoedstats, flowMetadata: flowMetadata}},
kdarapu3248f9a2019-10-03 13:54:52 +0530595 }
npujarec5762e2020-01-01 14:08:48 +0530596 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
597 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530598 for _, tt := range tests {
599 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700600 _ = flowMgr[0].AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
Kent Hagermane6ff1012020-07-14 15:07:53 -0400601 // TODO: actually verify test cases
kdarapu3248f9a2019-10-03 13:54:52 +0530602 })
603 }
604}
605
606func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
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 Scandoloabf9c512020-06-23 19:31:14 -0700610 wg := sync.WaitGroup{}
611
Girish Gowdra9602eb42020-09-09 15:50:39 -0700612 intfCount := NumPonPorts
613 onuCount := OnuIDEnd - OnuIDStart + 1
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700614
615 for i := 0; i < intfCount; i++ {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700616 for j := 1; j <= onuCount; j++ {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700617 wg.Add(1)
618 go func(i uint32, j uint32) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400619 // TODO: actually verify success
Girish Gowdra9602eb42020-09-09 15:50:39 -0700620 _ = flowMgr[i].UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700621 wg.Done()
622 }(uint32(i), uint32(j))
623 }
624
625 }
626
627 wg.Wait()
628}
629
630func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700631 intfNum := NumPonPorts
632 onuNum := OnuIDEnd - OnuIDStart + 1
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700633
634 // clean the flowMgr
Girish Gowdra9602eb42020-09-09 15:50:39 -0700635 for i := 0; i < intfNum; i++ {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700636 flowMgr[i].onuGemInfo = make([]rsrcMgr.OnuGemInfo, 0)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700637 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700638
639 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
640 defer cancel()
641
642 // Create OnuInfo
643 for i := 0; i < intfNum; i++ {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700644 for o := 1; o <= onuNum; o++ {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400645 // TODO: actually verify success
Girish Gowdra9602eb42020-09-09 15:50:39 -0700646 _ = flowMgr[i].UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o-1))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700647 }
648 }
649
650 // Add gemPorts to OnuInfo in parallel threads
651 wg := sync.WaitGroup{}
652
Girish Gowdra9602eb42020-09-09 15:50:39 -0700653 for o := 1; o <= onuNum; o++ {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700654 for i := 0; i < intfNum; i++ {
655 wg.Add(1)
656 go func(intfId uint32, onuId uint32) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700657 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId-1))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700658
Girish Gowdra9602eb42020-09-09 15:50:39 -0700659 flowMgr[intfId].addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700660 wg.Done()
661 }(uint32(i), uint32(o))
662 }
663 }
664
665 wg.Wait()
666
667 // check that each entry of onuGemInfo has the correct number of ONUs
668 for i := 0; i < intfNum; i++ {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700669 lenofOnu := len(flowMgr[i].onuGemInfo)
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700670 if onuNum != lenofOnu {
671 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
672 }
673
Girish Gowdra9602eb42020-09-09 15:50:39 -0700674 for o := 1; o <= onuNum; o++ {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700675 lenOfGemPorts := len(flowMgr[i].onuGemInfo[o-1].GemPorts)
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700676 // check that each onuEntry has 1 gemPort
677 if lenOfGemPorts != 1 {
678 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
679 }
680
681 // check that the value of the gemport is correct
Girish Gowdra9602eb42020-09-09 15:50:39 -0700682 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o-1))
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700683 currentValue := flowMgr[i].onuGemInfo[o-1].GemPorts[0]
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700684 if uint32(gemID) != currentValue {
685 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
686 }
687 }
kdarapu3248f9a2019-10-03 13:54:52 +0530688 }
689}
690
serkant.uluderya96af4932020-02-20 16:58:48 -0800691func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700692 // Create fresh flowMgr instance
693 flowMgr = newMockFlowmgr()
serkant.uluderya96af4932020-02-20 16:58:48 -0800694 type args struct {
695 intfID uint32
696 onuID uint32
697 gemPortIDs []uint32
698 gemPortIDsToBeDeleted []uint32
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700699 gemPortIDsRemaining []uint32
serkant.uluderya96af4932020-02-20 16:58:48 -0800700 serialNum string
701 finalLength int
702 }
703 tests := []struct {
704 name string
705 args args
706 }{
707 // Add/Delete single gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700708 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800709 // Delete all gemports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700710 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800711 // Try to delete when there is no gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700712 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800713 // Try to delete non-existent gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700714 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800715 // Try to delete two of the gem ports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700716 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800717 }
718 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
719 defer cancel()
720 for _, tt := range tests {
721 t.Run(tt.name, func(t *testing.T) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400722 // TODO: should check returned errors are as expected?
Girish Gowdra9602eb42020-09-09 15:50:39 -0700723 _ = flowMgr[tt.args.intfID].UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
serkant.uluderya96af4932020-02-20 16:58:48 -0800724 for _, gemPort := range tt.args.gemPortIDs {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700725 flowMgr[tt.args.intfID].addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
serkant.uluderya96af4932020-02-20 16:58:48 -0800726 }
727 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700728 flowMgr[tt.args.intfID].deleteGemPortFromLocalCache(ctx, tt.args.intfID, tt.args.onuID, gemPortDeleted)
serkant.uluderya96af4932020-02-20 16:58:48 -0800729 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700730 lenofGemPorts := len(flowMgr[tt.args.intfID].onuGemInfo[0].GemPorts)
serkant.uluderya96af4932020-02-20 16:58:48 -0800731 if lenofGemPorts != tt.args.finalLength {
732 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
733 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700734 gemPorts := flowMgr[tt.args.intfID].onuGemInfo[0].GemPorts
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700735 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
736 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
737 }
serkant.uluderya96af4932020-02-20 16:58:48 -0800738
739 })
740 }
741}
742
kdarapu3248f9a2019-10-03 13:54:52 +0530743func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530744 type args struct {
745 packetIn *openoltpb2.PacketIndication
746 }
747 tests := []struct {
748 name string
749 args args
750 want uint32
751 wantErr bool
752 }{
753 // TODO: Add test cases.
Esin Karamandf392e12020-12-16 13:33:09 +0000754 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 0, GemportId: 255, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
Girish Gowdra9602eb42020-09-09 15:50:39 -0700755 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 0, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1048576, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530756 // Negative Test cases.
Girish Gowdra9602eb42020-09-09 15:50:39 -0700757 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
Esin Karamandf392e12020-12-16 13:33:09 +0000758 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 0, GemportId: 257, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 16, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530759 }
npujarec5762e2020-01-01 14:08:48 +0530760 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
761 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530762 for _, tt := range tests {
763 t.Run(tt.name, func(t *testing.T) {
764
Girish Gowdra9602eb42020-09-09 15:50:39 -0700765 got, err := flowMgr[tt.args.packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
kdarapu3248f9a2019-10-03 13:54:52 +0530766 if (err != nil) != tt.wantErr {
767 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
768 return
769 }
770 if got != tt.want {
771 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
772 }
773 })
774 }
775}
776
777func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700778 // Create fresh flowMgr instance
779 flowMgr = newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530780
Esin Karaman7fb80c22020-07-16 14:23:33 +0000781 //untagged packet in hex string
782 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
783 untagged, err := hex.DecodeString(untaggedStr)
784 if err != nil {
785 t.Error("Unable to parse hex string", err)
786 panic(err)
787 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700788 //single-tagged packet in hex string. vlanID.pbit: 1.1
789 singleTaggedStr := "01005e0000010025ba48172481002001080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
Esin Karaman7fb80c22020-07-16 14:23:33 +0000790 singleTagged, err := hex.DecodeString(singleTaggedStr)
791 if err != nil {
792 t.Error("Unable to parse hex string", err)
793 panic(err)
794 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700795 //double-tagged packet in hex string. vlanID.pbit: 210.0-0.0
796 doubleTaggedStr := "01005e000016deadbeefba118100021081000000080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
Esin Karaman7fb80c22020-07-16 14:23:33 +0000797 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
798 if err != nil {
799 t.Error("Unable to parse hex string", err)
800 panic(err)
801 }
802
kdarapu3248f9a2019-10-03 13:54:52 +0530803 type args struct {
804 intfID uint32
805 onuID uint32
806 portNum uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000807 packet []byte
kdarapu3248f9a2019-10-03 13:54:52 +0530808 }
809 tests := []struct {
810 name string
811 args args
812 want uint32
813 wantErr bool
814 }{
815 // TODO: Add test cases.
Girish Gowdra9602eb42020-09-09 15:50:39 -0700816 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 1, packet: untagged}, 1, false},
817 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: singleTagged}, 2, false},
818 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 1, packet: doubleTagged}, 1, false},
819 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 10, portNum: 10, packet: untagged}, 2, true},
820 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530821 }
Esin Karaman7fb80c22020-07-16 14:23:33 +0000822
npujarec5762e2020-01-01 14:08:48 +0530823 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
824 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530825 for _, tt := range tests {
826 t.Run(tt.name, func(t *testing.T) {
827
Girish Gowdra9602eb42020-09-09 15:50:39 -0700828 got, err := flowMgr[tt.args.intfID].GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum, tt.args.packet)
Esin Karaman7fb80c22020-07-16 14:23:33 +0000829 if tt.wantErr {
830 if err == nil {
831 //error expected but got value
832 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
833 }
834 } else {
835 if err != nil {
836 //error is not expected but got error
837 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
838 return
839 }
840 if got != tt.want {
841 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
842 }
kdarapu3248f9a2019-10-03 13:54:52 +0530843 }
kdarapu3248f9a2019-10-03 13:54:52 +0530844 })
845 }
846}
847
848func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530849 type args struct {
850 intfID uint32
851 onuID uint32
852 uniID uint32
853 sn string
Gamze Abakafee36392019-10-03 11:17:24 +0000854 tpID uint32
kdarapu3248f9a2019-10-03 13:54:52 +0530855 }
856 tests := []struct {
857 name string
858 args args
859 wantErr bool
860 }{
861 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000862 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530863 }
npujarec5762e2020-01-01 14:08:48 +0530864 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
865 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530866 for _, tt := range tests {
867 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700868 if err := flowMgr[tt.args.intfID].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 +0530869 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
870 }
871 })
872 }
873}
kdarapub26b4502019-10-05 03:02:33 +0530874
875func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000876 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530877 kw := make(map[string]uint64)
878 kw["table_id"] = 1
879 kw["meter_id"] = 1
880 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
881
882 // Upstream flow
883 fa := &fu.FlowArgs{
884 MatchFields: []*ofp.OfpOxmOfbField{
885 fu.InPort(536870912),
886 fu.Metadata_ofp(1),
887 fu.IpProto(17), // dhcp
Gamze Abakafee36392019-10-03 11:17:24 +0000888 fu.VlanPcp(0),
kdarapub26b4502019-10-05 03:02:33 +0530889 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
890 },
891 Actions: []*ofp.OfpAction{
892 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
893 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
Girish Gowdra0aca4982021-01-04 12:44:27 -0800894 fu.Output(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530895 fu.PushVlan(0x8100),
896 },
897 KV: kw,
898 }
899
900 // EAPOL
901 fa2 := &fu.FlowArgs{
902 MatchFields: []*ofp.OfpOxmOfbField{
903 fu.InPort(536870912),
904 fu.Metadata_ofp(1),
905 fu.EthType(0x888E),
906 fu.VlanPcp(1),
907 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
908 },
909 Actions: []*ofp.OfpAction{
910 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
911 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
Girish Gowdra0aca4982021-01-04 12:44:27 -0800912 fu.Output(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530913 fu.PushVlan(0x8100),
914 },
915 KV: kw,
916 }
917
918 // HSIA
919 fa3 := &fu.FlowArgs{
920 MatchFields: []*ofp.OfpOxmOfbField{
921 fu.InPort(536870912),
922 fu.Metadata_ofp(1),
923 //fu.EthType(0x8100),
924 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
925 },
926 Actions: []*ofp.OfpAction{
927 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
928 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
Girish Gowdra0aca4982021-01-04 12:44:27 -0800929 fu.Output(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530930 fu.PushVlan(0x8100),
931 },
932 KV: kw,
933 }
934
935 fa4 := &fu.FlowArgs{
936 MatchFields: []*ofp.OfpOxmOfbField{
Girish Gowdra0aca4982021-01-04 12:44:27 -0800937 fu.InPort(1048576),
kdarapub26b4502019-10-05 03:02:33 +0530938 fu.Metadata_ofp(1),
939 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
940 fu.VlanPcp(1),
941 },
942 Actions: []*ofp.OfpAction{
943 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
944 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
945 fu.Output(536870912),
946 fu.PopVlan(),
947 },
948 KV: kw,
949 }
950
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300951 // PPPOED
952 pppoedFA := &fu.FlowArgs{
953 MatchFields: []*ofp.OfpOxmOfbField{
954 fu.InPort(536870912),
955 fu.Metadata_ofp(1),
956 fu.EthType(0x8863),
957 fu.VlanPcp(1),
958 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
959 },
960 Actions: []*ofp.OfpAction{
961 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
962 fu.Output(1048576),
963 fu.PushVlan(0x8100),
964 },
965 KV: kw,
966 }
967
kdarapub26b4502019-10-05 03:02:33 +0530968 classifierInfo := make(map[string]interface{})
969 actionInfo := make(map[string]interface{})
970 classifierInfo2 := make(map[string]interface{})
971 actionInfo2 := make(map[string]interface{})
972 classifierInfo3 := make(map[string]interface{})
973 actionInfo3 := make(map[string]interface{})
974 classifierInfo4 := make(map[string]interface{})
975 actionInfo4 := make(map[string]interface{})
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300976 classifierInfo5 := make(map[string]interface{})
977 actionInfo5 := make(map[string]interface{})
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700978 flow, _ := fu.MkFlowStat(fa)
979 flow2, _ := fu.MkFlowStat(fa2)
980 flow3, _ := fu.MkFlowStat(fa3)
981 flow4, _ := fu.MkFlowStat(fa4)
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300982 flow5, _ := fu.MkFlowStat(pppoedFA)
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700983 formulateClassifierInfoFromFlow(ctx, classifierInfo, flow)
984 formulateClassifierInfoFromFlow(ctx, classifierInfo2, flow2)
985 formulateClassifierInfoFromFlow(ctx, classifierInfo3, flow3)
986 formulateClassifierInfoFromFlow(ctx, classifierInfo4, flow4)
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -0300987 formulateClassifierInfoFromFlow(ctx, classifierInfo5, flow5)
kdarapub26b4502019-10-05 03:02:33 +0530988
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700989 err := formulateActionInfoFromFlow(ctx, actionInfo, classifierInfo, flow)
kdarapub26b4502019-10-05 03:02:33 +0530990 if err != nil {
991 // Error logging is already done in the called function
992 // So just return in case of error
993 return
994 }
995
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700996 err = formulateActionInfoFromFlow(ctx, actionInfo2, classifierInfo2, flow2)
kdarapub26b4502019-10-05 03:02:33 +0530997 if err != nil {
998 // Error logging is already done in the called function
999 // So just return in case of error
1000 return
1001 }
1002
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001003 err = formulateActionInfoFromFlow(ctx, actionInfo3, classifierInfo3, flow3)
kdarapub26b4502019-10-05 03:02:33 +05301004 if err != nil {
1005 // Error logging is already done in the called function
1006 // So just return in case of error
1007 return
1008 }
1009
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001010 err = formulateActionInfoFromFlow(ctx, actionInfo4, classifierInfo4, flow4)
kdarapub26b4502019-10-05 03:02:33 +05301011 if err != nil {
1012 // Error logging is already done in the called function
1013 // So just return in case of error
1014 return
1015 }
1016
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001017 err = formulateActionInfoFromFlow(ctx, actionInfo5, classifierInfo5, flow5)
1018 if err != nil {
1019 // Error logging is already done in the called function
1020 // So just return in case of error
1021 return
1022 }
1023
kdarapub26b4502019-10-05 03:02:33 +05301024 TpInst := &tp.TechProfile{
1025 Name: "Test-Tech-Profile",
1026 SubscriberIdentifier: "257",
1027 ProfileType: "Mock",
1028 Version: 1,
1029 NumGemPorts: 4,
kdarapub26b4502019-10-05 03:02:33 +05301030 InstanceCtrl: tp.InstanceControl{
1031 Onu: "1",
1032 Uni: "16",
1033 },
1034 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001035 TpInst.UsScheduler.Priority = 1
1036 TpInst.UsScheduler.Direction = "upstream"
1037 TpInst.UsScheduler.AllocID = 1
1038 TpInst.UsScheduler.AdditionalBw = "None"
1039 TpInst.UsScheduler.QSchedPolicy = "PQ"
1040 TpInst.UsScheduler.Weight = 4
1041
1042 TpInst.DsScheduler.Priority = 1
1043 TpInst.DsScheduler.Direction = "upstream"
1044 TpInst.DsScheduler.AllocID = 1
1045 TpInst.DsScheduler.AdditionalBw = "None"
1046 TpInst.DsScheduler.QSchedPolicy = "PQ"
1047 TpInst.DsScheduler.Weight = 4
1048
1049 TpInst.UpstreamGemPortAttributeList = make([]tp.IGemPortAttribute, 4)
1050 TpInst.UpstreamGemPortAttributeList[0].GemportID = 1
1051 TpInst.UpstreamGemPortAttributeList[0].PbitMap = "0b00000011"
1052 TpInst.UpstreamGemPortAttributeList[0].GemportID = 2
1053 TpInst.UpstreamGemPortAttributeList[0].PbitMap = "0b00001100"
1054 TpInst.UpstreamGemPortAttributeList[0].GemportID = 3
1055 TpInst.UpstreamGemPortAttributeList[0].PbitMap = "0b00110000"
1056 TpInst.UpstreamGemPortAttributeList[0].GemportID = 4
1057 TpInst.UpstreamGemPortAttributeList[0].PbitMap = "0b11000000"
1058
1059 TpInst.DownstreamGemPortAttributeList = make([]tp.IGemPortAttribute, 4)
1060 TpInst.DownstreamGemPortAttributeList[0].GemportID = 1
1061 TpInst.DownstreamGemPortAttributeList[0].PbitMap = "0b00000011"
1062 TpInst.DownstreamGemPortAttributeList[0].GemportID = 2
1063 TpInst.DownstreamGemPortAttributeList[0].PbitMap = "0b00001100"
1064 TpInst.DownstreamGemPortAttributeList[0].GemportID = 3
1065 TpInst.DownstreamGemPortAttributeList[0].PbitMap = "0b00110000"
1066 TpInst.DownstreamGemPortAttributeList[0].GemportID = 4
1067 TpInst.DownstreamGemPortAttributeList[0].PbitMap = "0b11000000"
kdarapub26b4502019-10-05 03:02:33 +05301068
kdarapub26b4502019-10-05 03:02:33 +05301069 type args struct {
1070 args map[string]uint32
1071 classifierInfo map[string]interface{}
1072 actionInfo map[string]interface{}
1073 flow *ofp.OfpFlowStats
1074 gemPort uint32
1075 intfID uint32
1076 onuID uint32
1077 uniID uint32
1078 portNo uint32
1079 TpInst *tp.TechProfile
1080 allocID []uint32
1081 gemPorts []uint32
1082 TpID uint32
1083 uni string
1084 }
1085 tests := []struct {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001086 name string
1087 args args
kdarapub26b4502019-10-05 03:02:33 +05301088 }{
1089 {
1090 name: "checkAndAddFlow-1",
1091 args: args{
1092 args: nil,
1093 classifierInfo: classifierInfo,
1094 actionInfo: actionInfo,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001095 flow: flow,
kdarapub26b4502019-10-05 03:02:33 +05301096 gemPort: 1,
1097 intfID: 1,
1098 onuID: 1,
1099 uniID: 16,
1100 portNo: 1,
1101 TpInst: TpInst,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001102 allocID: []uint32{0x8001},
kdarapub26b4502019-10-05 03:02:33 +05301103 gemPorts: []uint32{1, 2, 3, 4},
1104 TpID: 64,
1105 uni: "16",
1106 },
1107 },
1108 {
1109 name: "checkAndAddFlow-2",
1110 args: args{
1111 args: nil,
1112 classifierInfo: classifierInfo2,
1113 actionInfo: actionInfo2,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001114 flow: flow2,
kdarapub26b4502019-10-05 03:02:33 +05301115 gemPort: 1,
1116 intfID: 1,
1117 onuID: 1,
1118 uniID: 16,
1119 portNo: 1,
1120 TpInst: TpInst,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001121 allocID: []uint32{0x8001},
kdarapub26b4502019-10-05 03:02:33 +05301122 gemPorts: []uint32{1, 2, 3, 4},
1123 TpID: 64,
1124 uni: "16",
1125 },
1126 },
1127 {
1128 name: "checkAndAddFlow-3",
1129 args: args{
1130 args: nil,
1131 classifierInfo: classifierInfo3,
1132 actionInfo: actionInfo3,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001133 flow: flow3,
kdarapub26b4502019-10-05 03:02:33 +05301134 gemPort: 1,
1135 intfID: 1,
1136 onuID: 1,
1137 uniID: 16,
1138 portNo: 1,
1139 TpInst: TpInst,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001140 allocID: []uint32{0x8001},
kdarapub26b4502019-10-05 03:02:33 +05301141 gemPorts: []uint32{1, 2, 3, 4},
1142 TpID: 64,
1143 uni: "16",
1144 },
1145 },
1146 {
1147 name: "checkAndAddFlow-4",
1148 args: args{
1149 args: nil,
1150 classifierInfo: classifierInfo4,
1151 actionInfo: actionInfo4,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001152 flow: flow4,
kdarapub26b4502019-10-05 03:02:33 +05301153 gemPort: 1,
1154 intfID: 1,
1155 onuID: 1,
1156 uniID: 16,
1157 portNo: 1,
1158 TpInst: TpInst,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001159 allocID: []uint32{0x8001},
kdarapub26b4502019-10-05 03:02:33 +05301160 gemPorts: []uint32{1, 2, 3, 4},
1161 TpID: 64,
1162 uni: "16",
1163 },
1164 },
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001165 {
1166 name: "checkAndAddFlow-5",
1167 args: args{
1168 args: nil,
1169 classifierInfo: classifierInfo5,
1170 actionInfo: actionInfo5,
1171 flow: flow5,
1172 gemPort: 1,
1173 intfID: 1,
1174 onuID: 1,
1175 uniID: 16,
1176 portNo: 1,
1177 TpInst: TpInst,
1178 allocID: []uint32{0x8001},
1179 gemPorts: []uint32{1, 2, 3, 4},
1180 TpID: 64,
1181 uni: "16",
1182 },
1183 },
kdarapub26b4502019-10-05 03:02:33 +05301184 }
npujarec5762e2020-01-01 14:08:48 +05301185 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1186 defer cancel()
kdarapub26b4502019-10-05 03:02:33 +05301187 for _, tt := range tests {
1188 t.Run(tt.name, func(t *testing.T) {
Girish Gowdra9602eb42020-09-09 15:50:39 -07001189 flowMgr[tt.args.intfID].checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
Gamze Abakafee36392019-10-03 11:17:24 +00001190 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
kdarapub26b4502019-10-05 03:02:33 +05301191 })
1192 }
1193}
Esin Karamanccb714b2019-11-29 15:02:06 +00001194
Esin Karamand519bbf2020-07-01 11:16:03 +00001195func TestOpenOltFlowMgr_TestMulticastFlowAndGroup(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301196 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1197 defer cancel()
Esin Karamanccb714b2019-11-29 15:02:06 +00001198 //create group
1199 group := newGroup(2, []uint32{1})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001200 err := flowMgr[0].grpMgr.AddGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001201 if err != nil {
1202 t.Error("group-add failed", err)
1203 return
1204 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001205 //create multicast flow
1206 multicastFlowArgs := &fu.FlowArgs{
1207 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karamand519bbf2020-07-01 11:16:03 +00001208 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +00001209 fu.VlanVid(660), //vlan
1210 fu.Metadata_ofp(uint64(66)), //inner vlan
1211 fu.EthType(0x800), //ipv4
1212 fu.Ipv4Dst(3809869825), //227.22.0.1
1213 },
1214 Actions: []*ofp.OfpAction{
1215 fu.Group(1),
1216 },
1217 }
divyadesaid26f6b12020-03-19 06:30:28 +00001218 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
Esin Karamand519bbf2020-07-01 11:16:03 +00001219 fmt.Println(ofpStats.Id)
Girish Gowdra9602eb42020-09-09 15:50:39 -07001220 err = flowMgr[0].AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
Esin Karamand519bbf2020-07-01 11:16:03 +00001221 if err != nil {
1222 t.Error("Multicast flow-add failed", err)
1223 return
1224 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001225
1226 //add bucket to the group
1227 group = newGroup(2, []uint32{1, 2})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001228 err = flowMgr[0].grpMgr.ModifyGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001229 if err != nil {
1230 t.Error("modify-group failed", err)
1231 return
1232 }
1233 //remove the multicast flow
Girish Gowdra9602eb42020-09-09 15:50:39 -07001234 err = flowMgr[0].RemoveFlow(ctx, ofpStats)
Esin Karamand519bbf2020-07-01 11:16:03 +00001235 if err != nil {
1236 t.Error("Multicast flow-remove failed", err)
1237 return
1238 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001239
Esin Karamand519bbf2020-07-01 11:16:03 +00001240 //remove the group
Girish Gowdra9602eb42020-09-09 15:50:39 -07001241 err = flowMgr[0].grpMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001242 if err != nil {
1243 t.Error("delete-group failed", err)
1244 return
1245 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001246}
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001247
1248func TestOpenOltFlowMgr_TestRouteFlowToOnuChannel(t *testing.T) {
1249 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1250 defer cancel()
1251 log.SetPackageLogLevel("github.com/opencord/voltha-openolt-adapter/internal/pkg/core", log.DebugLevel)
1252 log.SetPackageLogLevel("github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager", log.DebugLevel)
1253 log.SetPackageLogLevel("github.com/opencord/voltha-openolt-adapter/pkg/mocks", log.DebugLevel)
Girish Gowdra0aca4982021-01-04 12:44:27 -08001254 kwTable1Meter1 := make(map[string]uint64)
1255 kwTable1Meter1["table_id"] = 1
1256 kwTable1Meter1["meter_id"] = 1
1257 kwTable1Meter1["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
1258
1259 kwTable0Meter1 := make(map[string]uint64)
1260 kwTable0Meter1["table_id"] = 0
1261 kwTable0Meter1["meter_id"] = 1
1262 kwTable0Meter1["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001263
1264 flowMetadata1 := voltha.FlowMetadata{Meters: []*voltha.OfpMeterConfig{
1265 {
1266 Flags: 5,
1267 MeterId: 1,
1268 Bands: []*voltha.OfpMeterBandHeader{
1269 {
1270 Type: voltha.OfpMeterBandType_OFPMBT_DROP,
1271 Rate: 16000,
1272 BurstSize: 30,
1273 },
1274 {
1275 Type: voltha.OfpMeterBandType_OFPMBT_DROP,
1276 Rate: 32000,
1277 BurstSize: 30,
1278 },
1279 {
1280 Type: voltha.OfpMeterBandType_OFPMBT_DROP,
1281 Rate: 64000,
1282 BurstSize: 30,
1283 },
1284 },
1285 },
1286 }}
1287
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001288 // Downstream LLDP Trap from NNI0 flow
1289 fa0 := &fu.FlowArgs{
1290 MatchFields: []*ofp.OfpOxmOfbField{
1291 fu.InPort(1048576),
1292 fu.EthType(35020),
1293 },
1294 Actions: []*ofp.OfpAction{
1295 fu.Output(4294967293),
1296 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001297 KV: make(map[string]uint64),
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001298 }
1299
1300 // Upstream flow DHCP flow - ONU1 UNI0 PON0
1301 fa1 := &fu.FlowArgs{
1302 MatchFields: []*ofp.OfpOxmOfbField{
1303 fu.InPort(536870912),
1304 fu.Metadata_ofp(1),
1305 fu.IpProto(17), // dhcp
1306 fu.VlanPcp(0),
1307 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
1308 fu.TunnelId(16),
1309 },
1310 Actions: []*ofp.OfpAction{
1311 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1312 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
1313 fu.Output(2147483645),
1314 fu.PushVlan(0x8100),
1315 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001316 KV: kwTable1Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001317 }
1318
1319 // Upstream EAPOL - ONU1 UNI0 PON0
1320 fa2 := &fu.FlowArgs{
1321 MatchFields: []*ofp.OfpOxmOfbField{
1322 fu.InPort(536870912),
1323 fu.Metadata_ofp(1),
1324 fu.EthType(0x888E),
1325 fu.VlanPcp(1),
1326 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
1327 fu.TunnelId(16),
1328 },
1329 Actions: []*ofp.OfpAction{
1330 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1331 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
1332 fu.Output(2147483645),
1333 fu.PushVlan(0x8100),
1334 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001335 KV: kwTable1Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001336 }
1337
1338 // Upstream HSIA - ONU1 UNI0 PON0
1339 fa3 := &fu.FlowArgs{
1340 MatchFields: []*ofp.OfpOxmOfbField{
1341 fu.InPort(536870912),
1342 fu.Metadata_ofp(1),
1343 //fu.EthType(0x8100),
1344 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
Girish Gowdra0aca4982021-01-04 12:44:27 -08001345 fu.TunnelId(16),
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001346 },
1347 Actions: []*ofp.OfpAction{
1348 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1349 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
1350 fu.Output(1048576),
1351 fu.PushVlan(0x8100),
1352 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001353 KV: kwTable1Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001354 }
1355
1356 // Downstream HSIA - ONU1 UNI0 PON0
1357 fa4 := &fu.FlowArgs{
1358 MatchFields: []*ofp.OfpOxmOfbField{
1359 fu.InPort(1048576),
1360 fu.Metadata_ofp(1),
1361 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
1362 fu.VlanPcp(1),
Girish Gowdra0aca4982021-01-04 12:44:27 -08001363 fu.TunnelId(16),
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001364 },
1365 Actions: []*ofp.OfpAction{
1366 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1367 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
1368 fu.Output(536870912),
1369 fu.PopVlan(),
1370 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001371 KV: kwTable0Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001372 }
1373
1374 // Upstream flow DHCP flow - ONU1 UNI0 PON15
1375 fa5 := &fu.FlowArgs{
1376 MatchFields: []*ofp.OfpOxmOfbField{
1377 fu.InPort(536870927),
1378 fu.Metadata_ofp(1),
1379 fu.IpProto(17), // dhcp
1380 fu.VlanPcp(0),
1381 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
Girish Gowdra0aca4982021-01-04 12:44:27 -08001382 fu.TunnelId(16),
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001383 },
1384 Actions: []*ofp.OfpAction{
1385 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1386 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 259)),
1387 fu.Output(2147483645),
1388 fu.PushVlan(0x8100),
1389 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001390 KV: kwTable1Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001391 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001392
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001393 // Upstream EAPOL - ONU1 UNI0 PON15
1394 fa6 := &fu.FlowArgs{
1395 MatchFields: []*ofp.OfpOxmOfbField{
1396 fu.InPort(536870927),
1397 fu.Metadata_ofp(1),
1398 fu.EthType(0x888E),
1399 fu.VlanPcp(1),
1400 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 259),
Girish Gowdra0aca4982021-01-04 12:44:27 -08001401 fu.TunnelId(16),
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001402 },
1403 Actions: []*ofp.OfpAction{
1404 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1405 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
1406 fu.Output(2147483645),
1407 fu.PushVlan(0x8100),
1408 },
Girish Gowdra0aca4982021-01-04 12:44:27 -08001409 KV: kwTable1Meter1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001410 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001411
1412 // Upstream PPPOED - ONU1 UNI0 PON0
1413 fa7 := &fu.FlowArgs{
1414 MatchFields: []*ofp.OfpOxmOfbField{
1415 fu.InPort(536870912),
1416 fu.Metadata_ofp(1),
1417 fu.EthType(0x8863),
1418 fu.VlanPcp(1),
1419 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
1420 fu.TunnelId(16),
1421 },
1422 Actions: []*ofp.OfpAction{
1423 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1424 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
1425 fu.Output(2147483645),
1426 fu.PushVlan(0x8100),
1427 },
1428 KV: kwTable1Meter1,
1429 }
1430
1431 // Upstream PPPOED - ONU1 UNI0 PON15
1432 fa8 := &fu.FlowArgs{
1433 MatchFields: []*ofp.OfpOxmOfbField{
1434 fu.InPort(536870927),
1435 fu.Metadata_ofp(1),
1436 fu.EthType(0x8863),
1437 fu.VlanPcp(1),
1438 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 259),
1439 fu.TunnelId(16),
1440 },
1441 Actions: []*ofp.OfpAction{
1442 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
1443 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
1444 fu.Output(2147483645),
1445 fu.PushVlan(0x8100),
1446 },
1447 KV: kwTable1Meter1,
1448 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001449 flow0, _ := fu.MkFlowStat(fa0)
1450 flow1, _ := fu.MkFlowStat(fa1)
1451 flow2, _ := fu.MkFlowStat(fa2)
1452 flow3, _ := fu.MkFlowStat(fa3)
1453 flow4, _ := fu.MkFlowStat(fa4)
1454
1455 flow5, _ := fu.MkFlowStat(fa5)
1456 flow6, _ := fu.MkFlowStat(fa6)
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001457 flow7, _ := fu.MkFlowStat(fa7)
1458 flow8, _ := fu.MkFlowStat(fa8)
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001459
1460 type args struct {
1461 ctx context.Context
1462 flow *ofp.OfpFlowStats
1463 addFlow bool
1464 flowMetadata *voltha.FlowMetadata
1465 }
1466 tests := []struct {
1467 name string
1468 args args
1469 wantErr bool
1470 returnedErr error
1471 }{
1472 {
1473 name: "RouteFlowToOnuChannel-0",
1474 args: args{
1475 ctx: ctx,
1476 flow: flow0,
1477 addFlow: true,
1478 flowMetadata: &flowMetadata1,
1479 },
1480 wantErr: false,
1481 },
1482 {
1483 name: "RouteFlowToOnuChannel-1",
1484 args: args{
1485 ctx: ctx,
1486 flow: flow1,
1487 addFlow: true,
1488 flowMetadata: &flowMetadata1,
1489 },
1490 wantErr: false,
1491 },
1492 {
1493 name: "RouteFlowToOnuChannel-2",
1494 args: args{
1495 ctx: ctx,
1496 flow: flow2,
1497 addFlow: true,
1498 flowMetadata: &flowMetadata1,
1499 },
1500 wantErr: false,
1501 },
1502 {
1503 name: "RouteFlowToOnuChannel-3",
1504 args: args{
1505 ctx: ctx,
1506 flow: flow3,
1507 addFlow: true,
1508 flowMetadata: &flowMetadata1,
1509 },
1510 wantErr: false,
1511 },
1512 {
1513 name: "RouteFlowToOnuChannel-4",
1514 args: args{
1515 ctx: ctx,
1516 flow: flow4,
1517 addFlow: true,
1518 flowMetadata: &flowMetadata1,
1519 },
1520 wantErr: false,
1521 },
1522 {
1523 name: "RouteFlowToOnuChannel-5",
1524 args: args{
1525 ctx: ctx,
1526 flow: flow1,
1527 addFlow: false,
1528 flowMetadata: &flowMetadata1,
1529 },
1530 wantErr: false,
1531 },
1532 {
1533 name: "RouteFlowToOnuChannel-6",
1534 args: args{
1535 ctx: ctx,
1536 flow: flow1,
1537 addFlow: true,
Girish Gowdra0aca4982021-01-04 12:44:27 -08001538 flowMetadata: &flowMetadata1,
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001539 },
1540 wantErr: true,
1541 },
1542 {
1543 name: "RouteFlowToOnuChannel-7",
1544 args: args{
1545 ctx: ctx,
1546 flow: flow5,
1547 addFlow: true,
1548 flowMetadata: &flowMetadata1,
1549 },
1550 wantErr: false,
1551 },
1552 {
1553 name: "RouteFlowToOnuChannel-8",
1554 args: args{
1555 ctx: ctx,
1556 flow: flow6,
1557 addFlow: true,
1558 flowMetadata: &flowMetadata1,
1559 },
1560 wantErr: false,
1561 },
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001562 {
1563 name: "RouteFlowToOnuChannel-9",
1564 args: args{
1565 ctx: ctx,
1566 flow: flow7,
1567 addFlow: true,
1568 flowMetadata: &flowMetadata1,
1569 },
1570 wantErr: false,
1571 },
1572 {
1573 name: "RouteFlowToOnuChannel-10",
1574 args: args{
1575 ctx: ctx,
1576 flow: flow8,
1577 addFlow: true,
1578 flowMetadata: &flowMetadata1,
1579 },
1580 wantErr: false,
1581 },
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001582 }
1583
1584 var wg sync.WaitGroup
1585 defer wg.Wait() // wait for all go routines to complete
1586 for _, tt := range tests {
1587 t.Run(tt.name, func(t *testing.T) {
1588 wg.Add(1) // one per go routine
1589 go func() {
1590 defer wg.Done()
1591 tt.returnedErr = flowMgr[0].RouteFlowToOnuChannel(tt.args.ctx, tt.args.flow, tt.args.addFlow, tt.args.flowMetadata)
1592 if (tt.wantErr == false && tt.returnedErr != nil) || (tt.wantErr == true && tt.returnedErr == nil) {
1593 t.Errorf("OpenOltFlowMgr.RouteFlowToOnuChannel() error = %v, wantErr %v", tt.returnedErr, tt.wantErr)
1594 }
1595 }()
1596 })
1597 }
1598}