blob: ee252503cd2106468715ff9d8674a000f2a85d38 [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
17//Package adaptercore provides the utility for olt devices, flows and statistics
18package adaptercore
19
20import (
kdarapu3248f9a2019-10-03 13:54:52 +053021 "testing"
22
kdarapub26b4502019-10-05 03:02:33 +053023 "github.com/opencord/voltha-protos/go/voltha"
24
kdarapu3248f9a2019-10-03 13:54:52 +053025 "github.com/opencord/voltha-go/common/log"
26 tp "github.com/opencord/voltha-go/common/techprofile"
27 "github.com/opencord/voltha-go/db/model"
28 fu "github.com/opencord/voltha-go/rw_core/utils"
29 "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
kdarapub26b4502019-10-05 03:02:33 +053030 rsrcMgr "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
kdarapu3248f9a2019-10-03 13:54:52 +053031 "github.com/opencord/voltha-openolt-adapter/mocks"
32 ofp "github.com/opencord/voltha-protos/go/openflow_13"
33 "github.com/opencord/voltha-protos/go/openolt"
34 openoltpb2 "github.com/opencord/voltha-protos/go/openolt"
35 tp_pb "github.com/opencord/voltha-protos/go/tech_profile"
kdarapu3248f9a2019-10-03 13:54:52 +053036)
37
kdarapub26b4502019-10-05 03:02:33 +053038var flowMgr *OpenOltFlowMgr
39
kdarapu3248f9a2019-10-03 13:54:52 +053040func init() {
41 log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
kdarapub26b4502019-10-05 03:02:33 +053042 flowMgr = newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +053043}
44func newMockResourceMgr() *resourcemanager.OpenOltResourceMgr {
45 ranges := []*openolt.DeviceInfo_DeviceResourceRanges{
46 {IntfIds: []uint32{0, 1, 2}}}
47
48 deviceinfo := &openolt.DeviceInfo{Vendor: "openolt", Model: "openolt", HardwareVersion: "1.0", FirmwareVersion: "1.0",
49 DeviceId: "olt", DeviceSerialNumber: "openolt", PonPorts: 3, Technology: "Default",
50 OnuIdStart: 1, OnuIdEnd: 1, AllocIdStart: 1, AllocIdEnd: 1,
51 GemportIdStart: 1, GemportIdEnd: 1, FlowIdStart: 1, FlowIdEnd: 1,
52 Ranges: ranges,
53 }
54 rsrMgr := resourcemanager.NewResourceMgr("olt", "127.0.0.1:2379", "etcd", "olt", deviceinfo)
kdarapub26b4502019-10-05 03:02:33 +053055 for key := range rsrMgr.ResourceMgrs {
56 rsrMgr.ResourceMgrs[key].KVStore = &model.Backend{}
57 rsrMgr.ResourceMgrs[key].KVStore.Client = &mocks.MockKVClient{}
58 rsrMgr.ResourceMgrs[key].TechProfileMgr = mocks.MockTechProfile{TpID: key}
59 }
kdarapu3248f9a2019-10-03 13:54:52 +053060 return rsrMgr
61}
62
63func newMockFlowmgr() *OpenOltFlowMgr {
64 rsrMgr := newMockResourceMgr()
65 dh := newMockDeviceHandler()
66
67 rsrMgr.KVStore = &model.Backend{}
68 rsrMgr.KVStore.Client = &mocks.MockKVClient{}
69
70 dh.resourceMgr = rsrMgr
71 flwMgr := NewFlowManager(dh, rsrMgr)
72 onuIds := make(map[onuIDKey]onuInfo)
73 onuIds[onuIDKey{intfID: 1, onuID: 1}] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
74 onuIds[onuIDKey{intfID: 2, onuID: 2}] = onuInfo{intfID: 2, onuID: 2, serialNumber: "2"}
75 flwMgr.onuIds = onuIds
76
77 onuSerialNumbers := make(map[string]onuInfo)
78 onuSerialNumbers["1"] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
79 onuSerialNumbers["2"] = onuInfo{intfID: 2, onuID: 1, serialNumber: "2"}
80 flwMgr.onuSerialNumbers = onuSerialNumbers
81
82 onuGemPortIds := make(map[gemPortKey]onuInfo)
83 onuGemPortIds[gemPortKey{intfID: 1, gemPort: 1}] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
84 onuGemPortIds[gemPortKey{intfID: 2, gemPort: 2}] = onuInfo{intfID: 2, onuID: 2, serialNumber: "2"}
85 flwMgr.onuGemPortIds = onuGemPortIds
86
87 packetInGemPort := make(map[packetInInfoKey]uint32)
88 packetInGemPort[packetInInfoKey{intfID: 1, onuID: 1, logicalPort: 1}] = 1
89 packetInGemPort[packetInInfoKey{intfID: 2, onuID: 2, logicalPort: 2}] = 2
90
91 flwMgr.packetInGemPort = packetInGemPort
kdarapub26b4502019-10-05 03:02:33 +053092 tps := make([]tp.TechProfileIf, len(rsrMgr.ResourceMgrs))
93 for key := range rsrMgr.ResourceMgrs {
94 tps[key] = mocks.MockTechProfile{TpID: key}
kdarapu3248f9a2019-10-03 13:54:52 +053095 }
96 flwMgr.techprofile = tps
97 return flwMgr
98}
kdarapub26b4502019-10-05 03:02:33 +053099
kdarapu3248f9a2019-10-03 13:54:52 +0530100func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530101 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530102
103 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
104 ProfileType: "pt1", NumGemPorts: 1, NumTconts: 1, Version: 1,
105 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
106 }
107 tprofile.UsScheduler.Direction = "UPSTREAM"
108 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
109 tprofile.UsScheduler.QSchedPolicy = "WRR"
110
111 tprofile2 := tprofile
112 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
113 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
114 tprofile2.DsScheduler.QSchedPolicy = "WRR"
115 bands := make([]*ofp.OfpMeterBandHeader, 2)
116 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
117 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
118 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
119 flowmetadata := &voltha.FlowMetadata{
120 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
121 }
122 type args struct {
123 Dir tp_pb.Direction
124 IntfID uint32
125 OnuID uint32
126 UniID uint32
127 UniPort uint32
128 TpInst *tp.TechProfile
129 MeterID uint32
130 flowMetadata *voltha.FlowMetadata
131 }
132 tests := []struct {
133 name string
134 args args
135 wantErr bool
136 }{
137 // TODO: Add test cases.
138 {"CreateSchedulerQueues-1", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 1, flowMetadata: flowmetadata}, false},
139 {"CreateSchedulerQueues-2", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: flowmetadata}, false},
140 {"CreateSchedulerQueues-3", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 2, flowMetadata: flowmetadata}, true},
141 {"CreateSchedulerQueues-4", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2, flowMetadata: flowmetadata}, true},
142 {"CreateSchedulerQueues-5", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 2, OnuID: 2, UniID: 2, UniPort: 2, TpInst: tprofile, MeterID: 2, flowMetadata: flowmetadata}, true},
143 {"CreateSchedulerQueues-6", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 2, OnuID: 2, UniID: 2, UniPort: 2, TpInst: tprofile2, MeterID: 2, flowMetadata: flowmetadata}, true},
144 {"CreateSchedulerQueues-13", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: flowmetadata}, false},
145 //Negative testcases
146 {"CreateSchedulerQueues-7", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 1, flowMetadata: &voltha.FlowMetadata{}}, true},
147 {"CreateSchedulerQueues-8", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 0, flowMetadata: &voltha.FlowMetadata{}}, true},
kdarapub26b4502019-10-05 03:02:33 +0530148 {"CreateSchedulerQueues-9", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: &voltha.FlowMetadata{}}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530149 {"CreateSchedulerQueues-10", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 2, flowMetadata: &voltha.FlowMetadata{}}, true},
150 {"CreateSchedulerQueues-11", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2, flowMetadata: &voltha.FlowMetadata{}}, true},
151 {"CreateSchedulerQueues-12", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2}, true},
152 }
153 for _, tt := range tests {
154 t.Run(tt.name, func(t *testing.T) {
155 if err := flowMgr.CreateSchedulerQueues(tt.args.Dir, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.UniPort, tt.args.TpInst, tt.args.MeterID, tt.args.flowMetadata); (err != nil) != tt.wantErr {
156 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
157 }
158 })
159 }
160}
161
162func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
163
kdarapub26b4502019-10-05 03:02:33 +0530164 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530165 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
166 ProfileType: "pt1", NumGemPorts: 1, NumTconts: 1, Version: 1,
167 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
168 }
169 tprofile.UsScheduler.Direction = "UPSTREAM"
170 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
171 tprofile.UsScheduler.QSchedPolicy = "WRR"
172
173 tprofile2 := tprofile
174 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
175 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
176 tprofile2.DsScheduler.QSchedPolicy = "WRR"
177 //defTprofile := &tp.DefaultTechProfile{}
178 type args struct {
179 Dir tp_pb.Direction
180 IntfID uint32
181 OnuID uint32
182 UniID uint32
183 UniPort uint32
184 TpInst *tp.TechProfile
185 }
186 tests := []struct {
187 name string
188 args args
189 wantErr bool
190 }{
191 // TODO: Add test cases.
192 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile}, false},
193 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
194 // negative test cases
195 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
196 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
197 }
198 for _, tt := range tests {
199 t.Run(tt.name, func(t *testing.T) {
200
201 if err := flowMgr.RemoveSchedulerQueues(tt.args.Dir, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.UniPort, tt.args.TpInst); (err != nil) != tt.wantErr {
202 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
203 }
204 })
205 }
kdarapub26b4502019-10-05 03:02:33 +0530206
kdarapu3248f9a2019-10-03 13:54:52 +0530207}
208
209func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530210 // flowMgr := newMockFlowmgr()
211 log.Debug("Info Warning Error: Starting RemoveFlow() test")
kdarapu3248f9a2019-10-03 13:54:52 +0530212 fa := &fu.FlowArgs{
213 MatchFields: []*ofp.OfpOxmOfbField{
214 fu.InPort(2),
215 fu.Metadata_ofp(2),
216 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
217 },
218 Actions: []*ofp.OfpAction{
219 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
220 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
221 fu.Output(1),
222 },
223 }
224 ofpstats := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530225 ofpstats.Cookie = ofpstats.Id
226 flowMgr.storedDeviceFlows = append(flowMgr.storedDeviceFlows, *ofpstats)
227 lldpFa := &fu.FlowArgs{
228 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
229 MatchFields: []*ofp.OfpOxmOfbField{
230 fu.InPort(1),
231 fu.EthType(0x88CC),
232 fu.TunnelId(536870912),
233 },
234 Actions: []*ofp.OfpAction{
235 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
236 },
237 }
238 lldpofpstats := fu.MkFlowStat(lldpFa)
239 //lldpofpstats.Cookie = lldpofpstats.Id
240
241 dhcpFa := &fu.FlowArgs{
242 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
243 MatchFields: []*ofp.OfpOxmOfbField{
244 fu.InPort(1),
245 fu.UdpSrc(67),
246 //fu.TunnelId(536870912),
247 fu.IpProto(17),
248 },
249 Actions: []*ofp.OfpAction{
250 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
251 },
252 }
253 dhcpofpstats := fu.MkFlowStat(dhcpFa)
254 //dhcpofpstats.Cookie = dhcpofpstats.Id
kdarapu3248f9a2019-10-03 13:54:52 +0530255 type args struct {
256 flow *ofp.OfpFlowStats
257 }
258 tests := []struct {
259 name string
260 args args
261 }{
262 // TODO: Add test cases.
263 {"RemoveFlow", args{flow: ofpstats}},
kdarapub26b4502019-10-05 03:02:33 +0530264 {"RemoveFlow", args{flow: lldpofpstats}},
265 {"RemoveFlow", args{flow: dhcpofpstats}},
kdarapu3248f9a2019-10-03 13:54:52 +0530266 }
267 for _, tt := range tests {
268 t.Run(tt.name, func(t *testing.T) {
269 flowMgr.RemoveFlow(tt.args.flow)
270 })
271 }
kdarapub26b4502019-10-05 03:02:33 +0530272 // t.Error("=====")
kdarapu3248f9a2019-10-03 13:54:52 +0530273}
274
275func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530276 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530277 kw := make(map[string]uint64)
278 kw["table_id"] = 1
279 kw["meter_id"] = 1
kdarapub26b4502019-10-05 03:02:33 +0530280 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
281
282 // Upstream flow
kdarapu3248f9a2019-10-03 13:54:52 +0530283 fa := &fu.FlowArgs{
284 MatchFields: []*ofp.OfpOxmOfbField{
kdarapub26b4502019-10-05 03:02:33 +0530285 fu.InPort(536870912),
286 fu.Metadata_ofp(1),
287 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
288 },
289 Actions: []*ofp.OfpAction{
290 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
291 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
292 fu.Output(65536),
293 fu.PushVlan(0x8100),
294 },
295 KV: kw,
296 }
297
298 // Downstream flow
299 fa3 := &fu.FlowArgs{
300 MatchFields: []*ofp.OfpOxmOfbField{
301 fu.InPort(65536),
302 fu.Metadata_ofp(1),
303 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
304 },
305 Actions: []*ofp.OfpAction{
306 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
307 //fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
308 fu.PopVlan(),
309 fu.Output(536870912),
310 },
311 KV: kw,
312 }
313
314 fa2 := &fu.FlowArgs{
315 MatchFields: []*ofp.OfpOxmOfbField{
kdarapu3248f9a2019-10-03 13:54:52 +0530316 fu.InPort(1000),
317 fu.Metadata_ofp(1),
318 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
319 },
320 Actions: []*ofp.OfpAction{
321 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
322 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
323 fu.Output(65533),
324 },
325 KV: kw,
326 }
327
kdarapub26b4502019-10-05 03:02:33 +0530328 // TODO Add LLDP flow
329 // TODO Add DHCP flow
330
331 // Flows for negative scenarios
332 // Failure in formulateActionInfoFromFlow()
333 fa4 := &fu.FlowArgs{
334 MatchFields: []*ofp.OfpOxmOfbField{
335 fu.InPort(1000),
336 fu.Metadata_ofp(1),
337 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
338 },
339 Actions: []*ofp.OfpAction{
340 fu.Experimenter(257, []byte{1, 2, 3, 4}),
341 },
342 KV: kw,
343 }
344
345 // Invalid Output
346 fa5 := &fu.FlowArgs{
347 MatchFields: []*ofp.OfpOxmOfbField{
348 fu.InPort(1000),
349 fu.Metadata_ofp(1),
350 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
351 },
352 Actions: []*ofp.OfpAction{
353 fu.Output(0),
354 },
355 KV: kw,
356 }
357
358 // Tech-Profile-ID update (not supported)
359 kw6 := make(map[string]uint64)
360 kw6["table_id"] = 1
361 kw6["meter_id"] = 1
362 kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
363 fa6 := &fu.FlowArgs{
364 MatchFields: []*ofp.OfpOxmOfbField{
365 fu.InPort(536870912),
366 fu.TunnelId(16),
367 fu.Metadata_ofp(1),
368 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
369 },
370 Actions: []*ofp.OfpAction{
371 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
372 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
373 fu.Output(65535),
374 },
375 KV: kw6,
376 }
377
378 lldpFa := &fu.FlowArgs{
379 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
380 MatchFields: []*ofp.OfpOxmOfbField{
381 fu.InPort(1),
382 fu.EthType(0x88CC),
383 fu.TunnelId(536870912),
384 },
385 Actions: []*ofp.OfpAction{
386 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
387 },
388 }
389
390 dhcpFa := &fu.FlowArgs{
391 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
392 MatchFields: []*ofp.OfpOxmOfbField{
393 fu.InPort(1),
394 fu.UdpSrc(67),
395 //fu.TunnelId(536870912),
396 fu.IpProto(17),
397 },
398 Actions: []*ofp.OfpAction{
399 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
400 },
401 }
402 igmpFa := &fu.FlowArgs{
403 KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
404 MatchFields: []*ofp.OfpOxmOfbField{
405 fu.InPort(1),
406 fu.UdpSrc(67),
407 //fu.TunnelId(536870912),
408 fu.IpProto(2),
409 },
410 Actions: []*ofp.OfpAction{
411 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
412 },
413 }
414
415 fa9 := &fu.FlowArgs{
416 MatchFields: []*ofp.OfpOxmOfbField{
417 fu.InPort(536870912),
418 fu.TunnelId(16),
419 fu.Metadata_ofp(1),
420 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
421 fu.VlanPcp(1000),
422 fu.UdpDst(65535),
423 fu.UdpSrc(536870912),
424 fu.Ipv4Dst(65535),
425 fu.Ipv4Src(536870912),
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 fa10 := &fu.FlowArgs{
436 MatchFields: []*ofp.OfpOxmOfbField{
437 fu.InPort(65533),
438 // fu.TunnelId(16),
439 fu.Metadata_ofp(1),
440 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
441 fu.VlanPcp(1000),
442 fu.UdpDst(65535),
443 fu.UdpSrc(536870912),
444 fu.Ipv4Dst(65535),
445 fu.Ipv4Src(536870912),
446 },
447 Actions: []*ofp.OfpAction{
448 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
449 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
450 fu.Output(65535),
451 },
452 KV: kw6,
453 }
kdarapu3248f9a2019-10-03 13:54:52 +0530454 ofpstats := fu.MkFlowStat(fa)
kdarapub26b4502019-10-05 03:02:33 +0530455 ofpstats2 := fu.MkFlowStat(fa2)
456 ofpstats3 := fu.MkFlowStat(fa3)
457 ofpstats4 := fu.MkFlowStat(fa4)
458 ofpstats5 := fu.MkFlowStat(fa5)
459 ofpstats6 := fu.MkFlowStat(fa6)
460 ofpstats7 := fu.MkFlowStat(lldpFa)
461 ofpstats8 := fu.MkFlowStat(dhcpFa)
462 ofpstats9 := fu.MkFlowStat(fa9)
463 ofpstats10 := fu.MkFlowStat(fa10)
464 igmpstats := fu.MkFlowStat(igmpFa)
465
kdarapu3248f9a2019-10-03 13:54:52 +0530466 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
kdarapu3248f9a2019-10-03 13:54:52 +0530467 flowMetadata := &voltha.FlowMetadata{
468 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
469 }
470 type args struct {
471 flow *ofp.OfpFlowStats
472 flowMetadata *voltha.FlowMetadata
473 }
474 tests := []struct {
475 name string
476 args args
477 }{
478 // TODO: Add test cases.
479 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
kdarapub26b4502019-10-05 03:02:33 +0530480 {"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
481 {"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
482 {"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
483 {"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
484 {"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
485 {"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
486 {"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
487 {"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
488 {"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
489 {"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
490 //ofpstats10
kdarapu3248f9a2019-10-03 13:54:52 +0530491 }
492 for _, tt := range tests {
493 t.Run(tt.name, func(t *testing.T) {
494 flowMgr.AddFlow(tt.args.flow, tt.args.flowMetadata)
495 })
496 }
497}
498
499func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530500 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530501 type args struct {
502 intfID uint32
503 onuID uint32
504 serialNum string
505 }
506 tests := []struct {
507 name string
508 args args
509 }{
510 // TODO: Add test cases.
511 {"UpdateOnuInfo", args{1, 1, "onu1"}},
512 {"UpdateOnuInfo", args{2, 3, "onu1"}},
513 }
514 for _, tt := range tests {
515 t.Run(tt.name, func(t *testing.T) {
516
517 flowMgr.UpdateOnuInfo(tt.args.intfID, tt.args.onuID, tt.args.serialNum)
518 })
519 }
520}
521
522func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530523 // flowMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530524 type args struct {
525 packetIn *openoltpb2.PacketIndication
526 }
527 tests := []struct {
528 name string
529 args args
530 want uint32
531 wantErr bool
532 }{
533 // TODO: Add test cases.
534 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
535 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 65537, false},
536 // Negative Test cases.
537 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
538 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 2064, false},
539 }
540 for _, tt := range tests {
541 t.Run(tt.name, func(t *testing.T) {
542
543 got, err := flowMgr.GetLogicalPortFromPacketIn(tt.args.packetIn)
544 if (err != nil) != tt.wantErr {
545 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
546 return
547 }
548 if got != tt.want {
549 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
550 }
551 })
552 }
553}
554
555func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530556 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530557
558 type args struct {
559 intfID uint32
560 onuID uint32
561 portNum uint32
562 }
563 tests := []struct {
564 name string
565 args args
566 want uint32
567 wantErr bool
568 }{
569 // TODO: Add test cases.
570 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 1}, 1, false},
571 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 2}, 2, false},
572 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2}, 0, true},
573 }
574 for _, tt := range tests {
575 t.Run(tt.name, func(t *testing.T) {
576
kdarapub26b4502019-10-05 03:02:33 +0530577 got, err := flowMgr.GetPacketOutGemPortID(tt.args.intfID, tt.args.onuID, tt.args.portNum)
kdarapu3248f9a2019-10-03 13:54:52 +0530578 if (err != nil) != tt.wantErr {
579 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
580 return
581 }
582 if got != tt.want {
583 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
584 }
585
586 })
587 }
588}
589
590func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
kdarapub26b4502019-10-05 03:02:33 +0530591 // flwMgr := newMockFlowmgr()
kdarapu3248f9a2019-10-03 13:54:52 +0530592 type args struct {
593 intfID uint32
594 onuID uint32
595 uniID uint32
596 sn string
597 }
598 tests := []struct {
599 name string
600 args args
601 wantErr bool
602 }{
603 // TODO: Add test cases.
kdarapub26b4502019-10-05 03:02:33 +0530604 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: ""}, false},
kdarapu3248f9a2019-10-03 13:54:52 +0530605 }
606 for _, tt := range tests {
607 t.Run(tt.name, func(t *testing.T) {
608
kdarapub26b4502019-10-05 03:02:33 +0530609 if err := flowMgr.DeleteTechProfileInstance(tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.sn); (err != nil) != tt.wantErr {
kdarapu3248f9a2019-10-03 13:54:52 +0530610 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
611 }
612 })
613 }
614}
kdarapub26b4502019-10-05 03:02:33 +0530615
616func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
617 // flowMgr := newMockFlowmgr()
618 kw := make(map[string]uint64)
619 kw["table_id"] = 1
620 kw["meter_id"] = 1
621 kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
622
623 // Upstream flow
624 fa := &fu.FlowArgs{
625 MatchFields: []*ofp.OfpOxmOfbField{
626 fu.InPort(536870912),
627 fu.Metadata_ofp(1),
628 fu.IpProto(17), // dhcp
629 fu.VlanPcp(257),
630 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
631 },
632 Actions: []*ofp.OfpAction{
633 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
634 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
635 fu.Output(65536),
636 fu.PushVlan(0x8100),
637 },
638 KV: kw,
639 }
640
641 // EAPOL
642 fa2 := &fu.FlowArgs{
643 MatchFields: []*ofp.OfpOxmOfbField{
644 fu.InPort(536870912),
645 fu.Metadata_ofp(1),
646 fu.EthType(0x888E),
647 fu.VlanPcp(1),
648 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
649 },
650 Actions: []*ofp.OfpAction{
651 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
652 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
653 fu.Output(65536),
654 fu.PushVlan(0x8100),
655 },
656 KV: kw,
657 }
658
659 // HSIA
660 fa3 := &fu.FlowArgs{
661 MatchFields: []*ofp.OfpOxmOfbField{
662 fu.InPort(536870912),
663 fu.Metadata_ofp(1),
664 //fu.EthType(0x8100),
665 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
666 },
667 Actions: []*ofp.OfpAction{
668 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
669 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
670 fu.Output(65536),
671 fu.PushVlan(0x8100),
672 },
673 KV: kw,
674 }
675
676 fa4 := &fu.FlowArgs{
677 MatchFields: []*ofp.OfpOxmOfbField{
678 fu.InPort(65535),
679 fu.Metadata_ofp(1),
680 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
681 fu.VlanPcp(1),
682 },
683 Actions: []*ofp.OfpAction{
684 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
685 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
686 fu.Output(536870912),
687 fu.PopVlan(),
688 },
689 KV: kw,
690 }
691
692 classifierInfo := make(map[string]interface{})
693 actionInfo := make(map[string]interface{})
694 classifierInfo2 := make(map[string]interface{})
695 actionInfo2 := make(map[string]interface{})
696 classifierInfo3 := make(map[string]interface{})
697 actionInfo3 := make(map[string]interface{})
698 classifierInfo4 := make(map[string]interface{})
699 actionInfo4 := make(map[string]interface{})
700 flowState := fu.MkFlowStat(fa)
701 flowState2 := fu.MkFlowStat(fa2)
702 flowState3 := fu.MkFlowStat(fa3)
703 flowState4 := fu.MkFlowStat(fa4)
704 formulateClassifierInfoFromFlow(classifierInfo, flowState)
705 formulateClassifierInfoFromFlow(classifierInfo2, flowState2)
706 formulateClassifierInfoFromFlow(classifierInfo3, flowState3)
707 formulateClassifierInfoFromFlow(classifierInfo4, flowState4)
708
709 err := formulateActionInfoFromFlow(actionInfo, classifierInfo, flowState)
710 if err != nil {
711 // Error logging is already done in the called function
712 // So just return in case of error
713 return
714 }
715
716 err = formulateActionInfoFromFlow(actionInfo2, classifierInfo2, flowState2)
717 if err != nil {
718 // Error logging is already done in the called function
719 // So just return in case of error
720 return
721 }
722
723 err = formulateActionInfoFromFlow(actionInfo3, classifierInfo3, flowState3)
724 if err != nil {
725 // Error logging is already done in the called function
726 // So just return in case of error
727 return
728 }
729
730 err = formulateActionInfoFromFlow(actionInfo4, classifierInfo4, flowState4)
731 if err != nil {
732 // Error logging is already done in the called function
733 // So just return in case of error
734 return
735 }
736
737 //ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
738 //flowMetadata := &voltha.FlowMetadata{
739 // Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
740 //}
741
742 TpInst := &tp.TechProfile{
743 Name: "Test-Tech-Profile",
744 SubscriberIdentifier: "257",
745 ProfileType: "Mock",
746 Version: 1,
747 NumGemPorts: 4,
748 NumTconts: 1,
749 InstanceCtrl: tp.InstanceControl{
750 Onu: "1",
751 Uni: "16",
752 },
753 }
754
755 type fields struct {
756 techprofile []tp.TechProfileIf
757 deviceHandler *DeviceHandler
758 resourceMgr *rsrcMgr.OpenOltResourceMgr
759 onuIds map[onuIDKey]onuInfo
760 onuSerialNumbers map[string]onuInfo
761 onuGemPortIds map[gemPortKey]onuInfo
762 packetInGemPort map[packetInInfoKey]uint32
763 storedDeviceFlows []ofp.OfpFlowStats
764 }
765 type args struct {
766 args map[string]uint32
767 classifierInfo map[string]interface{}
768 actionInfo map[string]interface{}
769 flow *ofp.OfpFlowStats
770 gemPort uint32
771 intfID uint32
772 onuID uint32
773 uniID uint32
774 portNo uint32
775 TpInst *tp.TechProfile
776 allocID []uint32
777 gemPorts []uint32
778 TpID uint32
779 uni string
780 }
781 tests := []struct {
782 name string
783 fields fields
784 args args
785 }{
786 {
787 name: "checkAndAddFlow-1",
788 args: args{
789 args: nil,
790 classifierInfo: classifierInfo,
791 actionInfo: actionInfo,
792 flow: flowState,
793 gemPort: 1,
794 intfID: 1,
795 onuID: 1,
796 uniID: 16,
797 portNo: 1,
798 TpInst: TpInst,
799 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
800 gemPorts: []uint32{1, 2, 3, 4},
801 TpID: 64,
802 uni: "16",
803 },
804 },
805 {
806 name: "checkAndAddFlow-2",
807 args: args{
808 args: nil,
809 classifierInfo: classifierInfo2,
810 actionInfo: actionInfo2,
811 flow: flowState2,
812 gemPort: 1,
813 intfID: 1,
814 onuID: 1,
815 uniID: 16,
816 portNo: 1,
817 TpInst: TpInst,
818 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
819 gemPorts: []uint32{1, 2, 3, 4},
820 TpID: 64,
821 uni: "16",
822 },
823 },
824 {
825 name: "checkAndAddFlow-3",
826 args: args{
827 args: nil,
828 classifierInfo: classifierInfo3,
829 actionInfo: actionInfo3,
830 flow: flowState3,
831 gemPort: 1,
832 intfID: 1,
833 onuID: 1,
834 uniID: 16,
835 portNo: 1,
836 TpInst: TpInst,
837 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
838 gemPorts: []uint32{1, 2, 3, 4},
839 TpID: 64,
840 uni: "16",
841 },
842 },
843 {
844 name: "checkAndAddFlow-4",
845 args: args{
846 args: nil,
847 classifierInfo: classifierInfo4,
848 actionInfo: actionInfo4,
849 flow: flowState4,
850 gemPort: 1,
851 intfID: 1,
852 onuID: 1,
853 uniID: 16,
854 portNo: 1,
855 TpInst: TpInst,
856 allocID: []uint32{0x8001, 0x8002, 0x8003, 0x8004},
857 gemPorts: []uint32{1, 2, 3, 4},
858 TpID: 64,
859 uni: "16",
860 },
861 },
862 }
863 for _, tt := range tests {
864 t.Run(tt.name, func(t *testing.T) {
865 flowMgr.checkAndAddFlow(tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow, tt.args.gemPort,
866 tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.portNo, tt.args.TpInst, tt.args.allocID, tt.args.gemPorts,
867 tt.args.TpID, tt.args.uni)
868 })
869 }
870}