blob: 6751416ffb3b1f32820431d7a71eb262e0097c1b [file] [log] [blame]
Akash Sonid36d23b2023-08-18 12:51:40 +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 controller
17
18import (
19 "context"
20 "reflect"
21 "testing"
22 "voltha-go-controller/internal/pkg/holder"
23 "voltha-go-controller/internal/pkg/of"
24 "voltha-go-controller/internal/test/mocks"
25
Akash Sonid36d23b2023-08-18 12:51:40 +053026 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
27 "github.com/stretchr/testify/assert"
bseenivadd66c362026-02-12 19:13:26 +053028 "go.uber.org/mock/gomock"
Akash Sonid36d23b2023-08-18 12:51:40 +053029)
30
31func TestNewDevicePort(t *testing.T) {
32 type args struct {
33 mp *ofp.OfpPort
34 }
35 tests := []struct {
36 name string
37 args args
38 want *DevicePort
39 }{
40 {
41 name: "NewDevicePort",
42 args: args{
43 mp: &ofp.OfpPort{
44 PortNo: uint32(1),
45 },
46 },
47 },
48 }
49 for _, tt := range tests {
50 t.Run(tt.name, func(t *testing.T) {
51 got := NewDevicePort(tt.args.mp)
52 assert.NotNil(t, got)
53 })
54 }
55}
56
57func TestDevice_UpdateFlows(t *testing.T) {
58 type args struct {
59 flow *of.VoltFlow
60 devPort *DevicePort
61 }
62 tests := []struct {
63 name string
64 args args
65 }{
66 {
67 name: "Device_UpdateFlows",
68 args: args{
69 flow: &of.VoltFlow{
70 PortName: "test_port_name",
71 },
72 devPort: &DevicePort{
73 Name: "test_name",
74 },
75 },
76 },
77 }
78 for _, tt := range tests {
79 flushQueue := make(map[uint32]*UniIDFlowQueue)
80 flushQueue[uint32(1)] = &UniIDFlowQueue{
81 ID: uint32(1),
82 }
83 t.Run(tt.name, func(t *testing.T) {
84 d := &Device{
85 flowQueue: flushQueue,
86 flowHash: uint32(1),
87 }
88 d.UpdateFlows(tt.args.flow, tt.args.devPort)
89 })
90 }
91}
92
93func TestNewDevice(t *testing.T) {
94 type args struct {
95 cntx context.Context
96 id string
97 slno string
98 vclientHldr *holder.VolthaServiceClientHolder
99 southBoundID string
100 mfr string
101 hwDesc string
102 swDesc string
103 }
104 tests := []struct {
105 name string
106 args args
107 want *Device
108 }{
109 {
110 name: "TestNewDevice",
111 args: args{
112 cntx: context.Background(),
113 id: "test_id",
114 slno: "test_sl_no",
115 },
116 },
117 }
118 for _, tt := range tests {
119 t.Run(tt.name, func(t *testing.T) {
120 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
121 db = dbintf
122 dbintf.EXPECT().GetFlowHash(gomock.Any(), gomock.Any()).Return("1", nil).Times(1)
123 got := NewDevice(tt.args.cntx, tt.args.id, tt.args.slno, tt.args.vclientHldr, tt.args.southBoundID, tt.args.mfr, tt.args.hwDesc, tt.args.swDesc)
124 assert.NotNil(t, got)
125 })
126 }
127}
128
129func TestDevice_triggerFlowResultNotification(t *testing.T) {
130 type args struct {
131 cntx context.Context
132 cookie uint64
133 flow *of.VoltSubFlow
134 oper of.Command
135 bwDetails of.BwAvailDetails
136 err error
137 }
138 tests := []struct {
139 name string
140 args args
141 }{
142 {
143 name: "Device_triggerFlowResultNotification",
144 args: args{
145 cntx: context.Background(),
146 cookie: uint64(1),
147 flow: &of.VoltSubFlow{
148 Cookie: uint64(1),
149 },
150 oper: of.CommandAdd,
151 bwDetails: of.BwAvailDetails{
152 PrevBw: "test_prev_bw",
153 },
154 err: nil,
155 },
156 },
157 }
158 for _, tt := range tests {
159 t.Run(tt.name, func(t *testing.T) {
160 flows := make(map[uint64]*of.VoltSubFlow)
161 flows[uint64(1)] = &of.VoltSubFlow{
162 Cookie: uint64(1),
163 }
164 d := &Device{
165 flows: flows,
166 }
167 appMock := mocks.NewMockApp(gomock.NewController(t))
168 _ = NewController(context.Background(), appMock)
169 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
170 db = dbintf
bseenivadd66c362026-02-12 19:13:26 +0530171 // Background goroutines can update groups; allow such calls
172 // to prevent gomock from failing after the test completes.
173 dbintf.EXPECT().PutGroup(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
Akash Sonid36d23b2023-08-18 12:51:40 +0530174 appMock.EXPECT().ProcessFlowModResultIndication(gomock.Any(), gomock.Any()).Times(1)
Akash Sonief452f12024-12-12 18:20:28 +0530175 d.triggerFlowResultNotification(tt.args.cntx, tt.args.cookie, tt.args.flow, tt.args.oper, tt.args.bwDetails, tt.args.err)
Akash Sonid36d23b2023-08-18 12:51:40 +0530176 })
177 }
178}
179
180func TestDevice_ResetCache(t *testing.T) {
181 tests := []struct {
182 name string
183 }{
184 {
185 name: "Device_ResetCache",
186 },
187 }
188 for _, tt := range tests {
189 t.Run(tt.name, func(t *testing.T) {
190 d := &Device{}
191 d.ResetCache()
192 })
193 }
194}
195
196func TestDevice_GetAllFlows(t *testing.T) {
197 tests := []struct {
198 name string
199 want []*of.VoltSubFlow
200 }{
201 {
202 name: "Device_GetAllFlows",
203 },
204 }
205 for _, tt := range tests {
206 t.Run(tt.name, func(t *testing.T) {
207 d := &Device{}
208 if got := d.GetAllFlows(); !reflect.DeepEqual(got, tt.want) {
209 t.Errorf("Device.GetAllFlows() = %v, want %v", got, tt.want)
210 }
211 })
212 }
213}
Akash Soni6f369452023-09-19 11:18:28 +0530214
215func TestDevice_PacketOutReq(t *testing.T) {
216 type args struct {
217 outport string
218 inport string
219 data []byte
220 isCustomPkt bool
221 }
222 tests := []struct {
223 name string
224 args args
225 wantErr bool
226 }{
227 {
228 name: "Device_PacketOutReq",
229 args: args{
230 outport: "test_out_port",
231 inport: "test_in_port",
232 },
233 },
234 }
235 for _, tt := range tests {
236 t.Run(tt.name, func(t *testing.T) {
237 portByName := make(map[string]*DevicePort)
238 portByName["test_in_port"] = &DevicePort{
239 Name: "test_device",
240 }
241 portByName["test_out_port"] = &DevicePort{
242 Name: "test_device",
243 }
244 packetOutChannel := make(chan *ofp.PacketOut, 2)
245
246 d := &Device{
247 packetOutChannel: packetOutChannel,
248 PortsByName: portByName,
249 }
250 if err := d.PacketOutReq(tt.args.outport, tt.args.inport, tt.args.data, tt.args.isCustomPkt); (err != nil) != tt.wantErr {
251 t.Errorf("Device.PacketOutReq() error = %v, wantErr %v", err, tt.wantErr)
252 }
253 })
254 }
255}
256
257func TestDevice_SetFlowHash(t *testing.T) {
258 type args struct {
259 cntx context.Context
260 hash uint32
261 }
262 tests := []struct {
263 name string
264 args args
265 }{
266 {
267 name: "Device_SetFlowHash",
268 args: args{
269 cntx: context.Background(),
270 hash: uint32(2),
271 },
272 },
273 }
274 for _, tt := range tests {
275 t.Run(tt.name, func(t *testing.T) {
276 d := &Device{}
277 dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
278 db = dbintf
bseenivadd66c362026-02-12 19:13:26 +0530279 // Expect flow-hash to be written once for this test.
Akash Soni6f369452023-09-19 11:18:28 +0530280 dbintf.EXPECT().PutFlowHash(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
bseenivadd66c362026-02-12 19:13:26 +0530281 // Background goroutines from other tests may update groups;
282 // allow such calls to be no-ops to prevent gomock from failing
283 // after this test completes.
284 dbintf.EXPECT().PutGroup(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
Akash Soni6f369452023-09-19 11:18:28 +0530285 d.SetFlowHash(tt.args.cntx, tt.args.hash)
286 })
287 }
288}