blob: 93a2e0e6afb657504d19566d21a09f7e7cbec5f1 [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 (
21 "fmt"
22 "testing"
23
24 "github.com/opencord/voltha-go/common/log"
25 tp "github.com/opencord/voltha-go/common/techprofile"
26 "github.com/opencord/voltha-go/db/model"
27 fu "github.com/opencord/voltha-go/rw_core/utils"
28 "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
29 "github.com/opencord/voltha-openolt-adapter/mocks"
30 ofp "github.com/opencord/voltha-protos/go/openflow_13"
31 "github.com/opencord/voltha-protos/go/openolt"
32 openoltpb2 "github.com/opencord/voltha-protos/go/openolt"
33 tp_pb "github.com/opencord/voltha-protos/go/tech_profile"
34 "github.com/opencord/voltha-protos/go/voltha"
35)
36
37func init() {
38 log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
39}
40func newMockResourceMgr() *resourcemanager.OpenOltResourceMgr {
41 ranges := []*openolt.DeviceInfo_DeviceResourceRanges{
42 {IntfIds: []uint32{0, 1, 2}}}
43
44 deviceinfo := &openolt.DeviceInfo{Vendor: "openolt", Model: "openolt", HardwareVersion: "1.0", FirmwareVersion: "1.0",
45 DeviceId: "olt", DeviceSerialNumber: "openolt", PonPorts: 3, Technology: "Default",
46 OnuIdStart: 1, OnuIdEnd: 1, AllocIdStart: 1, AllocIdEnd: 1,
47 GemportIdStart: 1, GemportIdEnd: 1, FlowIdStart: 1, FlowIdEnd: 1,
48 Ranges: ranges,
49 }
50 rsrMgr := resourcemanager.NewResourceMgr("olt", "127.0.0.1:2379", "etcd", "olt", deviceinfo)
51 return rsrMgr
52}
53
54func newMockFlowmgr() *OpenOltFlowMgr {
55 rsrMgr := newMockResourceMgr()
56 dh := newMockDeviceHandler()
57
58 rsrMgr.KVStore = &model.Backend{}
59 rsrMgr.KVStore.Client = &mocks.MockKVClient{}
60
61 dh.resourceMgr = rsrMgr
62 flwMgr := NewFlowManager(dh, rsrMgr)
63 onuIds := make(map[onuIDKey]onuInfo)
64 onuIds[onuIDKey{intfID: 1, onuID: 1}] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
65 onuIds[onuIDKey{intfID: 2, onuID: 2}] = onuInfo{intfID: 2, onuID: 2, serialNumber: "2"}
66 flwMgr.onuIds = onuIds
67
68 onuSerialNumbers := make(map[string]onuInfo)
69 onuSerialNumbers["1"] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
70 onuSerialNumbers["2"] = onuInfo{intfID: 2, onuID: 1, serialNumber: "2"}
71 flwMgr.onuSerialNumbers = onuSerialNumbers
72
73 onuGemPortIds := make(map[gemPortKey]onuInfo)
74 onuGemPortIds[gemPortKey{intfID: 1, gemPort: 1}] = onuInfo{intfID: 1, onuID: 1, serialNumber: "1"}
75 onuGemPortIds[gemPortKey{intfID: 2, gemPort: 2}] = onuInfo{intfID: 2, onuID: 2, serialNumber: "2"}
76 flwMgr.onuGemPortIds = onuGemPortIds
77
78 packetInGemPort := make(map[packetInInfoKey]uint32)
79 packetInGemPort[packetInInfoKey{intfID: 1, onuID: 1, logicalPort: 1}] = 1
80 packetInGemPort[packetInInfoKey{intfID: 2, onuID: 2, logicalPort: 2}] = 2
81
82 flwMgr.packetInGemPort = packetInGemPort
83 tps := make([]*tp.TechProfileMgr, len(rsrMgr.ResourceMgrs))
84 for key, val := range rsrMgr.ResourceMgrs {
85 tps[key] = val.TechProfileMgr
86 }
87 flwMgr.techprofile = tps
88 return flwMgr
89}
90func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
91 flowMgr := newMockFlowmgr()
92
93 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
94 ProfileType: "pt1", NumGemPorts: 1, NumTconts: 1, Version: 1,
95 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
96 }
97 tprofile.UsScheduler.Direction = "UPSTREAM"
98 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
99 tprofile.UsScheduler.QSchedPolicy = "WRR"
100
101 tprofile2 := tprofile
102 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
103 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
104 tprofile2.DsScheduler.QSchedPolicy = "WRR"
105 bands := make([]*ofp.OfpMeterBandHeader, 2)
106 bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
107 bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
108 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
109 flowmetadata := &voltha.FlowMetadata{
110 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
111 }
112 type args struct {
113 Dir tp_pb.Direction
114 IntfID uint32
115 OnuID uint32
116 UniID uint32
117 UniPort uint32
118 TpInst *tp.TechProfile
119 MeterID uint32
120 flowMetadata *voltha.FlowMetadata
121 }
122 tests := []struct {
123 name string
124 args args
125 wantErr bool
126 }{
127 // TODO: Add test cases.
128 {"CreateSchedulerQueues-1", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 1, flowMetadata: flowmetadata}, false},
129 {"CreateSchedulerQueues-2", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: flowmetadata}, false},
130 {"CreateSchedulerQueues-3", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 2, flowMetadata: flowmetadata}, true},
131 {"CreateSchedulerQueues-4", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2, flowMetadata: flowmetadata}, true},
132 {"CreateSchedulerQueues-5", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 2, OnuID: 2, UniID: 2, UniPort: 2, TpInst: tprofile, MeterID: 2, flowMetadata: flowmetadata}, true},
133 {"CreateSchedulerQueues-6", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 2, OnuID: 2, UniID: 2, UniPort: 2, TpInst: tprofile2, MeterID: 2, flowMetadata: flowmetadata}, true},
134 {"CreateSchedulerQueues-13", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: flowmetadata}, false},
135 //Negative testcases
136 {"CreateSchedulerQueues-7", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 1, flowMetadata: &voltha.FlowMetadata{}}, true},
137 {"CreateSchedulerQueues-8", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 0, flowMetadata: &voltha.FlowMetadata{}}, true},
138 {"CreateSchedulerQueues-9", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 1, flowMetadata: &voltha.FlowMetadata{}}, true},
139 {"CreateSchedulerQueues-10", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile, MeterID: 2, flowMetadata: &voltha.FlowMetadata{}}, true},
140 {"CreateSchedulerQueues-11", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2, flowMetadata: &voltha.FlowMetadata{}}, true},
141 {"CreateSchedulerQueues-12", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2, MeterID: 2}, true},
142 }
143 for _, tt := range tests {
144 t.Run(tt.name, func(t *testing.T) {
145 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 {
146 t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
147 }
148 })
149 }
150}
151
152func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
153
154 flowMgr := newMockFlowmgr()
155 tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
156 ProfileType: "pt1", NumGemPorts: 1, NumTconts: 1, Version: 1,
157 InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
158 }
159 tprofile.UsScheduler.Direction = "UPSTREAM"
160 tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
161 tprofile.UsScheduler.QSchedPolicy = "WRR"
162
163 tprofile2 := tprofile
164 tprofile2.DsScheduler.Direction = "DOWNSTREAM"
165 tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
166 tprofile2.DsScheduler.QSchedPolicy = "WRR"
167 //defTprofile := &tp.DefaultTechProfile{}
168 type args struct {
169 Dir tp_pb.Direction
170 IntfID uint32
171 OnuID uint32
172 UniID uint32
173 UniPort uint32
174 TpInst *tp.TechProfile
175 }
176 tests := []struct {
177 name string
178 args args
179 wantErr bool
180 }{
181 // TODO: Add test cases.
182 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_UPSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile}, false},
183 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
184 // negative test cases
185 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
186 {"RemoveSchedulerQueues", args{Dir: tp_pb.Direction_DOWNSTREAM, IntfID: 1, OnuID: 1, UniID: 1, UniPort: 1, TpInst: tprofile2}, false},
187 }
188 for _, tt := range tests {
189 t.Run(tt.name, func(t *testing.T) {
190
191 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 {
192 t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
193 }
194 })
195 }
196}
197
198func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
199 flowMgr := newMockFlowmgr()
200
201 fa := &fu.FlowArgs{
202 MatchFields: []*ofp.OfpOxmOfbField{
203 fu.InPort(2),
204 fu.Metadata_ofp(2),
205 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
206 },
207 Actions: []*ofp.OfpAction{
208 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
209 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
210 fu.Output(1),
211 },
212 }
213 ofpstats := fu.MkFlowStat(fa)
214 type args struct {
215 flow *ofp.OfpFlowStats
216 }
217 tests := []struct {
218 name string
219 args args
220 }{
221 // TODO: Add test cases.
222 {"RemoveFlow", args{flow: ofpstats}},
223 }
224 for _, tt := range tests {
225 t.Run(tt.name, func(t *testing.T) {
226 flowMgr.RemoveFlow(tt.args.flow)
227 })
228 }
229}
230
231func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
232
233 flowMgr := newMockFlowmgr()
234 kw := make(map[string]uint64)
235 kw["table_id"] = 1
236 kw["meter_id"] = 1
237 kw["write_metadata"] = 2
238 fa := &fu.FlowArgs{
239 MatchFields: []*ofp.OfpOxmOfbField{
240 fu.InPort(1000),
241 fu.Metadata_ofp(1),
242 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
243 },
244 Actions: []*ofp.OfpAction{
245 //fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
246 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
247 fu.Output(65533),
248 },
249 KV: kw,
250 }
251
252 ofpstats := fu.MkFlowStat(fa)
253 fmt.Println("ofpstats ", ofpstats)
254 //ofpstats.Dat
255 ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
256 //ofpWritemetaData := &ofp.ofp
257 flowMetadata := &voltha.FlowMetadata{
258 Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
259 }
260 type args struct {
261 flow *ofp.OfpFlowStats
262 flowMetadata *voltha.FlowMetadata
263 }
264 tests := []struct {
265 name string
266 args args
267 }{
268 // TODO: Add test cases.
269 {"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
270 }
271 for _, tt := range tests {
272 t.Run(tt.name, func(t *testing.T) {
273 flowMgr.AddFlow(tt.args.flow, tt.args.flowMetadata)
274 })
275 }
276}
277
278func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
279 flowMgr := newMockFlowmgr()
280 type args struct {
281 intfID uint32
282 onuID uint32
283 serialNum string
284 }
285 tests := []struct {
286 name string
287 args args
288 }{
289 // TODO: Add test cases.
290 {"UpdateOnuInfo", args{1, 1, "onu1"}},
291 {"UpdateOnuInfo", args{2, 3, "onu1"}},
292 }
293 for _, tt := range tests {
294 t.Run(tt.name, func(t *testing.T) {
295
296 flowMgr.UpdateOnuInfo(tt.args.intfID, tt.args.onuID, tt.args.serialNum)
297 })
298 }
299}
300
301func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
302 flowMgr := newMockFlowmgr()
303 type args struct {
304 packetIn *openoltpb2.PacketIndication
305 }
306 tests := []struct {
307 name string
308 args args
309 want uint32
310 wantErr bool
311 }{
312 // TODO: Add test cases.
313 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
314 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 65537, false},
315 // Negative Test cases.
316 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
317 {"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 2064, false},
318 }
319 for _, tt := range tests {
320 t.Run(tt.name, func(t *testing.T) {
321
322 got, err := flowMgr.GetLogicalPortFromPacketIn(tt.args.packetIn)
323 if (err != nil) != tt.wantErr {
324 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
325 return
326 }
327 if got != tt.want {
328 t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
329 }
330 })
331 }
332}
333
334func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
335 flwMgr := newMockFlowmgr()
336
337 type args struct {
338 intfID uint32
339 onuID uint32
340 portNum uint32
341 }
342 tests := []struct {
343 name string
344 args args
345 want uint32
346 wantErr bool
347 }{
348 // TODO: Add test cases.
349 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 1}, 1, false},
350 {"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 2}, 2, false},
351 {"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2}, 0, true},
352 }
353 for _, tt := range tests {
354 t.Run(tt.name, func(t *testing.T) {
355
356 got, err := flwMgr.GetPacketOutGemPortID(tt.args.intfID, tt.args.onuID, tt.args.portNum)
357 if (err != nil) != tt.wantErr {
358 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
359 return
360 }
361 if got != tt.want {
362 t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
363 }
364
365 })
366 }
367}
368
369func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
370 flwMgr := newMockFlowmgr()
371 type args struct {
372 intfID uint32
373 onuID uint32
374 uniID uint32
375 sn string
376 }
377 tests := []struct {
378 name string
379 args args
380 wantErr bool
381 }{
382 // TODO: Add test cases.
383 {"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: ""}, true},
384 }
385 for _, tt := range tests {
386 t.Run(tt.name, func(t *testing.T) {
387
388 if err := flwMgr.DeleteTechProfileInstance(tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.sn); (err != nil) != tt.wantErr {
389 t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
390 }
391 })
392 }
393}