blob: 906303cd8ff1b15fdd1ef01817e458affd2790b9 [file] [log] [blame]
Matteo Scandolo992a23e2021-02-04 15:35:04 -08001/*
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
17package devices
18
19import (
Elia Battistonfe017662022-01-05 11:43:16 +010020 "strconv"
21 "testing"
22
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080023 "github.com/google/gopacket"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080024 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
25 omcilib "github.com/opencord/bbsim/internal/common/omci"
Andrea Campanella10426e22021-10-15 17:58:04 +020026 "github.com/opencord/omci-lib-go/v2"
27 me "github.com/opencord/omci-lib-go/v2/generated"
David K. Bainbridgec415efe2021-08-19 13:05:21 +000028 "github.com/opencord/voltha-protos/v5/go/openolt"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080029 "gotest.tools/assert"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080030)
31
32var mockAttr = me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +010033 me.GemPortNetworkCtp_PortId: 0,
34 me.GemPortNetworkCtp_TContPointer: 0,
35 me.GemPortNetworkCtp_Direction: 0,
36 me.GemPortNetworkCtp_TrafficManagementPointerForUpstream: 0,
37 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: 0,
38 me.GemPortNetworkCtp_PriorityQueuePointerForDownStream: 0,
39 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForDownstream: 0,
40 me.GemPortNetworkCtp_EncryptionKeyRing: 0,
Matteo Scandolo992a23e2021-02-04 15:35:04 -080041}
42
43func makeOmciCreateRequest(t *testing.T) []byte {
44 omciReq := &omci.CreateRequest{
45 MeBasePacket: omci.MeBasePacket{
46 EntityClass: me.GemPortNetworkCtpClassID,
47 EntityInstance: 12,
48 },
49 Attributes: mockAttr,
50 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080051
Matteo Scandolo992a23e2021-02-04 15:35:04 -080052 omciPkt, err := omcilib.Serialize(omci.CreateRequestType, omciReq, 66)
53 if err != nil {
54 t.Fatal(err.Error())
55 }
56
57 omciPkt, _ = omcilib.HexEncode(omciPkt)
58
59 return omciPkt
60}
61
62func makeOmciSetRequest(t *testing.T) []byte {
63 omciReq := &omci.SetRequest{
64 MeBasePacket: omci.MeBasePacket{
65 EntityClass: me.GemPortNetworkCtpClassID,
66 EntityInstance: 12,
67 },
68 Attributes: mockAttr,
69 }
70 omciPkt, err := omcilib.Serialize(omci.SetRequestType, omciReq, 66)
71 if err != nil {
72 t.Fatal(err.Error())
73 }
74
75 omciPkt, _ = omcilib.HexEncode(omciPkt)
76
77 return omciPkt
78}
79
80func makeOmciDeleteRequest(t *testing.T) []byte {
81 omciReq := &omci.DeleteRequest{
82 MeBasePacket: omci.MeBasePacket{
83 EntityClass: me.GemPortNetworkCtpClassID,
84 EntityInstance: 12,
85 },
86 }
87 omciPkt, err := omcilib.Serialize(omci.DeleteRequestType, omciReq, 66)
88 if err != nil {
89 t.Fatal(err.Error())
90 }
91
92 omciPkt, _ = omcilib.HexEncode(omciPkt)
93
94 return omciPkt
95}
96
97func makeOmciMibResetRequest(t *testing.T) []byte {
98 omciReq := &omci.MibResetRequest{
99 MeBasePacket: omci.MeBasePacket{
100 EntityClass: me.OnuDataClassID,
101 },
102 }
103 omciPkt, err := omcilib.Serialize(omci.MibResetRequestType, omciReq, 66)
104 if err != nil {
105 t.Fatal(err.Error())
106 }
107
108 omciPkt, _ = omcilib.HexEncode(omciPkt)
109
110 return omciPkt
111}
112
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700113func makeOmciStartSoftwareDownloadRequest(t *testing.T) []byte {
114 omciReq := &omci.StartSoftwareDownloadRequest{
115 MeBasePacket: omci.MeBasePacket{
116 EntityClass: me.SoftwareImageClassID,
117 },
118 ImageSize: 31,
119 NumberOfCircuitPacks: 1,
120 WindowSize: 31,
121 CircuitPacks: []uint16{0},
122 }
123 omciPkt, err := omcilib.Serialize(omci.StartSoftwareDownloadRequestType, omciReq, 66)
124 if err != nil {
125 t.Fatal(err.Error())
126 }
127
128 omciPkt, _ = omcilib.HexEncode(omciPkt)
129
130 return omciPkt
131}
132
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800133func makeOmciEndSoftwareDownloadRequest(t *testing.T, imageSize uint32, imageCrc uint32) []byte {
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700134 omciReq := &omci.EndSoftwareDownloadRequest{
135 MeBasePacket: omci.MeBasePacket{
136 EntityClass: me.SoftwareImageClassID,
137 },
138 NumberOfInstances: 1,
139 ImageInstances: []uint16{0},
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800140 ImageSize: imageSize,
141 CRC32: imageCrc,
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700142 }
143 omciPkt, err := omcilib.Serialize(omci.EndSoftwareDownloadRequestType, omciReq, 66)
144 if err != nil {
145 t.Fatal(err.Error())
146 }
147
148 omciPkt, _ = omcilib.HexEncode(omciPkt)
149
150 return omciPkt
151}
152
153func makeOmciActivateSoftwareRequest(t *testing.T) []byte {
154 omciReq := &omci.ActivateSoftwareRequest{
155 MeBasePacket: omci.MeBasePacket{
156 EntityClass: me.SoftwareImageClassID,
157 },
158 }
159 omciPkt, err := omcilib.Serialize(omci.ActivateSoftwareRequestType, omciReq, 66)
160 if err != nil {
161 t.Fatal(err.Error())
162 }
163
164 omciPkt, _ = omcilib.HexEncode(omciPkt)
165
166 return omciPkt
167}
168
169func makeOmciCommitSoftwareRequest(t *testing.T) []byte {
170 omciReq := &omci.CommitSoftwareRequest{
171 MeBasePacket: omci.MeBasePacket{
172 EntityClass: me.SoftwareImageClassID,
173 },
174 }
175 omciPkt, err := omcilib.Serialize(omci.CommitSoftwareRequestType, omciReq, 66)
176 if err != nil {
177 t.Fatal(err.Error())
178 }
179
180 omciPkt, _ = omcilib.HexEncode(omciPkt)
181
182 return omciPkt
183}
184
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800185func makeOmciMessage(t *testing.T, onu *Onu, pkt []byte) bbsim.OmciMessage {
Matteo Scandolob5913142021-03-19 16:10:18 -0700186 omciPkt, omciMsg, err := omcilib.ParseOpenOltOmciPacket(pkt)
187 if err != nil {
188 t.Fatal(err.Error())
189 }
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800190 return bbsim.OmciMessage{
Matteo Scandolob5913142021-03-19 16:10:18 -0700191 OnuSN: onu.SerialNumber,
192 OnuID: onu.ID,
193 OmciPkt: omciPkt,
194 OmciMsg: omciMsg,
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800195 }
196}
197
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800198func omciBytesToMsg(t *testing.T, data []byte) (*omci.OMCI, *gopacket.Packet) {
199 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.NoCopy)
200 if packet == nil {
201 t.Fatal("could not decode rxMsg as OMCI")
202 }
203 omciLayer := packet.Layer(omci.LayerTypeOMCI)
204 if omciLayer == nil {
205 t.Fatal("could not decode omci layer")
206 }
207 omciMsg, ok := omciLayer.(*omci.OMCI)
208 if !ok {
209 t.Fatal("could not assign omci layer")
210 }
211 return omciMsg, &packet
212}
213
214func omciToCreateResponse(t *testing.T, omciPkt *gopacket.Packet) *omci.CreateResponse {
215 msgLayer := (*omciPkt).Layer(omci.LayerTypeCreateResponse)
216 if msgLayer == nil {
217 t.Fatal("omci Msg layer could not be detected for CreateResponse - handling of MibSyncChan stopped")
218 }
219 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
220 if !msgOk {
221 t.Fatal("omci Msg layer could not be assigned for CreateResponse - handling of MibSyncChan stopped")
222 }
223 return msgObj
224}
225
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800226func Test_MibDataSyncIncrease(t *testing.T) {
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700227 onu := createTestOnu()
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800228
229 assert.Equal(t, onu.MibDataSync, uint8(0))
230
231 stream := &mockStream{
232 Calls: make(map[int]*openolt.Indication),
233 }
234
235 // send a Create and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200236 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
237 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800238 assert.Equal(t, onu.MibDataSync, uint8(1))
239
240 // send a Set and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200241 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
242 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800243 assert.Equal(t, onu.MibDataSync, uint8(2))
244
245 // send a Delete and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200246 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
247 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800248 assert.Equal(t, onu.MibDataSync, uint8(3))
249
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700250 // Start software download
251 onu.InternalState.SetState(OnuStateEnabled)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200252 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciStartSoftwareDownloadRequest(t)), stream)
253 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700254 assert.Equal(t, onu.MibDataSync, uint8(4))
255
256 // End software download
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800257 onu.ImageSoftwareExpectedSections = 31
258 onu.ImageSoftwareReceivedSections = 31 // we fake that we have received all the download section we expect
259 onu.ImageSectionData = []byte{111, 114, 116, 116, 105, 116, 111, 114, 32, 113, 117, 105, 115, 46, 32, 86, 105, 118, 97, 109, 117, 115, 32, 110, 101, 99, 32, 108, 105, 98, 101}
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700260 onu.InternalState.SetState(OnuStateImageDownloadInProgress)
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800261 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 1523894119)), stream)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200262 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700263 assert.Equal(t, onu.MibDataSync, uint8(5))
264
265 // Activate software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200266 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciActivateSoftwareRequest(t)), stream)
267 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700268 assert.Equal(t, onu.MibDataSync, uint8(6))
269
270 // Commit software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200271 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCommitSoftwareRequest(t)), stream)
272 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700273 assert.Equal(t, onu.MibDataSync, uint8(7))
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800274}
275
276func Test_MibDataSyncReset(t *testing.T) {
277 onu := createMockOnu(1, 1)
278 onu.MibDataSync = 192
279 assert.Equal(t, onu.MibDataSync, uint8(192))
280
281 stream := &mockStream{
282 Calls: make(map[int]*openolt.Indication),
283 }
284
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700285 // create a GemPort and an AllocId for this ONU
286 onu.PonPort.storeGemPort(1024, onu.SerialNumber)
Girish Gowdra574834a2022-02-04 15:15:15 -0800287 onu.PonPort.storeAllocId(1024, 1024, 0x8001, 1024, onu.SerialNumber)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700288
289 // send a MibReset
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200290 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciMibResetRequest(t)), stream)
291 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700292
293 // check that MDS has reset to 0
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800294 assert.Equal(t, onu.MibDataSync, uint8(0))
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700295
296 // check that GemPort and AllocId have been removed
297 assert.Equal(t, len(onu.PonPort.AllocatedGemPorts), 0)
298 assert.Equal(t, len(onu.PonPort.AllocatedAllocIds), 0)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800299}
300
301func Test_MibDataSyncRotation(t *testing.T) {
302 onu := createMockOnu(1, 1)
303 onu.MibDataSync = 255
304 assert.Equal(t, onu.MibDataSync, uint8(255))
305
306 stream := &mockStream{
307 Calls: make(map[int]*openolt.Indication),
308 }
309
310 // send a request that increases the MDS, but once we're at 255 we should go back to 0 (8bit)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200311 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
312 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800313 assert.Equal(t, onu.MibDataSync, uint8(0))
314}
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800315
Elia Battistonfe017662022-01-05 11:43:16 +0100316func Test_MibDataSyncInvalidation(t *testing.T) {
317 onu := createMockOnu(1, 1)
318 onu.MibDataSync = 250
319 assert.Equal(t, onu.MibDataSync, uint8(250))
320
321 onu.InvalidateMibDataSync()
322
323 // check if the MDS has been changed
324 assert.Assert(t, onu.MibDataSync != uint8(250))
325
326 // the MDS has to be between 1 and 255, since 0 is valid for a reset
327 assert.Assert(t, onu.MibDataSync > 0)
Girish Gowdra574834a2022-02-04 15:15:15 -0800328 // assert.Assert(t, onu.MibDataSync <= 255) // This is always true since 'MibDataSync' is uint8
Elia Battistonfe017662022-01-05 11:43:16 +0100329}
330
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800331func Test_GemPortValidation(t *testing.T) {
332
333 // setup
334 onu := createMockOnu(1, 1)
335
336 stream := &mockStream{
337 Calls: make(map[int]*openolt.Indication),
338 }
339
340 // create a gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200341 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
342 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800343
344 // the first time we created the gemPort
345 // the MDS should be incremented
346 assert.Equal(t, stream.CallCount, 1)
347 assert.Equal(t, onu.MibDataSync, uint8(1))
348
349 // and the OMCI response status should be me.Success
350 indication := stream.Calls[1].GetOmciInd()
351 _, omciPkt := omciBytesToMsg(t, indication.Pkt)
352 responseLayer := omciToCreateResponse(t, omciPkt)
353 assert.Equal(t, responseLayer.Result, me.Success)
354
355 // send a request to create the same gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200356 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
357 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800358
359 // this time the MDS should not be incremented
360 assert.Equal(t, stream.CallCount, 2)
361 assert.Equal(t, onu.MibDataSync, uint8(1))
362
363 // and the OMCI response status should be me.ProcessingError
364 _, omciPkt = omciBytesToMsg(t, stream.Calls[2].GetOmciInd().Pkt)
365 responseLayer = omciToCreateResponse(t, omciPkt)
366 assert.Equal(t, responseLayer.Result, me.ProcessingError)
367}
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000368
369func Test_OmciResponseRate(t *testing.T) {
370
371 onu := createMockOnu(1, 1)
372
373 for onu.OmciResponseRate = 0; onu.OmciResponseRate <= maxOmciMsgCounter; onu.OmciResponseRate++ {
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000374 stream := &mockStream{
375 Calls: make(map[int]*openolt.Indication),
376 }
377 //send ten OMCI requests and check if number of responses is only equal to onu.OmciResponseRate
378 for i := 0; i < 10; i++ {
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200379 // we are not checking the error as we're expecting them (some messages should be skipped)
380 _ = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000381 }
382 assert.Equal(t, stream.CallCount, int(onu.OmciResponseRate))
383 }
384}
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800385
386func Test_EndSoftwareDownloadRequestHandling(t *testing.T) {
387 onu := createTestOnu()
388
389 // test EndSoftwareDownloadRequest in case of abort
390 onu.ImageSoftwareReceivedSections = 2
391 imageCrc, _ := strconv.ParseInt("FFFFFFFF", 16, 64)
392 msg := makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 0, uint32(imageCrc)))
393 res := onu.handleEndSoftwareDownloadRequest(msg)
394 assert.Equal(t, res, true)
Holger Hildebrandt96382572022-05-31 09:41:38 +0000395 assert.Equal(t, onu.ImageSoftwareReceivedSections, uint32(0))
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800396
397 // test EndSoftwareDownloadRequest if we received less sections than expected
398 onu.ImageSoftwareExpectedSections = 2
399 onu.ImageSoftwareReceivedSections = 1
400 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 2, 2))
401 res = onu.handleEndSoftwareDownloadRequest(msg)
402 assert.Equal(t, res, false)
403
404 // test CRC Mismatch
405 onu.ImageSectionData = []byte{111, 114, 116, 116, 105, 116, 111, 114, 32, 113, 117, 105, 115, 46, 32, 86, 105, 118, 97, 109, 117, 115, 32, 110, 101, 99, 32, 108, 105, 98, 101}
406 onu.ImageSoftwareExpectedSections = 2
407 onu.ImageSoftwareReceivedSections = 2
408 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 12))
409 res = onu.handleEndSoftwareDownloadRequest(msg)
410 assert.Equal(t, res, false)
411
412 // if it's a valid case then set the StandbyImageVersion
413 onu.InDownloadImageVersion = "DownloadedImage"
414 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 1523894119))
415 res = onu.handleEndSoftwareDownloadRequest(msg)
416 assert.Equal(t, res, true)
417 assert.Equal(t, onu.StandbyImageVersion, "DownloadedImage")
418}