blob: 71c864a93f066dd805b0d4ff80adbe11669ebfda [file] [log] [blame]
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -07001/*
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 core provides the utility for olt devices, flows and statistics
18package platform
19
20import (
21 "context"
22 fu "github.com/opencord/voltha-lib-go/v7/pkg/flows"
23 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
24 "github.com/opencord/voltha-protos/v5/go/voltha"
25 "google.golang.org/grpc/codes"
26 "google.golang.org/grpc/status"
27 "math"
28 "reflect"
29 "testing"
30)
31
32func TestMkUniPortNum(t *testing.T) {
33 type args struct {
34 intfID uint32
35 onuID uint32
36 uniID uint32
37 }
38 tests := []struct {
39 name string
40 args args
41 want uint32
42 }{
43 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -070044 {"MkUniPortNum-1", args{1, 1, 1}, ((1 * 65536) + (1 * 256) + 1)},
45 {"MkUniPortNum-2", args{4, 5, 6}, ((4 * 65536) + (5 * 256) + 6)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -070046 // Negative test cases to cover the log.warn
Mahir Gunyela8ab55f2021-10-20 15:07:25 -070047 {"MkUniPortNum-3", args{4, 130, 6}, ((4 * 65536) + (130 * 256) + 6)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -070048 }
49 for _, tt := range tests {
50 t.Run(tt.name, func(t *testing.T) {
51 if got := MkUniPortNum(context.Background(), tt.args.intfID, tt.args.onuID, tt.args.uniID); got != tt.want {
52 t.Errorf("MkUniPortNum() = %v, want %v", got, tt.want)
53 } else {
54 t.Logf("Expected %v , Actual %v \n", tt.want, got)
55 }
56 })
57 }
58}
59
60func TestOnuIDFromPortNum(t *testing.T) {
61 type args struct {
62 portNum uint32
63 }
64 tests := []struct {
65 name string
66 args args
67 want uint32
68 }{
69 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -070070 {"OnuIDFromPortNum-1", args{portNum: 8096}, ((8096 / 256) & 255)},
71 {"OnuIDFromPortNum-2", args{portNum: 9095}, ((9095 / 256) & 255)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -070072 }
73 for _, tt := range tests {
74 t.Run(tt.name, func(t *testing.T) {
75 if got := OnuIDFromPortNum(tt.args.portNum); got != tt.want {
76 t.Errorf("OnuIDFromPortNum() = %v, want %v", got, tt.want)
77 } else {
78 t.Logf("Expected %v , Actual %v \n", tt.want, got)
79 }
80 })
81 }
82}
83
84func TestIntfIDFromUniPortNum(t *testing.T) {
85 type args struct {
86 portNum uint32
87 }
88 tests := []struct {
89 name string
90 args args
91 want uint32
92 }{
93 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -070094 {"IntfIDFromUniPortNum-1", args{portNum: 8096}, ((8096 / 65536) & 255)},
95 {"IntfIDFromUniPortNum-2", args{portNum: 1024}, ((1024 / 65536) & 255)},
96 {"IntfIDFromUniPortNum-3", args{portNum: 66560}, ((66560 / 65536) & 255)},
97 {"IntfIDFromUniPortNum-4", args{portNum: 16712193}, ((16712193 / 65536) & 255)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -070098 }
99 for _, tt := range tests {
100 t.Run(tt.name, func(t *testing.T) {
101 if got := IntfIDFromUniPortNum(tt.args.portNum); got != tt.want {
102 t.Errorf("IntfIDFromUniPortNum() = %v, want %v", got, tt.want)
103 } else {
104 t.Logf("Expected %v , Actual %v \n", tt.want, got)
105 }
106 })
107 }
108}
109
110func TestUniIDFromPortNum(t *testing.T) {
111 type args struct {
112 portNum uint32
113 }
114 tests := []struct {
115 name string
116 args args
117 want uint32
118 }{
119
120 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700121 {"UniIDFromPortNum-1", args{portNum: 8096}, (8096 & 255)},
122 {"UniIDFromPortNum-2", args{portNum: 1024}, (1024 & 255)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700123 }
124 for _, tt := range tests {
125 t.Run(tt.name, func(t *testing.T) {
126 if got := UniIDFromPortNum(tt.args.portNum); got != tt.want {
127 t.Errorf("UniIDFromPortNum() = %v, want %v", got, tt.want)
128 } else {
129 t.Logf("Expected %v , Actual %v \n", tt.want, got)
130 }
131 })
132 }
133}
134
135func TestIntfIDToPortNo(t *testing.T) {
136 type args struct {
137 intfID uint32
138 intfType voltha.Port_PortType
139 }
140 tests := []struct {
141 name string
142 args args
143 want uint32
144 }{
145 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700146 {"IntfIDToPortNo-1", args{intfID: 120, intfType: voltha.Port_ETHERNET_NNI}, (uint32(math.Pow(2, 24)) + 120)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700147 {"IntfIDToPortNo-2", args{intfID: 1024, intfType: voltha.Port_ETHERNET_UNI}, 0},
148 {"IntfIDToPortNo-3", args{intfID: 456, intfType: voltha.Port_PON_OLT}, (uint32(2*math.Pow(2, 28)) + 456)},
149 {"IntfIDToPortNo-4", args{intfID: 28, intfType: voltha.Port_PON_ONU}, 0},
150 {"IntfIDToPortNo-5", args{intfID: 45, intfType: voltha.Port_UNKNOWN}, 0},
151 {"IntfIDToPortNo-6", args{intfID: 45, intfType: voltha.Port_VENET_OLT}, 0},
152 {"IntfIDToPortNo-7", args{intfID: 45, intfType: voltha.Port_VENET_ONU}, 0},
153 }
154 for _, tt := range tests {
155 t.Run(tt.name, func(t *testing.T) {
156 if got := IntfIDToPortNo(tt.args.intfID, tt.args.intfType); got != tt.want {
157 t.Errorf("IntfIDToPortNo() = %v, want %v", got, tt.want)
158 } else {
159 t.Logf("Expected %v , Actual %v \n", tt.want, got)
160 }
161 })
162 }
163}
164
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700165func TestPortNoToIntfID(t *testing.T) {
166 type args struct {
167 portNo uint32
168 intfType voltha.Port_PortType
169 }
170 tests := []struct {
171 name string
172 args args
173 want uint32
174 }{
175 // TODO: Add test cases.
176 {"PortNoToIntfID-1", args{portNo: 16777216, intfType: voltha.Port_ETHERNET_NNI}, 0},
177 {"PortNoToIntfID-2", args{portNo: 16777217, intfType: voltha.Port_ETHERNET_NNI}, 1},
178 {"PortNoToIntfID-3", args{portNo: 16777218, intfType: voltha.Port_ETHERNET_NNI}, 2},
179 {"PortNoToIntfID-4", args{portNo: 1024, intfType: voltha.Port_ETHERNET_UNI}, 0},
180 {"PortNoToIntfID-5", args{portNo: 536870912, intfType: voltha.Port_PON_OLT}, 0},
181 {"PortNoToIntfID-6", args{portNo: 536871167, intfType: voltha.Port_PON_OLT}, 255},
182 {"PortNoToIntfID-7", args{portNo: 28, intfType: voltha.Port_PON_ONU}, 0},
183 {"PortNoToIntfID-8", args{portNo: 45, intfType: voltha.Port_UNKNOWN}, 0},
184 {"PortNoToIntfID-9", args{portNo: 45, intfType: voltha.Port_VENET_OLT}, 0},
185 {"PortNoToIntfID-10", args{portNo: 45, intfType: voltha.Port_VENET_ONU}, 0},
186 }
187 for _, tt := range tests {
188 t.Run(tt.name, func(t *testing.T) {
189 if got := PortNoToIntfID(tt.args.portNo, tt.args.intfType); got != tt.want {
190 t.Errorf("PortNoToIntfID() = %v, want %v", got, tt.want)
191 } else {
192 t.Logf("Expected %v , Actual %v \n", tt.want, got)
193 }
194 })
195 }
196}
197
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700198func TestIntfIDFromNniPortNum(t *testing.T) {
199 type args struct {
200 portNum uint32
201 }
202
203 tests := []struct {
204 name string
205 args args
206 want uint32
207 wantErr error
208 }{
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700209 // TODO: Add test cases. min 16777216, max 33554432
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700210 {"IntfIDFromNniPortNum-01", args{portNum: 8081}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 8081)},
211 {"IntfIDFromNniPortNum-02", args{portNum: 9090}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 9090)},
212 {"IntfIDFromNniPortNum-03", args{portNum: 0}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 0)},
213 {"IntfIDFromNniPortNum-04", args{portNum: 65535}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 65535)},
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700214 {"IntfIDFromNniPortNum-05", args{portNum: 16777215}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 16777215)},
215 {"IntfIDFromNniPortNum-06", args{portNum: 16777216}, 0, nil},
216 {"IntfIDFromNniPortNum-07", args{portNum: 16777217}, 1, nil},
217 {"IntfIDFromNniPortNum-08", args{portNum: 16777218}, 2, nil},
218 {"IntfIDFromNniPortNum-09", args{portNum: 16777219}, 3, nil},
219 {"IntfIDFromNniPortNum-10", args{portNum: 33554430}, 16777214, nil},
220 {"IntfIDFromNniPortNum-11", args{portNum: 33554431}, 16777215, nil},
221 {"IntfIDFromNniPortNum-12", args{portNum: 33554432}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 33554432)},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700222 }
223 for _, tt := range tests {
224 t.Run(tt.name, func(t *testing.T) {
225 got, err := IntfIDFromNniPortNum(context.Background(), tt.args.portNum)
226 if got != tt.want {
227 t.Errorf("IntfIDFromNniPortNum(): FOR[%v] WANT[%v and %v] GOT[%v and %v]",
228 tt.args.portNum, tt.want, tt.wantErr, got, err)
229 }
230 })
231 }
232}
233
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700234func TestIntfIDFromPonPortNum(t *testing.T) {
235 type args struct {
236 portNum uint32
237 }
238
239 tests := []struct {
240 name string
241 args args
242 want uint32
243 wantErr error
244 }{
245 // TODO: Add test cases. min 16777216, max 33554432
246 {"IntfIDFromPonPortNum-02", args{portNum: 9090}, 0, status.Errorf(codes.InvalidArgument, "pon-port-number-out-of-range:%d", 9090)},
247 {"IntfIDFromPonPortNum-03", args{portNum: 0}, 0, status.Errorf(codes.InvalidArgument, "pon-port-number-out-of-range:%d", 0)},
248 {"IntfIDFromPonPortNum-04", args{portNum: 65535}, 0, status.Errorf(codes.InvalidArgument, "pon-port-number-out-of-range:%d", 65535)},
249 {"IntfIDFromPonPortNum-05", args{portNum: 16777215}, 0, status.Errorf(codes.InvalidArgument, "pon-port-number-out-of-range:%d", 16777215)},
250 {"IntfIDFromPonPortNum-01", args{portNum: 536870911}, 0, status.Errorf(codes.InvalidArgument, "pon-port-number-out-of-range:%d", 536870911)},
251 {"IntfIDFromPonPortNum-06", args{portNum: 536870912}, 0, nil},
252 {"IntfIDFromPonPortNum-07", args{portNum: 536870913}, 1, nil},
253 {"IntfIDFromPonPortNum-08", args{portNum: 536870914}, 2, nil},
254 {"IntfIDFromPonPortNum-09", args{portNum: 536870915}, 3, nil},
255 {"IntfIDFromPonPortNum-10", args{portNum: 536871166}, 254, nil},
256 {"IntfIDFromPonPortNum-11", args{portNum: 536871167}, 255, nil},
257 {"IntfIDFromPonPortNum-12", args{portNum: 536871168}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 536871168)},
258 }
259 for _, tt := range tests {
260 t.Run(tt.name, func(t *testing.T) {
261 got, err := IntfIDFromPonPortNum(context.Background(), tt.args.portNum)
262 if got != tt.want {
263 t.Errorf("IntfIDFromPonPortNum(): FOR[%v] WANT[%v and %v] GOT[%v and %v]",
264 tt.args.portNum, tt.want, tt.wantErr, got, err)
265 }
266 })
267 }
268}
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700269func TestIntfIDToPortTypeName(t *testing.T) {
270 type args struct {
271 intfID uint32
272 }
273 input := uint32(2*math.Pow(2, 28)) | 3
274 tests := []struct {
275 name string
276 args args
277 want voltha.Port_PortType
278 }{
279 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700280 {"IntfIDToPortTypeName-1", args{intfID: 16777216}, voltha.Port_ETHERNET_NNI},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700281 {"IntfIDToPortTypeName-2", args{intfID: 1000}, voltha.Port_ETHERNET_UNI},
282 {"IntfIDToPortTypeName-2", args{intfID: input}, voltha.Port_PON_OLT},
283 }
284 for _, tt := range tests {
285 t.Run(tt.name, func(t *testing.T) {
286 if got := IntfIDToPortTypeName(tt.args.intfID); !reflect.DeepEqual(got, tt.want) {
287 t.Errorf("IntfIDToPortTypeName() = %v, want %v", got, tt.want)
288 }
289 })
290 }
291}
292
293func TestExtractAccessFromFlow(t *testing.T) {
294 type args struct {
295 inPort uint32
296 outPort uint32
297 }
298 tests := []struct {
299 name string
300 args args
301 port uint32
302 IntfID uint32
303 onuID uint32
304 uniID uint32
305 }{
306 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700307 {"ExtractAccessFromFlow-1", args{inPort: 1540, outPort: 16777216}, 1540, 0, 6, 4},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700308 {"ExtractAccessFromFlow-2", args{inPort: 1048576, outPort: 10}, 10, 0, 0, 10},
309 }
310 for _, tt := range tests {
311 t.Run(tt.name, func(t *testing.T) {
312 got, got1, got2, got3 := ExtractAccessFromFlow(tt.args.inPort, tt.args.outPort)
313 if got != tt.port {
314 t.Errorf("ExtractAccessFromFlow() got = %v, want %v", got, tt.port)
315 }
316 if got1 != tt.IntfID {
317 t.Errorf("ExtractAccessFromFlow() got1 = %v, want %v", got1, tt.IntfID)
318 }
319 if got2 != tt.onuID {
320 t.Errorf("ExtractAccessFromFlow() got2 = %v, want %v", got2, tt.onuID)
321 }
322 if got3 != tt.uniID {
323 t.Errorf("ExtractAccessFromFlow() got3 = %v, want %v", got3, tt.uniID)
324 }
325 })
326 }
327 //t.Error()
328}
329
330func TestIsUpstream(t *testing.T) {
331 type args struct {
332 outPort uint32
333 }
334 tests := []struct {
335 name string
336 args args
337 want bool
338 }{
339 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700340 {"TestIsUpstream-1", args{outPort: 2147483645}, true}, //controller bound
341 {"TestIsUpstream-2", args{outPort: 16777215}, false},
342 {"TestIsUpstream-3", args{outPort: 16777216}, true},
343 {"TestIsUpstream-4", args{outPort: 16777217}, true},
344 {"TestIsUpstream-5", args{outPort: 33554431}, true},
345 {"TestIsUpstream-6", args{outPort: 33554432}, false},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700346 }
347 for _, tt := range tests {
348 t.Run(tt.name, func(t *testing.T) {
349 if got := IsUpstream(tt.args.outPort); got != tt.want {
350 t.Errorf("IsUpstream() = %v, want %v", got, tt.want)
351 }
352 })
353 }
354}
355
356func TestIsControllerBoundFlow(t *testing.T) {
357 type args struct {
358 outPort uint32
359 }
360 tests := []struct {
361 name string
362 args args
363 want bool
364 }{
365 // TODO: Add test cases.
Mahir Gunyela8ab55f2021-10-20 15:07:25 -0700366 {"IsControllerBoundFlow-1", args{outPort: 2147483645}, true},
367 {"IsControllerBoundFlow-2", args{outPort: 2147483646}, false},
368 {"IsControllerBoundFlow-3", args{outPort: 4294967293}, true},
369 {"IsControllerBoundFlow-4", args{outPort: 4294967294}, false},
Mahir Gunyel2c4b96b2021-09-13 17:01:05 -0700370 {"IsControllerBoundFlow-5", args{outPort: 65539}, false},
371 {"IsControllerBoundFlow-6", args{outPort: 1000}, false},
372 }
373 for _, tt := range tests {
374 t.Run(tt.name, func(t *testing.T) {
375 if got := IsControllerBoundFlow(tt.args.outPort); got != tt.want {
376 t.Errorf("IsControllerBoundFlow() = %v, want %v", got, tt.want)
377 }
378 })
379 }
380}
381
382func TestFlowExtractInfo(t *testing.T) {
383 fa := &fu.FlowArgs{
384 MatchFields: []*ofp.OfpOxmOfbField{
385 fu.InPort(2),
386 fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2)),
387 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
388 fu.EthType(2048),
389 },
390
391 Actions: []*ofp.OfpAction{
392 fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA))),
393 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
394 fu.Output(1),
395 },
396 }
397 ofpstats, _ := fu.MkFlowStat(fa)
398 type args struct {
399 flow *ofp.OfpFlowStats
400 flowDirection string
401 }
402 tests := []struct {
403 name string
404 args args
405 want uint32
406 want1 uint32
407 want2 uint32
408 want3 uint32
409 want4 uint32
410 want5 uint32
411 wantErr bool
412 }{
413 // TODO: Add test cases.
414 {"FlowExtractInfo-1", args{flow: ofpstats, flowDirection: "upstream"}, 2, 0, 0, 2, 0, 0, false},
415
416 // Negative Testcases
417 {"FlowExtractInfo-2", args{flow: ofpstats, flowDirection: "downstream"}, 1, 0, 0, 1, 2, 2048, false},
418 {"FlowExtractInfo-3", args{flow: nil, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
419 {"FlowExtractInfo-4", args{flow: &ofp.OfpFlowStats{}, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
420 }
421 for _, tt := range tests {
422 t.Run(tt.name, func(t *testing.T) {
423 got, got1, got2, got3, got4, got5, err := FlowExtractInfo(context.Background(), tt.args.flow, tt.args.flowDirection)
424 if (err != nil) != tt.wantErr {
425 t.Errorf("FlowExtractInfo() error = %v, wantErr %v", err, tt.wantErr)
426 return
427 }
428 if got != tt.want {
429 t.Errorf("FlowExtractInfo() got = %v, want %v", got, tt.want)
430 return
431 }
432 if got1 != tt.want1 {
433 t.Errorf("FlowExtractInfo() got1 = %v, want %v", got1, tt.want1)
434 return
435 }
436 if got2 != tt.want2 {
437 t.Errorf("FlowExtractInfo() got2 = %v, want %v", got2, tt.want2)
438 return
439 }
440 if got3 != tt.want3 {
441 t.Errorf("FlowExtractInfo() got3 = %v, want %v", got3, tt.want3)
442 return
443 }
444 if got4 != tt.want4 {
445 t.Errorf("FlowExtractInfo() got4 = %v, want %v", got4, tt.want4)
446 return
447 }
448 if got5 != tt.want5 {
449 t.Errorf("FlowExtractInfo() got5 = %v, want %v", got5, tt.want5)
450 return
451 }
452 })
453 }
454}