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