blob: 1c346aae167c98a7bcee717c51b2ae8e7a91832a [file] [log] [blame]
vinokumaf7605fc2023-06-02 18:08:01 +05301/*
2* Copyright 2022-present Open Networking Foundation
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14 */
15
16package application
17
18import (
Akash Soni6f369452023-09-19 11:18:28 +053019 "context"
Akash Soni9fad7362023-10-03 12:19:37 +053020 "errors"
Akash Soni6f369452023-09-19 11:18:28 +053021 "net"
Akash Soni9fad7362023-10-03 12:19:37 +053022 "sync"
vinokumaf7605fc2023-06-02 18:08:01 +053023 "testing"
Akash Soni6f369452023-09-19 11:18:28 +053024 "time"
25 "voltha-go-controller/internal/pkg/of"
26 common "voltha-go-controller/internal/pkg/types"
27 "voltha-go-controller/internal/test/mocks"
28
29 "github.com/golang/mock/gomock"
30 "github.com/google/gopacket/layers"
31 "github.com/stretchr/testify/assert"
vinokumaf7605fc2023-06-02 18:08:01 +053032)
33
34func TestVoltApplication_InitIgmpSrcMac(t *testing.T) {
35 tests := []struct {
36 name string
37 }{
38 {
39 name: "test",
40 },
41 }
42 for _, tt := range tests {
43 t.Run(tt.name, func(t *testing.T) {
44 va := &VoltApplication{}
45 va.InitIgmpSrcMac()
46 })
47 }
48}
Akash Soni6f369452023-09-19 11:18:28 +053049
50func TestVoltApplication_UpdateIgmpProfile(t *testing.T) {
51 type args struct {
52 cntx context.Context
53 igmpProfileConfig *common.IGMPConfig
54 }
55 igmpConfig := &common.IGMPConfig{
56 ProfileID: "test_profile_id",
57 FastLeave: &vgcRebooted,
58 PeriodicQuery: &isUpgradeComplete,
59 WithRAUpLink: &isUpgradeComplete,
60 WithRADownLink: &isUpgradeComplete,
61 }
62 igmpProfile_data := &IgmpProfile{
63 ProfileID: "test_profile_id",
64 }
65
66 tests := []struct {
67 name string
68 args args
69 wantErr bool
70 }{
71 {
72 name: "UpdateIgmpProfile",
73 args: args{
74 cntx: context.Background(),
75 igmpProfileConfig: igmpConfig,
76 },
77 },
78 {
79 name: "UpdateIgmpProfile_Profile_not_found",
80 args: args{
81 cntx: context.Background(),
82 igmpProfileConfig: igmpConfig,
83 },
84 wantErr: true,
85 },
86 }
87 for _, tt := range tests {
88 t.Run(tt.name, func(t *testing.T) {
89 va := &VoltApplication{}
90 switch tt.name {
91 case "UpdateIgmpProfile":
92 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
93 db = dbintf
94 dbintf.EXPECT().PutIgmpProfile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
95 va.IgmpProfilesByName.Store("test_profile_id", igmpProfile_data)
96 if err := va.UpdateIgmpProfile(tt.args.cntx, tt.args.igmpProfileConfig); (err != nil) != tt.wantErr {
97 t.Errorf("VoltApplication.UpdateIgmpProfile() error = %v, wantErr %v", err, tt.wantErr)
98 }
99 case "UpdateIgmpProfile_Profile_not_found":
100 igmpConfig.ProfileID = ""
101 if err := va.UpdateIgmpProfile(tt.args.cntx, tt.args.igmpProfileConfig); (err != nil) != tt.wantErr {
102 t.Errorf("VoltApplication.UpdateIgmpProfile() error = %v, wantErr %v", err, tt.wantErr)
103 }
104 }
105 })
106 }
107}
108
109func TestVoltApplication_resetIgmpProfileToDefault(t *testing.T) {
110 type args struct {
111 cntx context.Context
112 }
113 igmpProfile_data := &IgmpProfile{
114 ProfileID: "test_profile_id",
115 }
116 tests := []struct {
117 name string
118 args args
119 }{
120 {
121 name: "resetIgmpProfileToDefault",
122 args: args{
123 cntx: context.Background(),
124 },
125 },
126 }
127 for _, tt := range tests {
128 t.Run(tt.name, func(t *testing.T) {
129 va := &VoltApplication{}
130 va.IgmpProfilesByName.Store("", igmpProfile_data)
131 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
132 db = dbintf
133 dbintf.EXPECT().PutIgmpProfile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
134 va.resetIgmpProfileToDefault(tt.args.cntx)
135 })
136 }
137}
138
139func Test_ipv4ToUint(t *testing.T) {
140 type args struct {
141 ip net.IP
142 }
143 tests := []struct {
144 name string
145 args args
146 want uint32
147 }{
148 {
149 name: "ipv4ToUint",
150 args: args{
151 ip: AllSystemsMulticastGroupIP,
152 },
153 want: 3758096385,
154 },
155 {
156 name: "ipv4ToUint",
157 args: args{
158 ip: nil,
159 },
160 },
161 }
162 for _, tt := range tests {
163 t.Run(tt.name, func(t *testing.T) {
164 if got := ipv4ToUint(tt.args.ip); got != tt.want {
165 t.Errorf("ipv4ToUint() = %v, want %v", got, tt.want)
166 }
167 })
168 }
169}
170
171func TestIgmpUsEthLayer(t *testing.T) {
172 type args struct {
173 mcip net.IP
174 }
175 tests := []struct {
176 name string
177 args args
178 want *layers.Ethernet
179 }{
180 {
181 name: "IgmpUsEthLayer",
182 args: args{
183 mcip: AllSystemsMulticastGroupIP,
184 },
185 want: &layers.Ethernet{},
186 },
187 }
188 for _, tt := range tests {
189 t.Run(tt.name, func(t *testing.T) {
190 got := IgmpUsEthLayer(tt.args.mcip)
191 assert.NotNil(t, got)
192 })
193 }
194}
195
196func TestIgmpUsDot1qLayer(t *testing.T) {
197 type args struct {
198 vlan of.VlanType
199 priority uint8
200 }
201 tests := []struct {
202 name string
203 args args
204 want *layers.Dot1Q
205 }{
206 {
207 name: "IgmpUsDot1qLayer",
208 args: args{
209 vlan: of.VlanAny,
210 priority: 0,
211 },
212 want: &layers.Dot1Q{},
213 },
214 {
215 name: "IgmpDsDot1qLayer",
216 args: args{
217 vlan: of.VlanAny,
218 priority: 0,
219 },
220 want: &layers.Dot1Q{},
221 },
222 }
223 for _, tt := range tests {
224 t.Run(tt.name, func(t *testing.T) {
225 switch tt.name {
226 case "IgmpUsDot1qLayer":
227 got := IgmpUsDot1qLayer(tt.args.vlan, tt.args.priority)
228 assert.NotNil(t, got)
229 case "IgmpDsDot1qLayer":
230 got := IgmpDsDot1qLayer(tt.args.vlan, tt.args.priority)
231 assert.NotNil(t, got)
232 }
233 })
234 }
235}
236
237func TestIgmpv2UsIpv4Layer(t *testing.T) {
238 type args struct {
239 src net.IP
240 mcip net.IP
241 }
242 tests := []struct {
243 name string
244 args args
245 want *layers.IPv4
246 }{
247 {
248 name: "Igmpv2UsIpv4Layer",
249 args: args{
250 src: AllSystemsMulticastGroupIP,
251 mcip: AllSystemsMulticastGroupIP,
252 },
253 want: &layers.IPv4{},
254 },
255 {
256 name: "IgmpDsIpv4Layer",
257 args: args{
258 src: AllSystemsMulticastGroupIP,
259 mcip: net.ParseIP("0.0.0.0"),
260 },
261 want: &layers.IPv4{},
262 },
263 }
264 for _, tt := range tests {
265 t.Run(tt.name, func(t *testing.T) {
266 switch tt.name {
267 case "Igmpv2UsIpv4Layer":
268 got := Igmpv2UsIpv4Layer(tt.args.src, tt.args.mcip)
269 assert.NotNil(t, got)
270 case "IgmpDsIpv4Layer":
271 got := IgmpDsIpv4Layer(tt.args.src, tt.args.mcip)
272 assert.NotNil(t, got)
273 }
274 })
275 }
276}
277
278func TestIgmpv3UsIpv4Layer(t *testing.T) {
279 type args struct {
280 src net.IP
281 }
282 tests := []struct {
283 name string
284 args args
285 want *layers.IPv4
286 }{
287 {
288 name: "Igmpv3UsIpv4Layer",
289 args: args{
290 src: AllSystemsMulticastGroupIP,
291 },
292 want: &layers.IPv4{},
293 },
294 }
295 for _, tt := range tests {
296 t.Run(tt.name, func(t *testing.T) {
297 got := Igmpv3UsIpv4Layer(tt.args.src)
298 assert.NotNil(t, got)
299 })
300 }
301}
302
303func TestIgmpDsEthLayer(t *testing.T) {
304 type args struct {
305 mcip net.IP
306 }
307 tests := []struct {
308 name string
309 args args
310 want *layers.Ethernet
311 }{
312 {
313 name: "IgmpDsEthLayer",
314 args: args{
315 mcip: AllSystemsMulticastGroupIP,
316 },
317 want: &layers.Ethernet{},
318 },
319 }
320 for _, tt := range tests {
321 t.Run(tt.name, func(t *testing.T) {
322 got := IgmpDsEthLayer(tt.args.mcip)
323 assert.NotNil(t, got)
324 })
325 }
326}
327
328func TestIgmpQueryv2Layer(t *testing.T) {
329 type args struct {
330 mcip net.IP
331 resptime time.Duration
332 }
333 tests := []struct {
334 name string
335 args args
336 want *layers.IGMPv1or2
337 }{
338 {
339 name: "IgmpQueryv2Laye",
340 args: args{
341 mcip: AllSystemsMulticastGroupIP,
342 resptime: time.Microsecond,
343 },
344 want: &layers.IGMPv1or2{},
345 },
346 }
347 for _, tt := range tests {
348 t.Run(tt.name, func(t *testing.T) {
349 got := IgmpQueryv2Layer(tt.args.mcip, tt.args.resptime)
350 assert.NotNil(t, got)
351 })
352 }
353}
354
355func TestIgmpQueryv3Layer(t *testing.T) {
356 type args struct {
357 mcip net.IP
358 resptime time.Duration
359 }
360 tests := []struct {
361 name string
362 args args
363 want *layers.IGMP
364 }{
365 {
366 name: "IgmpQueryv3Layer",
367 args: args{
368 mcip: AllSystemsMulticastGroupIP,
369 resptime: time.Microsecond,
370 },
371 want: &layers.IGMP{},
372 },
373 }
374 for _, tt := range tests {
375 t.Run(tt.name, func(t *testing.T) {
376 got := IgmpQueryv3Layer(tt.args.mcip, tt.args.resptime)
377 assert.NotNil(t, got)
378 })
379 }
380}
381
382func TestIgmpReportv2Layer(t *testing.T) {
383 type args struct {
384 mcip net.IP
385 }
386 tests := []struct {
387 name string
388 args args
389 want *layers.IGMPv1or2
390 }{
391 {
392 name: "IgmpReportv2Layer",
393 args: args{
394 mcip: AllSystemsMulticastGroupIP,
395 },
396 want: &layers.IGMPv1or2{},
397 },
398 {
399 name: "IgmpLeavev2Layer",
400 args: args{
401 mcip: AllSystemsMulticastGroupIP,
402 },
403 want: &layers.IGMPv1or2{},
404 },
405 }
406 for _, tt := range tests {
407 t.Run(tt.name, func(t *testing.T) {
408 switch tt.name {
409 case "IgmpReportv2Layer":
410 got := IgmpReportv2Layer(tt.args.mcip)
411 assert.NotNil(t, got)
412 case "IgmpLeavev2Layer":
413 got := IgmpLeavev2Layer(tt.args.mcip)
414 assert.NotNil(t, got)
415 }
416 })
417 }
418}
419
420func TestIgmpReportv3Layer(t *testing.T) {
421 type args struct {
422 mcip net.IP
423 incl bool
424 srclist []net.IP
425 }
426 tests := []struct {
427 name string
428 args args
429 want *layers.IGMP
430 }{
431 {
432 name: "IgmpReportv3Layer",
433 args: args{
434 mcip: AllSystemsMulticastGroupIP,
435 incl: true,
436 },
437 want: &layers.IGMP{},
438 },
439 }
440 for _, tt := range tests {
441 t.Run(tt.name, func(t *testing.T) {
442 got := IgmpReportv3Layer(tt.args.mcip, tt.args.incl, tt.args.srclist)
443 assert.NotNil(t, got)
444 })
445 }
446}
447
Akash Soni6f369452023-09-19 11:18:28 +0530448func Test_getVersion(t *testing.T) {
449 type args struct {
450 ver string
451 }
452 tests := []struct {
453 name string
454 args args
455 want uint8
456 }{
457 {
458 name: "getVersion_IgmpVersion2",
459 args: args{
460 ver: "2",
461 },
462 want: IgmpVersion2,
463 },
464 {
465 name: "getVersion_IgmpVersion2",
466 args: args{
467 ver: "0",
468 },
469 want: IgmpVersion3,
470 },
471 }
472 for _, tt := range tests {
473 t.Run(tt.name, func(t *testing.T) {
474 if got := getVersion(tt.args.ver); got != tt.want {
475 t.Errorf("getVersion() = %v, want %v", got, tt.want)
476 }
477 })
478 }
479}
480
481func TestIsIPPresent(t *testing.T) {
482 type args struct {
483 i net.IP
484 ips []net.IP
485 }
486 ips := []net.IP{}
487 ips = append(ips, AllSystemsMulticastGroupIP)
488 tests := []struct {
489 name string
490 args args
491 want bool
492 }{
493 {
494 name: "TestIsIPPresent_True",
495 args: args{
496 i: AllSystemsMulticastGroupIP,
497 ips: ips,
498 },
499 want: true,
500 },
501 {
502 name: "TestIsIPPresent_False",
503 args: args{
504 ips: ips,
505 },
506 want: false,
507 },
508 }
509 for _, tt := range tests {
510 t.Run(tt.name, func(t *testing.T) {
511 if got := IsIPPresent(tt.args.i, tt.args.ips); got != tt.want {
512 t.Errorf("IsIPPresent() = %v, want %v", got, tt.want)
513 }
514 })
515 }
516}
Akash Soni9fad7362023-10-03 12:19:37 +0530517
518func TestAddToPendingPool(t *testing.T) {
519 type args struct {
520 cntx context.Context
521 device string
522 groupKey string
523 }
524
525 group := &IgmpGroup{
526 GroupName: "test_key",
527 GroupID: uint32(256),
528 PendingGroupForDevice: make(map[string]time.Time),
529 }
530 tests := []struct {
531 name string
532 args args
533 want bool
534 }{
535 {
536 name: "AddToPendingPool_true",
537 args: args{
538 device: "SDX6320031",
539 cntx: context.Background(),
540 groupKey: "test_key",
541 },
542 want: true,
543 },
544 {
545 name: "AddToPendingPool_false",
546 args: args{
547 device: "SDX6320031",
548 cntx: context.Background(),
549 groupKey: "test_key",
550 },
551 want: true,
552 },
553 }
554 for _, tt := range tests {
555 t.Run(tt.name, func(t *testing.T) {
556 switch tt.name {
557 case "AddToPendingPool_true":
558 va := GetApplication()
559 va.IgmpGroups.Store("test_key", group)
560 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
561 db = dbintf
562 dbintf.EXPECT().PutIgmpGroup(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
563 if got := AddToPendingPool(tt.args.cntx, tt.args.device, tt.args.groupKey); got != tt.want {
564 t.Errorf("AddToPendingPool() = %v, want %v", got, tt.want)
565 }
566 case "AddToPendingPool_false":
567 va := GetApplication()
568 va.IgmpGroups.Store("test_key", group)
569 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
570 db = dbintf
571 dbintf.EXPECT().PutIgmpGroup(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("failed")).Times(1)
572 if got := AddToPendingPool(tt.args.cntx, tt.args.device, tt.args.groupKey); got != tt.want {
573 t.Errorf("AddToPendingPool() = %v, want %v", got, tt.want)
574 }
575 }
576 })
577 }
578}
579
580func TestGetMcastServiceForSubAlarm(t *testing.T) {
581 type args struct {
582 uniPort *VoltPort
583 mvp *MvlanProfile
584 }
585 mvp := &MvlanProfile{
586 Name: "mvlan_test",
587 }
588 voltPort := &VoltPort{
589 Name: "16777472",
590 Device: "SDX6320031",
591 ID: 16777472,
592 State: PortStateUp,
593 }
594 voltServ := &VoltService{
595 VoltServiceOper: VoltServiceOper{
596 Device: "SDX6320031",
597 },
598 VoltServiceCfg: VoltServiceCfg{
599 IgmpEnabled: true,
600 MvlanProfileName: "mvlan_test",
601 Name: "SDX6320031-1_SDX6320031-1-4096-2310-4096-65",
602 },
603 }
604 voltPortVnets := make([]*VoltPortVnet, 0)
605 voltPortVnet := &VoltPortVnet{
606 Device: "SDX6320031",
607 Port: "16777472",
608 IgmpEnabled: true,
609 services: sync.Map{},
610 }
611 tests := []struct {
612 name string
613 args args
614 want string
615 }{
616 {
617 name: "GetMcastServiceForSubAlarm",
618 args: args{
619 uniPort: voltPort,
620 mvp: mvp,
621 },
622 want: "SDX6320031-1_SDX6320031-1-4096-2310-4096-65",
623 },
624 }
625 for _, tt := range tests {
626 t.Run(tt.name, func(t *testing.T) {
627 switch tt.name {
628 case "GetMcastServiceForSubAlarm":
629 va := GetApplication()
630 voltPortVnets = append(voltPortVnets, voltPortVnet)
631 voltPortVnet.services.Store("SDX6320031-1_SDX6320031-1-4096-2310-4096-65", voltServ)
632 va.VnetsByPort.Store("16777472", voltPortVnets)
633 if got := GetMcastServiceForSubAlarm(tt.args.uniPort, tt.args.mvp); got != tt.want {
634 t.Errorf("GetMcastServiceForSubAlarm() = %v, want %v", got, tt.want)
635 }
636 }
637 })
638 }
639}
640
641func TestSendQueryExpiredEventGroupSpecific(t *testing.T) {
642 type args struct {
643 portKey string
644 igd *IgmpGroupDevice
645 igc *IgmpGroupChannel
646 }
647 mvp := &MvlanProfile{
648 Name: "mvlan_test",
649 }
650 voltServ := &VoltService{
651 VoltServiceOper: VoltServiceOper{
652 Device: "SDX6320031",
653 },
654 VoltServiceCfg: VoltServiceCfg{
655 IgmpEnabled: true,
656 MvlanProfileName: "mvlan_test",
657 Name: "SDX6320031-1_SDX6320031-1-4096-2310-4096-65",
658 },
659 }
660 voltPortVnets := make([]*VoltPortVnet, 0)
661 voltPortVnet := &VoltPortVnet{
662 Device: "SDX6320031",
663 Port: "16777472",
664 IgmpEnabled: true,
665 services: sync.Map{},
666 }
667 tests := []struct {
668 name string
669 args args
670 }{
671 {
672 name: "SendQueryExpiredEventGroupSpecific",
673 args: args{
674 portKey: "16777472",
675 igd: &IgmpGroupDevice{
676 Mvlan: of.VlanAny,
677 },
678 igc: &IgmpGroupChannel{},
679 },
680 },
681 }
682 for _, tt := range tests {
683 t.Run(tt.name, func(t *testing.T) {
684 va := GetApplication()
685 voltPortVnets = append(voltPortVnets, voltPortVnet)
686 voltPortVnet.services.Store("SDX6320031-1_SDX6320031-1-4096-2310-4096-65", voltServ)
687 va.VnetsByPort.Store("16777472", voltPortVnets)
688 va.MvlanProfilesByTag.Store(of.VlanAny, mvp)
689 SendQueryExpiredEventGroupSpecific(tt.args.portKey, tt.args.igd, tt.args.igc)
690 })
691 }
692}
693
694func TestVoltApplication_GetPonPortID(t *testing.T) {
695 type args struct {
696 device string
697 uniPortID string
698 }
699 tests := []struct {
700 name string
701 args args
702 want uint32
703 }{
704 {
705 name: "RestoreIgmpGroupsFromDb",
706 args: args{},
707 want: uint32(255),
708 },
709 }
710 for _, tt := range tests {
711 t.Run(tt.name, func(t *testing.T) {
712 va := &VoltApplication{}
713 if got := va.GetPonPortID(tt.args.device, tt.args.uniPortID); got != tt.want {
714 t.Errorf("VoltApplication.GetPonPortID() = %v, want %v", got, tt.want)
715 }
716 })
717 }
718}