blob: b75bfac1390fad2ec4aed3533ef04a20c9d22c8a [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
Girish Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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()
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
Girish Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-09-09 15:50:39 -070085 // onuGemInfo := make([]rsrcMgr.OnuGemInfo, NumPonPorts)
86 var i uint32
kdarapu3248f9a2019-10-03 13:54:52 +053087
Girish Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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 Gowdraaf66b0f2020-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{
295 fu.InPort(65536),
296 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
kdarapu3248f9a2019-10-03 13:54:52 +0530308 type args struct {
309 flow *ofp.OfpFlowStats
310 }
311 tests := []struct {
312 name string
313 args args
314 }{
315 // TODO: Add test cases.
316 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530317 {"RemoveFlow", args{flow: lldpofpstats}},
318 {"RemoveFlow", args{flow: dhcpofpstats}},
Esin Karamanccb714b2019-11-29 15:02:06 +0000319 {"RemoveFlow", args{flow: multicastOfpStats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530320 }
npujarec5762e2020-01-01 14:08:48 +0530321 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
322 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530323 for _, tt := range tests {
324 t.Run(tt.name, func(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700325 if err := flowMgr[0].RemoveFlow(ctx, tt.args.flow); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400326 logger.Warn(ctx, err)
327 }
kdarapu3248f9a2019-10-03 13:54:52 +0530328 })
329 }
kdarapub26b4502019-10-05 03:02:33 +0530330 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530331}
332
333func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530334 kw := make(map[string]uint64)
335 kw["table_id"] = 1
336 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530337 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
338
339 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530340 fa := &fu.FlowArgs{
341 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530342 fu.InPort(536870912),
343 fu.Metadata_ofp(1),
344 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
345 },
346 Actions: []*ofp.OfpAction{
347 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
348 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
349 fu.Output(65536),
350 fu.PushVlan(0x8100),
351 },
352 KV: kw,
353 }
354
355 // Downstream flow
356 fa3 := &fu.FlowArgs{
357 MatchFields: []*ofp.OfpOxmOfbField{
358 fu.InPort(65536),
359 fu.Metadata_ofp(1),
360 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
361 },
362 Actions: []*ofp.OfpAction{
363 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
364 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
365 fu.PopVlan(),
366 fu.Output(536870912),
367 },
368 KV: kw,
369 }
370
371 fa2 := &fu.FlowArgs{
372 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530373 fu.InPort(1000),
374 fu.Metadata_ofp(1),
375 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
376 },
377 Actions: []*ofp.OfpAction{
378 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
379 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
380 fu.Output(65533),
381 },
382 KV: kw,
383 }
384
kdarapub26b4502019-10-05 03:02:33 +0530385 // TODO Add LLDP flow
386 // TODO Add DHCP flow
387
388 // Flows for negative scenarios
389 // Failure in formulateActionInfoFromFlow()
390 fa4 := &fu.FlowArgs{
391 MatchFields: []*ofp.OfpOxmOfbField{
392 fu.InPort(1000),
393 fu.Metadata_ofp(1),
394 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
395 },
396 Actions: []*ofp.OfpAction{
397 fu.Experimenter(257, []byte{1, 2, 3, 4}),
398 },
399 KV: kw,
400 }
401
402 // Invalid Output
403 fa5 := &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.Output(0),
411 },
412 KV: kw,
413 }
414
415 // Tech-Profile-ID update (not supported)
416 kw6 := make(map[string]uint64)
417 kw6["table_id"] = 1
418 kw6["meter_id"] = 1
419 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
420 fa6 := &fu.FlowArgs{
421 MatchFields: []*ofp.OfpOxmOfbField{
422 fu.InPort(536870912),
423 fu.TunnelId(16),
424 fu.Metadata_ofp(1),
425 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
426 },
427 Actions: []*ofp.OfpAction{
428 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
429 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
430 fu.Output(65535),
431 },
432 KV: kw6,
433 }
434
435 lldpFa := &fu.FlowArgs{
436 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
437 MatchFields: []*ofp.OfpOxmOfbField{
438 fu.InPort(1),
439 fu.EthType(0x88CC),
440 fu.TunnelId(536870912),
441 },
442 Actions: []*ofp.OfpAction{
443 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
444 },
445 }
446
447 dhcpFa := &fu.FlowArgs{
448 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
449 MatchFields: []*ofp.OfpOxmOfbField{
450 fu.InPort(1),
451 fu.UdpSrc(67),
452 //fu.TunnelId(536870912),
453 fu.IpProto(17),
454 },
455 Actions: []*ofp.OfpAction{
456 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
457 },
458 }
459 igmpFa := &fu.FlowArgs{
460 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
461 MatchFields: []*ofp.OfpOxmOfbField{
462 fu.InPort(1),
463 fu.UdpSrc(67),
464 //fu.TunnelId(536870912),
465 fu.IpProto(2),
466 },
467 Actions: []*ofp.OfpAction{
468 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
469 },
470 }
471
472 fa9 := &fu.FlowArgs{
473 MatchFields: []*ofp.OfpOxmOfbField{
474 fu.InPort(536870912),
475 fu.TunnelId(16),
476 fu.Metadata_ofp(1),
477 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
478 fu.VlanPcp(1000),
479 fu.UdpDst(65535),
480 fu.UdpSrc(536870912),
481 fu.Ipv4Dst(65535),
482 fu.Ipv4Src(536870912),
483 },
484 Actions: []*ofp.OfpAction{
485 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
486 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
487 fu.Output(65535),
488 },
489 KV: kw6,
490 }
491
492 fa10 := &fu.FlowArgs{
493 MatchFields: []*ofp.OfpOxmOfbField{
494 fu.InPort(65533),
495 // fu.TunnelId(16),
496 fu.Metadata_ofp(1),
497 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
498 fu.VlanPcp(1000),
499 fu.UdpDst(65535),
500 fu.UdpSrc(536870912),
501 fu.Ipv4Dst(65535),
502 fu.Ipv4Src(536870912),
503 },
504 Actions: []*ofp.OfpAction{
505 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
506 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
507 fu.Output(65535),
508 },
509 KV: kw6,
510 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000511 //multicast flow
512 fa11 := &fu.FlowArgs{
513 MatchFields: []*ofp.OfpOxmOfbField{
514 fu.InPort(65536),
515 fu.VlanVid(660), //vlan
516 fu.Metadata_ofp(uint64(66)), //inner vlan
517 fu.EthType(0x800), //ipv4
518 fu.Ipv4Dst(3809869825), //227.22.0.1
519 },
520 Actions: []*ofp.OfpAction{
521 fu.Group(1),
522 },
523 KV: kw6,
524 }
divyadesaid26f6b12020-03-19 06:30:28 +0000525 ofpstats, _ := fu.MkFlowStat(fa)
526 ofpstats2, _ := fu.MkFlowStat(fa2)
527 ofpstats3, _ := fu.MkFlowStat(fa3)
528 ofpstats4, _ := fu.MkFlowStat(fa4)
529 ofpstats5, _ := fu.MkFlowStat(fa5)
530 ofpstats6, _ := fu.MkFlowStat(fa6)
531 ofpstats7, _ := fu.MkFlowStat(lldpFa)
532 ofpstats8, _ := fu.MkFlowStat(dhcpFa)
533 ofpstats9, _ := fu.MkFlowStat(fa9)
534 ofpstats10, _ := fu.MkFlowStat(fa10)
535 igmpstats, _ := fu.MkFlowStat(igmpFa)
536 ofpstats11, _ := fu.MkFlowStat(fa11)
kdarapub26b4502019-10-05 03:02:33 +0530537
Gamze Abakafee36392019-10-03 11:17:24 +0000538 fmt.Println(ofpstats6, ofpstats9, ofpstats10)
539
kdarapu3248f9a2019-10-03 13:54:52 +0530540 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
kdarapu3248f9a2019-10-03 13:54:52 +0530541 flowMetadata := &voltha.FlowMetadata{
542 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
543 }
544 type args struct {
545 flow *ofp.OfpFlowStats
546 flowMetadata *voltha.FlowMetadata
547 }
548 tests := []struct {
549 name string
550 args args
551 }{
552 // TODO: Add test cases.
553 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530554 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
555 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
556 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
557 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000558 //{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530559 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
560 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000561 //{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530562 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
Gamze Abakafee36392019-10-03 11:17:24 +0000563 //{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530564 //ofpstats10
Esin Karamanccb714b2019-11-29 15:02:06 +0000565 {"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
kdarapu3248f9a2019-10-03 13:54:52 +0530566 }
npujarec5762e2020-01-01 14:08:48 +0530567 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
568 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530569 for _, tt := range tests {
570 t.Run(tt.name, func(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700571 _ = flowMgr[0].AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
Kent Hagermane6ff1012020-07-14 15:07:53 -0400572 // TODO: actually verify test cases
kdarapu3248f9a2019-10-03 13:54:52 +0530573 })
574 }
575}
576
577func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +0530578 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
579 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530580
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700581 wg := sync.WaitGroup{}
582
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700583 intfCount := NumPonPorts
584 onuCount := OnuIDEnd - OnuIDStart + 1
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700585
586 for i := 0; i < intfCount; i++ {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700587 for j := 1; j <= onuCount; j++ {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700588 wg.Add(1)
589 go func(i uint32, j uint32) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400590 // TODO: actually verify success
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700591 _ = flowMgr[i].UpdateOnuInfo(ctx, i, i, fmt.Sprintf("onu-%d", i))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700592 wg.Done()
593 }(uint32(i), uint32(j))
594 }
595
596 }
597
598 wg.Wait()
599}
600
601func TestOpenOltFlowMgr_addGemPortToOnuInfoMap(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700602 intfNum := NumPonPorts
603 onuNum := OnuIDEnd - OnuIDStart + 1
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700604
605 // clean the flowMgr
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700606 for i := 0; i < intfNum; i++ {
607 flowMgr[i].onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, intfNum)
608 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700609
610 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
611 defer cancel()
612
613 // Create OnuInfo
614 for i := 0; i < intfNum; i++ {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700615 for o := 1; o <= onuNum; o++ {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400616 // TODO: actually verify success
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700617 _ = flowMgr[i].UpdateOnuInfo(ctx, uint32(i), uint32(o), fmt.Sprintf("i%do%d", i, o-1))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700618 }
619 }
620
621 // Add gemPorts to OnuInfo in parallel threads
622 wg := sync.WaitGroup{}
623
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700624 for o := 1; o <= onuNum; o++ {
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700625 for i := 0; i < intfNum; i++ {
626 wg.Add(1)
627 go func(intfId uint32, onuId uint32) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700628 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", intfId, onuId-1))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700629
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700630 flowMgr[intfId].addGemPortToOnuInfoMap(ctx, intfId, onuId, uint32(gemID))
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700631 wg.Done()
632 }(uint32(i), uint32(o))
633 }
634 }
635
636 wg.Wait()
637
638 // check that each entry of onuGemInfo has the correct number of ONUs
639 for i := 0; i < intfNum; i++ {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700640 lenofOnu := len(flowMgr[i].onuGemInfo[uint32(i)])
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700641 if onuNum != lenofOnu {
642 t.Errorf("OnuGemInfo length is not as expected len = %d, want %d", lenofOnu, onuNum)
643 }
644
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700645 for o := 1; o <= onuNum; o++ {
646 lenOfGemPorts := len(flowMgr[i].onuGemInfo[uint32(i)][o-1].GemPorts)
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700647 // check that each onuEntry has 1 gemPort
648 if lenOfGemPorts != 1 {
649 t.Errorf("Expected 1 GemPort per ONU, found %d", lenOfGemPorts)
650 }
651
652 // check that the value of the gemport is correct
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700653 gemID, _ := strconv.Atoi(fmt.Sprintf("90%d%d", i, o-1))
654 currentValue := flowMgr[i].onuGemInfo[uint32(i)][o-1].GemPorts[0]
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700655 if uint32(gemID) != currentValue {
656 t.Errorf("Expected GemPort value to be %d, found %d", gemID, currentValue)
657 }
658 }
kdarapu3248f9a2019-10-03 13:54:52 +0530659 }
660}
661
serkant.uluderya96af4932020-02-20 16:58:48 -0800662func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700663 // Create fresh flowMgr instance
664 flowMgr = newMockFlowmgr()
serkant.uluderya96af4932020-02-20 16:58:48 -0800665 type args struct {
666 intfID uint32
667 onuID uint32
668 gemPortIDs []uint32
669 gemPortIDsToBeDeleted []uint32
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700670 gemPortIDsRemaining []uint32
serkant.uluderya96af4932020-02-20 16:58:48 -0800671 serialNum string
672 finalLength int
673 }
674 tests := []struct {
675 name string
676 args args
677 }{
678 // Add/Delete single gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700679 {"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800680 // Delete all gemports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700681 {"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800682 // Try to delete when there is no gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700683 {"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, []uint32{}, "onu1", 0}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800684 // Try to delete non-existent gem port
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700685 {"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, []uint32{1}, "onu1", 1}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800686 // Try to delete two of the gem ports
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700687 {"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, []uint32{1, 3}, "onu1", 2}},
serkant.uluderya96af4932020-02-20 16:58:48 -0800688 }
689 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
690 defer cancel()
691 for _, tt := range tests {
692 t.Run(tt.name, func(t *testing.T) {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400693 // TODO: should check returned errors are as expected?
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700694 _ = flowMgr[tt.args.intfID].UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
serkant.uluderya96af4932020-02-20 16:58:48 -0800695 for _, gemPort := range tt.args.gemPortIDs {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700696 flowMgr[tt.args.intfID].addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
serkant.uluderya96af4932020-02-20 16:58:48 -0800697 }
698 for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700699 flowMgr[tt.args.intfID].deleteGemPortFromLocalCache(ctx, tt.args.intfID, tt.args.onuID, gemPortDeleted)
serkant.uluderya96af4932020-02-20 16:58:48 -0800700 }
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700701 lenofGemPorts := len(flowMgr[tt.args.intfID].onuGemInfo[tt.args.intfID][0].GemPorts)
serkant.uluderya96af4932020-02-20 16:58:48 -0800702 if lenofGemPorts != tt.args.finalLength {
703 t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
704 }
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700705 gemPorts := flowMgr[tt.args.intfID].onuGemInfo[tt.args.intfID][0].GemPorts
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700706 if !reflect.DeepEqual(tt.args.gemPortIDsRemaining, gemPorts) {
707 t.Errorf("GemPorts are not as expected = %v, want %v", gemPorts, tt.args.gemPortIDsRemaining)
708 }
serkant.uluderya96af4932020-02-20 16:58:48 -0800709
710 })
711 }
712}
713
kdarapu3248f9a2019-10-03 13:54:52 +0530714func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530715 type args struct {
716 packetIn *openoltpb2.PacketIndication
717 }
718 tests := []struct {
719 name string
720 args args
721 want uint32
722 wantErr bool
723 }{
724 // TODO: Add test cases.
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700725 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 0, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
726 {"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 +0530727 // Negative Test cases.
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700728 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
729 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 0, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 16, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530730 }
npujarec5762e2020-01-01 14:08:48 +0530731 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
732 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530733 for _, tt := range tests {
734 t.Run(tt.name, func(t *testing.T) {
735
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700736 got, err := flowMgr[tt.args.packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
kdarapu3248f9a2019-10-03 13:54:52 +0530737 if (err != nil) != tt.wantErr {
738 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
739 return
740 }
741 if got != tt.want {
742 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
743 }
744 })
745 }
746}
747
748func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700749 // Create fresh flowMgr instance
750 flowMgr = newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530751
Esin Karaman7fb80c22020-07-16 14:23:33 +0000752 //untagged packet in hex string
753 untaggedStr := "01005e000002000000000001080046c00020000040000102fa140a000001e00000029404000017000705e10000fa"
754 untagged, err := hex.DecodeString(untaggedStr)
755 if err != nil {
756 t.Error("Unable to parse hex string", err)
757 panic(err)
758 }
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700759 //single-tagged packet in hex string. vlanID.pbit: 1.1
760 singleTaggedStr := "01005e0000010025ba48172481002001080046c0002000004000010257deab140023e0000001940400001164ee9b0000000000000000000000000000"
Esin Karaman7fb80c22020-07-16 14:23:33 +0000761 singleTagged, err := hex.DecodeString(singleTaggedStr)
762 if err != nil {
763 t.Error("Unable to parse hex string", err)
764 panic(err)
765 }
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700766 //double-tagged packet in hex string. vlanID.pbit: 210.0-0.0
767 doubleTaggedStr := "01005e000016deadbeefba118100021081000000080046000028000000000102c5b87f000001e0000016940400002200f8030000000104000000e10000fa"
Esin Karaman7fb80c22020-07-16 14:23:33 +0000768 doubleTagged, err := hex.DecodeString(doubleTaggedStr)
769 if err != nil {
770 t.Error("Unable to parse hex string", err)
771 panic(err)
772 }
773
kdarapu3248f9a2019-10-03 13:54:52 +0530774 type args struct {
775 intfID uint32
776 onuID uint32
777 portNum uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000778 packet []byte
kdarapu3248f9a2019-10-03 13:54:52 +0530779 }
780 tests := []struct {
781 name string
782 args args
783 want uint32
784 wantErr bool
785 }{
786 // TODO: Add test cases.
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700787 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 1, packet: untagged}, 1, false},
788 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2, packet: singleTagged}, 2, false},
789 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 1, packet: doubleTagged}, 1, false},
790 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 10, portNum: 10, packet: untagged}, 2, true},
791 {"GetPacketOutGemPortID", args{intfID: 0, onuID: 1, portNum: 3, packet: []byte{}}, 3, true},
kdarapu3248f9a2019-10-03 13:54:52 +0530792 }
Esin Karaman7fb80c22020-07-16 14:23:33 +0000793
npujarec5762e2020-01-01 14:08:48 +0530794 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
795 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530796 for _, tt := range tests {
797 t.Run(tt.name, func(t *testing.T) {
798
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700799 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 +0000800 if tt.wantErr {
801 if err == nil {
802 //error expected but got value
803 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, wantErr %v", got, tt.wantErr)
804 }
805 } else {
806 if err != nil {
807 //error is not expected but got error
808 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
809 return
810 }
811 if got != tt.want {
812 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
813 }
kdarapu3248f9a2019-10-03 13:54:52 +0530814 }
kdarapu3248f9a2019-10-03 13:54:52 +0530815 })
816 }
817}
818
819func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapu3248f9a2019-10-03 13:54:52 +0530820 type args struct {
821 intfID uint32
822 onuID uint32
823 uniID uint32
824 sn string
Gamze Abakafee36392019-10-03 11:17:24 +0000825 tpID uint32
kdarapu3248f9a2019-10-03 13:54:52 +0530826 }
827 tests := []struct {
828 name string
829 args args
830 wantErr bool
831 }{
832 // TODO: Add test cases.
Gamze Abakafee36392019-10-03 11:17:24 +0000833 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530834 }
npujarec5762e2020-01-01 14:08:48 +0530835 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
836 defer cancel()
kdarapu3248f9a2019-10-03 13:54:52 +0530837 for _, tt := range tests {
838 t.Run(tt.name, func(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -0700839 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 +0530840 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
841 }
842 })
843 }
844}
kdarapub26b4502019-10-05 03:02:33 +0530845
846func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000847 ctx := context.Background()
kdarapub26b4502019-10-05 03:02:33 +0530848 kw := make(map[string]uint64)
849 kw["table_id"] = 1
850 kw["meter_id"] = 1
851 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
852
853 // Upstream flow
854 fa := &fu.FlowArgs{
855 MatchFields: []*ofp.OfpOxmOfbField{
856 fu.InPort(536870912),
857 fu.Metadata_ofp(1),
858 fu.IpProto(17), // dhcp
Gamze Abakafee36392019-10-03 11:17:24 +0000859 fu.VlanPcp(0),
kdarapub26b4502019-10-05 03:02:33 +0530860 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
861 },
862 Actions: []*ofp.OfpAction{
863 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
864 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
865 fu.Output(65536),
866 fu.PushVlan(0x8100),
867 },
868 KV: kw,
869 }
870
871 // EAPOL
872 fa2 := &fu.FlowArgs{
873 MatchFields: []*ofp.OfpOxmOfbField{
874 fu.InPort(536870912),
875 fu.Metadata_ofp(1),
876 fu.EthType(0x888E),
877 fu.VlanPcp(1),
878 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
879 },
880 Actions: []*ofp.OfpAction{
881 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
882 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
883 fu.Output(65536),
884 fu.PushVlan(0x8100),
885 },
886 KV: kw,
887 }
888
889 // HSIA
890 fa3 := &fu.FlowArgs{
891 MatchFields: []*ofp.OfpOxmOfbField{
892 fu.InPort(536870912),
893 fu.Metadata_ofp(1),
894 //fu.EthType(0x8100),
895 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
896 },
897 Actions: []*ofp.OfpAction{
898 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
899 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
900 fu.Output(65536),
901 fu.PushVlan(0x8100),
902 },
903 KV: kw,
904 }
905
906 fa4 := &fu.FlowArgs{
907 MatchFields: []*ofp.OfpOxmOfbField{
908 fu.InPort(65535),
909 fu.Metadata_ofp(1),
910 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
911 fu.VlanPcp(1),
912 },
913 Actions: []*ofp.OfpAction{
914 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
915 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
916 fu.Output(536870912),
917 fu.PopVlan(),
918 },
919 KV: kw,
920 }
921
922 classifierInfo := make(map[string]interface{})
923 actionInfo := make(map[string]interface{})
924 classifierInfo2 := make(map[string]interface{})
925 actionInfo2 := make(map[string]interface{})
926 classifierInfo3 := make(map[string]interface{})
927 actionInfo3 := make(map[string]interface{})
928 classifierInfo4 := make(map[string]interface{})
929 actionInfo4 := make(map[string]interface{})
divyadesaid26f6b12020-03-19 06:30:28 +0000930 flowState, _ := fu.MkFlowStat(fa)
931 flowState2, _ := fu.MkFlowStat(fa2)
932 flowState3, _ := fu.MkFlowStat(fa3)
933 flowState4, _ := fu.MkFlowStat(fa4)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000934 formulateClassifierInfoFromFlow(ctx, classifierInfo, flowState)
935 formulateClassifierInfoFromFlow(ctx, classifierInfo2, flowState2)
936 formulateClassifierInfoFromFlow(ctx, classifierInfo3, flowState3)
937 formulateClassifierInfoFromFlow(ctx, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530938
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 err := formulateActionInfoFromFlow(ctx, actionInfo, classifierInfo, flowState)
kdarapub26b4502019-10-05 03:02:33 +0530940 if err != nil {
941 // Error logging is already done in the called function
942 // So just return in case of error
943 return
944 }
945
Neha Sharma96b7bf22020-06-15 10:37:32 +0000946 err = formulateActionInfoFromFlow(ctx, actionInfo2, classifierInfo2, flowState2)
kdarapub26b4502019-10-05 03:02:33 +0530947 if err != nil {
948 // Error logging is already done in the called function
949 // So just return in case of error
950 return
951 }
952
Neha Sharma96b7bf22020-06-15 10:37:32 +0000953 err = formulateActionInfoFromFlow(ctx, actionInfo3, classifierInfo3, flowState3)
kdarapub26b4502019-10-05 03:02:33 +0530954 if err != nil {
955 // Error logging is already done in the called function
956 // So just return in case of error
957 return
958 }
959
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960 err = formulateActionInfoFromFlow(ctx, actionInfo4, classifierInfo4, flowState4)
kdarapub26b4502019-10-05 03:02:33 +0530961 if err != nil {
962 // Error logging is already done in the called function
963 // So just return in case of error
964 return
965 }
966
967 //ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
968 //flowMetadata := &voltha.FlowMetadata{
969 // Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
970 //}
971
972 TpInst := &tp.TechProfile{
973 Name: "Test-Tech-Profile",
974 SubscriberIdentifier: "257",
975 ProfileType: "Mock",
976 Version: 1,
977 NumGemPorts: 4,
kdarapub26b4502019-10-05 03:02:33 +0530978 InstanceCtrl: tp.InstanceControl{
979 Onu: "1",
980 Uni: "16",
981 },
982 }
983
kdarapub26b4502019-10-05 03:02:33 +0530984 type args struct {
985 args map[string]uint32
986 classifierInfo map[string]interface{}
987 actionInfo map[string]interface{}
988 flow *ofp.OfpFlowStats
989 gemPort uint32
990 intfID uint32
991 onuID uint32
992 uniID uint32
993 portNo uint32
994 TpInst *tp.TechProfile
995 allocID []uint32
996 gemPorts []uint32
997 TpID uint32
998 uni string
999 }
1000 tests := []struct {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001001 name string
1002 args args
kdarapub26b4502019-10-05 03:02:33 +05301003 }{
1004 {
1005 name: "checkAndAddFlow-1",
1006 args: args{
1007 args: nil,
1008 classifierInfo: classifierInfo,
1009 actionInfo: actionInfo,
1010 flow: flowState,
1011 gemPort: 1,
1012 intfID: 1,
1013 onuID: 1,
1014 uniID: 16,
1015 portNo: 1,
1016 TpInst: TpInst,
1017 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1018 gemPorts: []uint32{1, 2, 3, 4},
1019 TpID: 64,
1020 uni: "16",
1021 },
1022 },
1023 {
1024 name: "checkAndAddFlow-2",
1025 args: args{
1026 args: nil,
1027 classifierInfo: classifierInfo2,
1028 actionInfo: actionInfo2,
1029 flow: flowState2,
1030 gemPort: 1,
1031 intfID: 1,
1032 onuID: 1,
1033 uniID: 16,
1034 portNo: 1,
1035 TpInst: TpInst,
1036 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1037 gemPorts: []uint32{1, 2, 3, 4},
1038 TpID: 64,
1039 uni: "16",
1040 },
1041 },
1042 {
1043 name: "checkAndAddFlow-3",
1044 args: args{
1045 args: nil,
1046 classifierInfo: classifierInfo3,
1047 actionInfo: actionInfo3,
1048 flow: flowState3,
1049 gemPort: 1,
1050 intfID: 1,
1051 onuID: 1,
1052 uniID: 16,
1053 portNo: 1,
1054 TpInst: TpInst,
1055 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1056 gemPorts: []uint32{1, 2, 3, 4},
1057 TpID: 64,
1058 uni: "16",
1059 },
1060 },
1061 {
1062 name: "checkAndAddFlow-4",
1063 args: args{
1064 args: nil,
1065 classifierInfo: classifierInfo4,
1066 actionInfo: actionInfo4,
1067 flow: flowState4,
1068 gemPort: 1,
1069 intfID: 1,
1070 onuID: 1,
1071 uniID: 16,
1072 portNo: 1,
1073 TpInst: TpInst,
1074 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
1075 gemPorts: []uint32{1, 2, 3, 4},
1076 TpID: 64,
1077 uni: "16",
1078 },
1079 },
1080 }
npujarec5762e2020-01-01 14:08:48 +05301081 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1082 defer cancel()
kdarapub26b4502019-10-05 03:02:33 +05301083 for _, tt := range tests {
1084 t.Run(tt.name, func(t *testing.T) {
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001085 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 +00001086 tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
kdarapub26b4502019-10-05 03:02:33 +05301087 })
1088 }
1089}
Esin Karamanccb714b2019-11-29 15:02:06 +00001090
Esin Karamand519bbf2020-07-01 11:16:03 +00001091func TestOpenOltFlowMgr_TestMulticastFlowAndGroup(t *testing.T) {
npujarec5762e2020-01-01 14:08:48 +05301092 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
1093 defer cancel()
Esin Karamanccb714b2019-11-29 15:02:06 +00001094 //create group
1095 group := newGroup(2, []uint32{1})
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001096 err := flowMgr[0].grpMgr.AddGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001097 if err != nil {
1098 t.Error("group-add failed", err)
1099 return
1100 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001101 //create multicast flow
1102 multicastFlowArgs := &fu.FlowArgs{
1103 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karamand519bbf2020-07-01 11:16:03 +00001104 fu.InPort(1048576),
Esin Karamanccb714b2019-11-29 15:02:06 +00001105 fu.VlanVid(660), //vlan
1106 fu.Metadata_ofp(uint64(66)), //inner vlan
1107 fu.EthType(0x800), //ipv4
1108 fu.Ipv4Dst(3809869825), //227.22.0.1
1109 },
1110 Actions: []*ofp.OfpAction{
1111 fu.Group(1),
1112 },
1113 }
divyadesaid26f6b12020-03-19 06:30:28 +00001114 ofpStats, _ := fu.MkFlowStat(multicastFlowArgs)
Esin Karamand519bbf2020-07-01 11:16:03 +00001115 fmt.Println(ofpStats.Id)
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001116 err = flowMgr[0].AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
Esin Karamand519bbf2020-07-01 11:16:03 +00001117 if err != nil {
1118 t.Error("Multicast flow-add failed", err)
1119 return
1120 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001121
1122 //add bucket to the group
1123 group = newGroup(2, []uint32{1, 2})
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001124 err = flowMgr[0].grpMgr.ModifyGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001125 if err != nil {
1126 t.Error("modify-group failed", err)
1127 return
1128 }
1129 //remove the multicast flow
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001130 err = flowMgr[0].RemoveFlow(ctx, ofpStats)
Esin Karamand519bbf2020-07-01 11:16:03 +00001131 if err != nil {
1132 t.Error("Multicast flow-remove failed", err)
1133 return
1134 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001135
Esin Karamand519bbf2020-07-01 11:16:03 +00001136 //remove the group
Girish Gowdraaf66b0f2020-09-09 15:50:39 -07001137 err = flowMgr[0].grpMgr.DeleteGroup(ctx, group)
Esin Karamand519bbf2020-07-01 11:16:03 +00001138 if err != nil {
1139 t.Error("delete-group failed", err)
1140 return
1141 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001142}