blob: e6c4213019a23cd7561d276cf267a20dd1fd28e3 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001/*
Joey Armstrong5f51f2e2023-01-17 17:06:26 -05002 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
khenaidood948f772021-08-11 17:49:24 -04003 *
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 test
18
19import (
20 "context"
21 "errors"
22 "fmt"
23 "io"
24 "math/rand"
Gustavo Silva9a0ed002022-10-11 11:06:58 -030025 "os"
26 "runtime"
27 "runtime/pprof"
28 "strconv"
khenaidood948f772021-08-11 17:49:24 -040029 "strings"
30 "sync"
Gustavo Silva9a0ed002022-10-11 11:06:58 -030031 "testing"
32 "time"
khenaidood948f772021-08-11 17:49:24 -040033
34 "github.com/Shopify/sarama"
35 "github.com/golang/protobuf/ptypes/empty"
36 "github.com/opencord/voltha-lib-go/v7/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v7/pkg/kafka"
38 mock_kafka "github.com/opencord/voltha-lib-go/v7/pkg/mocks/kafka"
39 "github.com/opencord/voltha-lib-go/v7/pkg/probe"
khenaidoo9beaaf12021-10-19 17:32:01 -040040 "github.com/opencord/voltha-protos/v5/go/omci"
khenaidood948f772021-08-11 17:49:24 -040041 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
42 "github.com/opencord/voltha-protos/v5/go/voltha"
43 "google.golang.org/grpc"
44
khenaidood948f772021-08-11 17:49:24 -040045 "github.com/golang/protobuf/jsonpb"
46 "github.com/opencord/voltha-go/rw_core/config"
47 c "github.com/opencord/voltha-go/rw_core/core"
48 cm "github.com/opencord/voltha-go/rw_core/mocks"
49 "github.com/opencord/voltha-lib-go/v7/pkg/log"
50 mock_etcd "github.com/opencord/voltha-lib-go/v7/pkg/mocks/etcd"
51 "github.com/phayes/freeport"
52 "github.com/stretchr/testify/assert"
53)
54
55var oltAdapters = map[string]*AdapterInfo{
56 "olt_adapter_type1": {
57 TotalReplica: 1,
58 DeviceType: "olt-device-type1",
59 Vendor: "olt-mock-vendor1",
60 ChildDeviceType: "onu-device-type1",
61 ChildVendor: "onu-mock-vendor1",
62 },
63 "olt_adapter_type2": {
64 TotalReplica: 1,
65 DeviceType: "olt-device-type2",
66 Vendor: "olt-mock-vendor2",
67 ChildDeviceType: "onu-device-type2",
68 ChildVendor: "onu-mock-vendor2",
69 },
70}
71
72var onuAdapters = map[string]*AdapterInfo{
73 "onu_adapter_type1": {
74 TotalReplica: 1,
75 DeviceType: "onu-device-type1",
76 Vendor: "onu-mock-vendor1",
77 },
78 "onu_adapter_type2": {
79 TotalReplica: 1,
80 DeviceType: "onu-device-type2",
81 Vendor: "onu-mock-vendor2",
82 },
83}
84
85type NBTest struct {
86 etcdServer *mock_etcd.EtcdServer
87 config *config.RWCoreFlags
88 kvClientPort int
89 kEventClient kafka.Client
90 kafkaBroker *sarama.MockBroker
91 numONUPerOLT int
92 startingUNIPortNo int
93 oltAdapters map[string][]*cm.OLTAdapter // map<adapter type>[adapter instances]
94 onuAdapters map[string][]*cm.ONUAdapter
95 coreInstanceID string
96 internalTimeout time.Duration
97 maxTimeout time.Duration
98 coreRPCTimeout time.Duration
Himani Chawla4b4bd252021-11-08 15:59:40 +053099 coreFlowTimeout time.Duration
khenaidood948f772021-08-11 17:49:24 -0400100 core *c.Core
101 probe *probe.Probe
102 oltAdaptersLock sync.RWMutex
103 onuAdaptersLock sync.RWMutex
104 changeEventLister *ChangedEventListener
105}
106
107var testLogger log.CLogger
108
109func init() {
110 var err error
111 testLogger, err = log.RegisterPackage(log.JSON, log.InfoLevel, log.Fields{"nbi-handler-test": true})
112 if err != nil {
113 panic(err)
114 }
115
116 if err = log.SetLogLevel(log.InfoLevel); err != nil {
117 panic(err)
118 }
119}
120
121func newNBTest(ctx context.Context, loadTest bool) *NBTest {
122 test := &NBTest{}
123 // Start the embedded etcd server
124 var err error
125 test.etcdServer, test.kvClientPort, err = StartEmbeddedEtcdServer(ctx, "voltha.rwcore.nb.test", "voltha.rwcore.nb.etcd", "error")
126 if err != nil {
127 logger.Fatal(ctx, err)
128 }
129 test.coreInstanceID = "rw-nbi-test"
130 test.internalTimeout = 20 * time.Second
131 test.maxTimeout = 20 * time.Second
132 test.coreRPCTimeout = 20 * time.Second
Himani Chawla4b4bd252021-11-08 15:59:40 +0530133 test.coreFlowTimeout = 30 * time.Second
khenaidood948f772021-08-11 17:49:24 -0400134 if loadTest {
135 test.internalTimeout = 100 * time.Second
136 test.maxTimeout = 300 * time.Second
137 test.coreRPCTimeout = 100 * time.Second
Himani Chawla4b4bd252021-11-08 15:59:40 +0530138 test.coreFlowTimeout = 120 * time.Second
khenaidood948f772021-08-11 17:49:24 -0400139 setRetryInterval(5 * time.Second)
140 }
141 return test
142}
143
144func (nb *NBTest) startGRPCCore(ctx context.Context, t *testing.T) (coreEndpoint, nbiEndpoint string) {
145 // Setup the configs
146 cfg := &config.RWCoreFlags{}
147 cfg.ParseCommandArguments([]string{})
148 cfg.InternalTimeout = nb.internalTimeout
149 cfg.RPCTimeout = nb.coreRPCTimeout
Himani Chawla4b4bd252021-11-08 15:59:40 +0530150 cfg.FlowTimeout = nb.coreFlowTimeout
khenaidood948f772021-08-11 17:49:24 -0400151 cfg.KVStoreAddress = "127.0.0.1" + ":" + strconv.Itoa(nb.kvClientPort)
152 cfg.LogLevel = "DEBUG"
153
154 // Get a free port for the Core gRPC server
155 grpcPort, err := freeport.GetFreePort()
156 if err != nil {
157 logger.Fatal(ctx, "Cannot get a freeport for grpc core")
158 }
159 cfg.GrpcSBIAddress = "127.0.0.1:" + strconv.Itoa(grpcPort)
160 coreEndpoint = cfg.GrpcSBIAddress
161
162 // Get a free port for the NBI gRPC server
163 grpcPort, err = freeport.GetFreePort()
164 if err != nil {
165 logger.Fatal(ctx, "Cannot get a freeport for grpc NBI")
166 }
167 cfg.GrpcNBIAddress = "127.0.0.1:" + strconv.Itoa(grpcPort)
168 nbiEndpoint = cfg.GrpcNBIAddress
169
170 // Set up the probe service
171 nb.probe = &probe.Probe{}
172 probePort, err := freeport.GetFreePort()
173 if err != nil {
174 logger.Fatal(ctx, "Cannot get a freeport for probe port")
175 }
176 cfg.ProbeAddress = "127.0.0.1:" + strconv.Itoa(probePort)
177 go nb.probe.ListenAndServe(ctx, cfg.ProbeAddress)
178
179 //Add the probe to the context to pass to all the services started
180 probeCtx := context.WithValue(ctx, probe.ProbeContextKey, nb.probe)
181
182 // Set up a mock kafka broker
183 kafkaPort, err := freeport.GetFreePort()
184 if err != nil {
185 logger.Fatalw(probeCtx, "Cannot get a freeport for kafka port", log.Fields{"error": err})
186 }
187 cfg.KafkaClusterAddress = "127.0.0.1:" + strconv.Itoa(kafkaPort)
188
189 // Register probe services
190 nb.probe.RegisterService(
191 ctx,
192 "cluster-message-service",
193 "grpc-sbi-service",
194 "adapter-service",
195 "kv-service",
196 "device-service",
197 "logical-device-service",
198 )
199
200 nb.kEventClient = mock_kafka.NewKafkaClient()
201
202 nb.config = cfg
203 shutdownCtx, cancelCtx := context.WithCancel(probeCtx)
204
205 rwCore := &c.Core{Shutdown: cancelCtx, Stopped: make(chan struct{}), KafkaClient: nb.kEventClient}
206 go rwCore.Start(shutdownCtx, "core-test", cfg)
207
208 return
209}
210
211func (nb *NBTest) stopAll(ctx context.Context) {
212 if nb.etcdServer != nil {
213 StopEmbeddedEtcdServer(ctx, nb.etcdServer)
214 }
215
216 if nb.kEventClient != nil {
217 nb.kEventClient.Stop(ctx)
218 }
219
220 if nb.kafkaBroker != nil {
221 nb.kafkaBroker.Close()
222 }
223
224 // Stop all grpc clients first
225 nb.oltAdaptersLock.Lock()
226 if nb.oltAdapters != nil {
227 for _, adapterInstances := range nb.oltAdapters {
228 for _, instance := range adapterInstances {
229 instance.StopGrpcClient()
230 }
231 }
232 }
233 nb.oltAdaptersLock.Unlock()
234 nb.onuAdaptersLock.Lock()
235 if nb.onuAdapters != nil {
236 for _, adapterInstances := range nb.onuAdapters {
237 for _, instance := range adapterInstances {
238 instance.StopGrpcClient()
239 }
240 }
241 }
242 nb.onuAdaptersLock.Unlock()
243
244 // Now stop the grpc servers
245 nb.oltAdaptersLock.Lock()
246 defer nb.oltAdaptersLock.Unlock()
247 if nb.oltAdapters != nil {
248 for _, adapterInstances := range nb.oltAdapters {
249 for _, instance := range adapterInstances {
250 instance.Stop()
251 }
252 }
253 }
254
255 nb.onuAdaptersLock.Lock()
256 defer nb.onuAdaptersLock.Unlock()
257 if nb.onuAdapters != nil {
258 for _, adapterInstances := range nb.onuAdapters {
259 for _, instance := range adapterInstances {
260 instance.Stop()
261 }
262 }
263 }
264 if nb.core != nil {
khenaidooa46458b2021-12-15 16:50:44 -0500265 nb.core.Stop(ctx)
khenaidood948f772021-08-11 17:49:24 -0400266 }
267}
268
269func (nb *NBTest) verifyLogicalDevices(t *testing.T, oltDevice *voltha.Device, nbi voltha.VolthaServiceClient) {
270 // Get the latest logical device
271 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
272 assert.Nil(t, err)
273 assert.NotNil(t, logicalDevices)
274 var ld *voltha.LogicalDevice
275 for _, logicalDevice := range logicalDevices.Items {
276 if logicalDevice.RootDeviceId == oltDevice.Id {
277 ld = logicalDevice
278 break
279 }
280 }
281 assert.NotNil(t, ld)
282 ports, err := nbi.ListLogicalDevicePorts(getContext(), &voltha.ID{Id: ld.Id})
283 assert.Nil(t, err)
284
285 assert.NotEqual(t, "", ld.Id)
286 assert.NotEqual(t, uint64(0), ld.DatapathId)
287 assert.Equal(t, "olt_adapter_mock", ld.Desc.HwDesc)
288 assert.Equal(t, "olt_adapter_mock", ld.Desc.SwDesc)
289 assert.NotEqual(t, "", ld.RootDeviceId)
290 assert.NotEqual(t, "", ld.Desc.SerialNum)
291 assert.Equal(t, uint32(256), ld.SwitchFeatures.NBuffers)
292 assert.Equal(t, uint32(2), ld.SwitchFeatures.NTables)
293 assert.Equal(t, uint32(15), ld.SwitchFeatures.Capabilities)
294 assert.Equal(t, 1+nb.numONUPerOLT, len(ports.Items))
295 assert.Equal(t, oltDevice.ParentId, ld.Id)
296 //Expected port no
297 expectedPortNo := make(map[uint32]bool)
298 expectedPortNo[uint32(2)] = false
299 for i := 0; i < nb.numONUPerOLT; i++ {
300 expectedPortNo[uint32(i+100)] = false
301 }
302 for _, p := range ports.Items {
303 assert.Equal(t, p.OfpPort.PortNo, p.DevicePortNo)
304 assert.Equal(t, uint32(4), p.OfpPort.State)
305 expectedPortNo[p.OfpPort.PortNo] = true
306 if strings.HasPrefix(p.Id, "nni") {
307 assert.Equal(t, true, p.RootPort)
308 //assert.Equal(t, uint32(2), p.OfpPort.PortNo)
309 assert.Equal(t, p.Id, fmt.Sprintf("nni-%d", p.DevicePortNo))
310 } else {
311 assert.Equal(t, p.Id, fmt.Sprintf("uni-%d", p.DevicePortNo))
312 assert.Equal(t, false, p.RootPort)
313 }
314 }
315}
316
317func (nb *NBTest) verifyDevices(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string) {
318 // Get the latest set of devices
319 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
320 assert.Nil(t, err)
321 assert.NotNil(t, devices)
322
323 // A device is ready to be examined when its ADMIN state is ENABLED and OPERATIONAL state is ACTIVE
324 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
325 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
326 }
327
328 var wg sync.WaitGroup
329 for _, device := range devices.Items {
330 if (device.Root && device.Id != oltDeviceID) || (!device.Root && device.ParentId != oltDeviceID) {
331 continue
332 }
333 wg.Add(1)
334 go func(wg *sync.WaitGroup, device *voltha.Device) {
335 // Wait until the device is in the right state
336 err := waitUntilDeviceReadiness(device.Id, nb.maxTimeout, vFunction, nbi)
337 assert.Nil(t, err)
338
339 // Now, verify the details of the device. First get the latest update
340 d, err := nbi.GetDevice(getContext(), &voltha.ID{Id: device.Id})
341 assert.Nil(t, err)
342 dPorts, err := nbi.ListDevicePorts(getContext(), &voltha.ID{Id: device.Id})
343 assert.Nil(t, err)
344 assert.Equal(t, voltha.AdminState_ENABLED, d.AdminState)
345 assert.Equal(t, voltha.ConnectStatus_REACHABLE, d.ConnectStatus)
346 assert.Equal(t, voltha.OperStatus_ACTIVE, d.OperStatus)
347 assert.NotEqual(t, "", d.MacAddress)
348 assert.NotEqual(t, "", d.SerialNumber)
349
350 if d.Type == "olt_adapter_mock" {
351 assert.Equal(t, true, d.Root)
352 assert.NotEqual(t, "", d.Id)
353 assert.NotEqual(t, "", d.ParentId)
354 assert.Nil(t, d.ProxyAddress)
355 } else if d.Type == "onu_adapter_mock" {
356 assert.Equal(t, false, d.Root)
357 assert.NotEqual(t, uint32(0), d.Vlan)
358 assert.NotEqual(t, "", d.Id)
359 assert.NotEqual(t, "", d.ParentId)
360 assert.NotEqual(t, "", d.ProxyAddress.DeviceId)
361 assert.Equal(t, "olt_adapter_mock", d.ProxyAddress.DeviceType)
362 } else {
363 assert.Error(t, errors.New("invalid-device-type"))
364 }
365 assert.Equal(t, 2, len(dPorts.Items))
366 for _, p := range dPorts.Items {
367 assert.Equal(t, voltha.AdminState_ENABLED, p.AdminState)
368 assert.Equal(t, voltha.OperStatus_ACTIVE, p.OperStatus)
369 if p.Type == voltha.Port_ETHERNET_NNI || p.Type == voltha.Port_ETHERNET_UNI {
370 assert.Equal(t, 0, len(p.Peers))
371 } else if p.Type == voltha.Port_PON_OLT {
372 assert.Equal(t, nb.numONUPerOLT, len(p.Peers))
373 assert.Equal(t, uint32(1), p.PortNo)
374 } else if p.Type == voltha.Port_PON_ONU {
375 assert.Equal(t, 1, len(p.Peers))
376 assert.Equal(t, uint32(1), p.PortNo)
377 } else {
378 assert.Error(t, errors.New("invalid-port"))
379 }
380 }
381 wg.Done()
382 }(&wg, device)
383 }
384 wg.Wait()
385}
386
387func (nb *NBTest) getChildDevices(parentID string, nbi voltha.VolthaServiceClient) (*voltha.Devices, error) {
388 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
389 if err != nil {
390 return nil, err
391 }
392 var childDevice []*voltha.Device
393 for _, d := range devices.Items {
394 if d.Root != true && d.ParentId == parentID {
395 childDevice = append(childDevice, d)
396 }
397 }
398 return &voltha.Devices{Items: childDevice}, nil
399}
400
401func (nb *NBTest) testCoreWithoutData(t *testing.T, nbi voltha.VolthaServiceClient) {
402 lds, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
403 assert.Nil(t, err)
404 assert.NotNil(t, lds)
405 assert.Equal(t, 0, len(lds.Items))
406 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
407 assert.Nil(t, err)
408 assert.NotNil(t, devices)
409 assert.Equal(t, 0, len(devices.Items))
410 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
411 assert.Equal(t, 0, len(adapters.Items))
412 assert.Nil(t, err)
413 assert.NotNil(t, adapters)
414}
415func (nb *NBTest) getNumAdapters() int {
416 totalAdapters := int32(0)
417 for _, aInfo := range onuAdapters {
418 totalAdapters = totalAdapters + aInfo.TotalReplica
419 }
420 for _, aInfo := range oltAdapters {
421 totalAdapters = totalAdapters + aInfo.TotalReplica
422 }
423 return int(totalAdapters)
424}
425
426func (nb *NBTest) testAdapterRegistration(t *testing.T, nbi voltha.VolthaServiceClient) {
427 ctx := context.Background()
428 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
429 assert.Nil(t, err)
430 assert.NotNil(t, adapters)
431 assert.Equal(t, nb.getNumAdapters(), len(adapters.Items))
432 nb.oltAdaptersLock.RLock()
433 defer nb.oltAdaptersLock.RUnlock()
434 nb.onuAdaptersLock.RLock()
435 defer nb.onuAdaptersLock.RUnlock()
436 for _, a := range adapters.Items {
437 if strings.Contains(a.Type, "olt") {
438 _, exist := nb.oltAdapters[a.Type]
439 assert.True(t, exist)
440 assert.True(t, strings.Contains(a.Vendor, "olt-mock-vendor"))
441 } else if strings.Contains(a.Type, "onu") {
442 _, exist := nb.onuAdapters[a.Type]
443 assert.True(t, exist)
444 assert.True(t, strings.Contains(a.Vendor, "onu-mock-vendor"))
445 } else {
446 logger.Fatal(ctx, "unregistered-adapter", a.Id)
447 }
448 }
449 deviceTypes, err := nbi.ListDeviceTypes(getContext(), &empty.Empty{})
450 assert.Nil(t, err)
451 assert.NotNil(t, deviceTypes)
452 assert.Equal(t, len(nb.oltAdapters)+len(nb.onuAdapters), len(deviceTypes.Items))
453 for _, dt := range deviceTypes.Items {
454 if strings.Contains(dt.AdapterType, "olt") {
455 _, exist := nb.oltAdapters[dt.AdapterType]
456 assert.True(t, exist)
457 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
458 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
459 } else if strings.Contains(dt.AdapterType, "onu") {
460 _, exist := nb.onuAdapters[dt.AdapterType]
461 assert.True(t, exist)
462 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
463 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
464 } else {
465 logger.Fatal(ctx, "invalid-device-type", dt.Id)
466 }
467 }
468}
469
470func (nb *NBTest) testCreateDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
471 // Create a valid device
472 aRandomMacAddress := getRandomMacAddress()
473 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: aRandomMacAddress})
474 assert.Nil(t, err)
475 assert.NotNil(t, oltDevice)
476
477 oltD, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
478 assert.Nil(t, err)
479 assert.NotNil(t, oltD)
480 assert.Equal(t, oltDevice.String(), oltD.String())
481
482 // Try to create the same device
483 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: aRandomMacAddress})
484 assert.NotNil(t, err)
485 assert.True(t, strings.Contains(err.Error(), "device is already pre-provisioned"))
486
487 // Try to create a device with invalid data
488 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType})
489 assert.NotNil(t, err)
490 assert.True(t, strings.Contains(err.Error(), "no-device-info-present; MAC or HOSTIP&PORT"))
491
492 // Ensure we still have the previous device still in the core
493 createDevice, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
494 assert.Nil(t, err)
495 assert.NotNil(t, createDevice)
496
497 //Remove the device
498 err = cleanUpCreatedDevices(nb.maxTimeout, nbi, oltDevice.Id)
499 assert.Nil(t, err)
500}
501
502func (nb *NBTest) enableDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDevice *voltha.Device) {
503 // Subscribe to the event listener
504 eventCh := nb.changeEventLister.Subscribe((nb.numONUPerOLT + 1) * nb.getNumAdapters())
505 defer nb.changeEventLister.Unsubscribe(eventCh)
506
507 // Enable the oltDevice
508 _, err := nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
509 assert.Nil(t, err)
510
511 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
512 var wg sync.WaitGroup
513 wg.Add(1)
514 subCtx, cancel := context.WithCancel(context.Background())
515 defer cancel()
516 go nb.monitorLogicalDevices(subCtx, t, nbi, 1, nb.numONUPerOLT, &wg, false, false, oltDevice.Id, eventCh)
517
518 // Wait for the logical device to be in the ready state
519 var vldFunction = func(ports []*voltha.LogicalPort) bool {
520 return len(ports) == nb.numONUPerOLT+1
521 }
522 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
523 assert.Nil(t, err)
524
525 // Verify that the devices have been setup correctly
526 nb.verifyDevices(t, nbi, oltDevice.Id)
527
528 // Get latest oltDevice data
529 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
530 assert.Nil(t, err)
531
532 // Verify that the logical device has been setup correctly
533 nb.verifyLogicalDevices(t, oltDevice, nbi)
534
535 // Wait until all flows has been sent to the devices successfully
536 wg.Wait()
537}
538
539func (nb *NBTest) testForceDeletePreProvDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
540 // Create a valid device
541 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
542 assert.Nil(t, err)
543 assert.NotNil(t, oltDevice)
544
545 // Ensure the device is present
546 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
547 assert.Nil(t, err)
548 assert.NotNil(t, device)
549 assert.Equal(t, oltDevice.String(), device.String())
550
551 //Remove the device forcefully
552 _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
553 assert.Nil(t, err)
554
555 err = waitUntilDeviceIsRemoved(nb.maxTimeout, nbi, oltDevice.Id)
556 assert.Nil(t, err)
557}
558
559func (nb *NBTest) testForceDeleteEnabledDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
560 // Create a valid device
561 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
562 assert.Nil(t, err)
563 assert.NotNil(t, oltDevice)
564
565 // Enable device
566 nb.enableDevice(t, nbi, oltDevice)
567
568 //Remove the device forcefully
569 _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
570 assert.Nil(t, err)
571
572 err = waitUntilDeviceIsRemoved(nb.maxTimeout, nbi, oltDevice.Id)
573 assert.Nil(t, err)
574}
575
576func (nb *NBTest) testDeletePreProvDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
577 // Create a valid device
578 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
579 assert.Nil(t, err)
580 assert.NotNil(t, oltDevice)
581
582 // Ensure device is present
583 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
584 assert.Nil(t, err)
585 assert.NotNil(t, device)
586 assert.Equal(t, oltDevice.String(), device.String())
587
588 err = cleanUpCreatedDevice(nb.maxTimeout, nbi, oltDevice.Id)
589 assert.Nil(t, err)
590}
591
592func (nb *NBTest) testDeleteEnabledDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
593 // Create a valid device
594 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
595 assert.Nil(t, err)
596 assert.NotNil(t, oltDevice)
597
598 // Enable device
599 nb.enableDevice(t, nbi, oltDevice)
600
601 //Remove the device
602 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
603 assert.Nil(t, err)
604
605 var vFunction isConditionSatisfied = func() bool {
606 _, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
607 if err != nil {
608 return strings.Contains(err.Error(), "NotFound")
609 }
610 return false
611 }
612
613 err = waitUntilCondition(nb.maxTimeout, vFunction)
614 assert.Nil(t, err)
615}
616
617func (nb *NBTest) testForceDeleteDeviceFailure(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
618 // Create a valid device
619 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
620 assert.Nil(t, err)
621 assert.NotNil(t, oltDevice)
622
623 // Enable the device
624 nb.enableDevice(t, nbi, oltDevice)
625
626 // Set the delete action on the relevant adapter
627 oltAdapter, err := nb.getOLTAdapterInstance(t, nbi, oltDevice.Id)
628 assert.Nil(t, err)
629 oltAdapter.SetDeleteAction(oltDevice.Id, true)
630
631 //Remove the device
632 _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
633 assert.Nil(t, err)
634
635 err = waitUntilDeviceIsRemoved(nb.maxTimeout, nbi, oltDevice.Id)
636 assert.Nil(t, err)
637
638}
639
640func (nb *NBTest) testDeleteDeviceFailure(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
641 // Create and enable a OLT device for that device type
642 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
643 assert.Nil(t, err)
644 assert.NotNil(t, oltDevice)
645
646 // Set the delete action to fail device deletion
647 oltAdapter, err := nb.getOLTAdapterInstance(t, nbi, oltDevice.Id)
648 assert.Nil(t, err)
649 oltAdapter.SetDeleteAction(oltDevice.Id, true)
650
651 // Subscribe and wait asynchronously on the kafka message bus for a delete failure event
652 ch := make(chan int, 1)
653 eventTopic := &kafka.Topic{Name: nb.config.EventTopic}
654 eventChnl, err := nb.kEventClient.Subscribe(getContext(), eventTopic)
655 assert.Nil(t, err)
656 defer func() {
657 if eventChnl != nil {
658 err = nb.kEventClient.UnSubscribe(getContext(), eventTopic, eventChnl)
659 assert.Nil(t, err)
660 }
661 }()
662 go func() {
663 timer := time.NewTimer(nb.internalTimeout)
664 defer timer.Stop()
665 loop:
666 for {
667 select {
668 case event := <-eventChnl:
669 if evnt, ok := event.(*voltha.Event); ok {
670 rpcEvent := evnt.GetRpcEvent()
671 if rpcEvent != nil && rpcEvent.ResourceId == oltDevice.Id && rpcEvent.Rpc == "DeleteDevice" {
672 ch <- 1
673 break loop
674 }
675 }
676 case <-timer.C:
677 ch <- 0
678 break loop
679 }
680 }
681 }()
682
683 //Now remove the device
684 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
Gustavo Silva9a0ed002022-10-11 11:06:58 -0300685 assert.NotNil(t, err)
khenaidood948f772021-08-11 17:49:24 -0400686
687 // Wait for the delete event
688 event := <-ch
689 assert.Equal(t, 1, event)
690
691 // Set the delete action to pass device deletion
692 oltAdapter.SetDeleteAction(oltDevice.Id, false)
693
694 // Now Force Delete this device - needs to be done in a verification function because if the
695 // previous failed delete action was not complete then a force delete will return an error
696 var forceDeleteComplete isConditionSatisfied = func() bool {
697 _, err := nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
698 return err != nil
699
700 }
701 err = waitUntilCondition(nb.maxTimeout, forceDeleteComplete)
702 assert.Nil(t, err)
703
704 // Wait until device is gone
705 var deviceDeleteComplete isConditionSatisfied = func() bool {
706 _, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
707 if err != nil {
708 return strings.Contains(err.Error(), "NotFound")
709 }
710 return false
711 }
712
713 err = waitUntilCondition(nb.maxTimeout, deviceDeleteComplete)
714 assert.Nil(t, err)
715}
716
717// createAndEnableOLTDevice creates and enables an OLT device. If there is a connection error (e.g. core communication is
718// not fully ready or the relevant adapter has not been registered yet) then it will automatically retry on failure.
719func (nb *NBTest) createAndEnableOLTDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) (*voltha.Device, error) {
720 var oltDevice *voltha.Device
721 var err error
722 var enableDeviceWithRetry isConditionSatisfied = func() bool {
723 // Create device
724 oltDevice, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: oltDeviceType, MacAddress: getRandomMacAddress()})
725 assert.Nil(t, err)
726 assert.NotNil(t, oltDevice)
727
728 // Verify oltDevice exist in the core
729 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
730 assert.Nil(t, err)
731 exist := false
732 for _, d := range devices.Items {
733 if d.Id == oltDevice.Id {
734 exist = true
735 break
736 }
737 }
738 assert.True(t, true, exist)
739 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
740 if err == nil {
741 return true
742 }
743 _, _ = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
744 assert.Nil(t, err)
745
746 return false
747 }
748 err = waitUntilCondition(nb.maxTimeout, enableDeviceWithRetry)
749 assert.Nil(t, err)
750
751 // Wait for device to be fully enabled
752 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
753 return device.AdminState == voltha.AdminState_ENABLED &&
754 device.OperStatus == voltha.OperStatus_ACTIVE &&
755 device.ConnectStatus == voltha.ConnectStatus_REACHABLE
756 }
757 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
758 assert.Nil(t, err)
759
760 // Wait until all relevant ONUs are enabled and ready
761 numOnuPerOlt := cm.GetNumONUPerOLT()
762 var onusReady isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
763 if devices == nil || len(devices.Items) < numOnuPerOlt+1 {
764 return false
765 }
766 count := 0
767 for _, d := range devices.Items {
768 if !d.Root && d.ParentId == oltDevice.Id {
769 if d.AdminState == voltha.AdminState_ENABLED &&
770 d.OperStatus == voltha.OperStatus_ACTIVE &&
771 d.ConnectStatus == voltha.ConnectStatus_REACHABLE {
772 count = count + 1
773 }
774 }
775 }
776 return count >= numOnuPerOlt
777 }
778 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, onusReady)
779 assert.Nil(t, err)
780
781 return oltDevice, err
782}
783
784func (nb *NBTest) testEnableDeviceFailed(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
785 //Create a device that has no adapter registered
786 macAddress := getRandomMacAddress()
787 oltDeviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegistered", MacAddress: macAddress})
788 assert.Nil(t, err)
789 assert.NotNil(t, oltDeviceNoAdapter)
790
791 // Try to enable the oltDevice and check the error message
792 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
793 assert.NotNil(t, err)
794 assert.True(t, strings.Contains(err.Error(), "adapter-not-registered-for-device-type noAdapterRegistered"))
795
796 //Remove the device
797 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
798 assert.Nil(t, err)
799
800 // Wait until device is removed
801 err = waitUntilDeviceIsRemoved(nb.maxTimeout, nbi, oltDeviceNoAdapter.Id)
802 assert.Nil(t, err)
803}
804
805func (nb *NBTest) testEnableDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
806 // Subscribe to the event listener
807 eventCh := nb.changeEventLister.Subscribe((nb.numONUPerOLT + 1) * nb.getNumAdapters())
808
809 defer nb.changeEventLister.Unsubscribe(eventCh)
810
811 // Create and enable a OLT device for that device type
812 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
813 assert.Nil(t, err)
814 assert.NotNil(t, oltDevice)
815
816 //Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
817 var wg sync.WaitGroup
818 wg.Add(1)
819 subCtx, cancel := context.WithCancel(context.Background())
820 defer cancel()
821 go nb.monitorLogicalDevices(subCtx, t, nbi, 1, nb.numONUPerOLT, &wg, false, false, oltDevice.Id, eventCh)
822
823 // Wait for the logical device to be in the ready state
824 var vldFunction = func(ports []*voltha.LogicalPort) bool {
825 return len(ports) == nb.numONUPerOLT+1
826 }
827 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
828 assert.Nil(t, err)
829
830 // Verify that the devices have been setup correctly
831 nb.verifyDevices(t, nbi, oltDevice.Id)
832
833 // Get latest oltDevice data
834 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
835 assert.Nil(t, err)
836
837 // Verify that the logical device has been setup correctly
838 nb.verifyLogicalDevices(t, oltDevice, nbi)
839
840 //Wait until all flows has been sent to the devices successfully
841 wg.Wait()
842
843 // log.SetAllLogLevel(log.DebugLevel)
844 //Remove the device
845 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, false)
846 assert.Nil(t, err)
847}
848
849func (nb *NBTest) testDisableAndReEnableRootDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
850 // Create and enable an OLT device
851 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
852 assert.Nil(t, err)
853 assert.NotNil(t, oltDevice)
854
855 // Wait until all ONU devices have been created and enabled
856
857 // Disable the oltDevice
858 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
859 assert.Nil(t, err)
860
861 // Wait for the old device to be disabled
862 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
863 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
864 }
865 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
866 assert.Nil(t, err)
867
868 // Verify that all onu devices are disabled as well
869 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
870 assert.Nil(t, err)
871 assert.NotNil(t, onuDevices)
872 assert.Greater(t, len(onuDevices.Items), 0)
873 for _, onu := range onuDevices.Items {
874 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
875 assert.Nil(t, err)
876 }
877
878 // Wait for the logical device to satisfy the expected condition
879 var vlFunction = func(ports []*voltha.LogicalPort) bool {
880 for _, lp := range ports {
881 if (lp.OfpPort.Config&uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
882 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LINK_DOWN) {
883 return false
884 }
885 }
886 return true
887 }
888 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
889 assert.Nil(t, err)
890
891 // Reenable the oltDevice
892 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
893 assert.Nil(t, err)
894
895 // Wait for the old device to be enabled
896 vdFunction = func(device *voltha.Device) bool {
897 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
898 }
899 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
900 assert.Nil(t, err)
901
902 // Verify that all onu devices are enabled as well
903 onuDevices, err = nb.getChildDevices(oltDevice.Id, nbi)
904 assert.Nil(t, err)
905 assert.NotNil(t, onuDevices)
906 assert.Greater(t, len(onuDevices.Items), 0)
907 for _, onu := range onuDevices.Items {
908 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
909 assert.Nil(t, err)
910 }
911
912 // Wait for the logical device to satisfy the expected condition
913 vlFunction = func(ports []*voltha.LogicalPort) bool {
914 for _, lp := range ports {
915 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
916 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
917 return false
918 }
919 }
920 return true
921 }
922 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
923 assert.Nil(t, err)
924
925 //Remove the device
926 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
927 assert.Nil(t, err)
928}
929
930func (nb *NBTest) testDisableAndDeleteAllDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
931 //Get an OLT device
932 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
933 assert.Nil(t, err)
934 assert.NotNil(t, oltDevice)
935
936 // Disable the oltDevice
937 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
938 assert.Nil(t, err)
939
940 // Wait for the olt device to be disabled
941 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
942 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
943 }
944 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
945 assert.Nil(t, err)
946
947 // Verify that all onu devices are disabled as well (previous test may have removed all ONUs)
948 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
949 assert.Nil(t, err)
950 assert.NotNil(t, onuDevices)
951 assert.GreaterOrEqual(t, len(onuDevices.Items), 0)
952 for _, onu := range onuDevices.Items {
953 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
954 assert.Nil(t, err)
955 }
956
957 // Delete the oltDevice
958 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
959 assert.Nil(t, err)
960
961 // Verify all devices relevant to the OLT device are gone
962 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
963 if (devices == nil) || len(devices.Items) == 0 {
964 return true
965 }
966 for _, d := range devices.Items {
967 if (d.Root && d.Id == oltDevice.Id) || (!d.Root && d.ParentId == oltDevice.Id) {
968 return false
969 }
970 }
971 return true
972 }
973 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
974 assert.Nil(t, err)
975
976 // Wait for absence of logical device
977 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
978 if (lds == nil) || (len(lds.Items) == 0) {
979 return true
980 }
981 for _, ld := range lds.Items {
982 if ld.RootDeviceId == oltDevice.Id {
983 return false
984 }
985 }
986 return true
987 }
988 err = waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
989 assert.Nil(t, err)
990
991 //Remove the device
992 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
993 assert.Nil(t, err)
994}
995
996func (nb *NBTest) testEnableAndDeleteAllDevice(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
997 //Create/Enable an OLT device
998 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
999 assert.Nil(t, err)
1000 assert.NotNil(t, oltDevice)
1001
1002 // Wait for the logical device to be in the ready state
1003 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1004 return len(ports) == nb.numONUPerOLT+1
1005 }
1006 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1007 assert.Nil(t, err)
1008
1009 //Get all child devices
1010 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
1011 assert.Nil(t, err)
1012 assert.NotNil(t, onuDevices)
1013 assert.Greater(t, len(onuDevices.Items), 0)
1014
1015 // Wait for each onu device to get deleted
1016 var vdFunc isDeviceConditionSatisfied = func(device *voltha.Device) bool {
1017 return device == nil
1018 }
1019
1020 // Delete the onuDevice
1021 for _, onu := range onuDevices.Items {
1022 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: onu.Id})
1023 assert.Nil(t, err)
1024 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunc, nbi)
1025 assert.Nil(t, err)
1026 }
1027
1028 // Disable the oltDevice
1029 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1030 assert.Nil(t, err)
1031
1032 // Wait for the olt device to be disabled
1033 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
1034 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
1035 }
1036 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vFunction, nbi)
1037 assert.Nil(t, err)
1038
1039 // Delete the oltDevice
1040 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1041 assert.Nil(t, err)
1042
1043 // Cleanup
1044 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1045 assert.Nil(t, err)
1046}
1047
1048func (nb *NBTest) testDisableAndEnablePort(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1049 //Create an OLT device
1050 var cp *voltha.Port
1051 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1052 assert.Nil(t, err)
1053 assert.NotNil(t, oltDevice)
1054
1055 oltPorts, err := nbi.ListDevicePorts(getContext(), &voltha.ID{Id: oltDevice.Id})
1056 assert.Nil(t, err)
1057
1058 for _, cp = range oltPorts.Items {
1059 if cp.Type == voltha.Port_PON_OLT {
1060 break
1061 }
1062
1063 }
1064 assert.NotNil(t, cp)
1065 cp.DeviceId = oltDevice.Id
1066
1067 // Disable the NW Port of oltDevice
1068 _, err = nbi.DisablePort(getContext(), cp)
1069 assert.Nil(t, err)
1070 // Wait for the olt device Port to be disabled
1071 var vdFunction isDevicePortsConditionSatisfied = func(ports *voltha.Ports) bool {
1072 for _, port := range ports.Items {
1073 if port.PortNo == cp.PortNo {
1074 return port.AdminState == voltha.AdminState_DISABLED
1075 }
1076 }
1077 return false
1078 }
1079 err = waitUntilDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
1080 assert.Nil(t, err)
1081 // Wait for the logical device to satisfy the expected condition
1082 var vlFunction = func(ports []*voltha.LogicalPort) bool {
1083 for _, lp := range ports {
1084 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
1085 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
1086 return false
1087 }
1088 }
1089 return true
1090 }
1091 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
1092 assert.Nil(t, err)
1093
1094 // Enable the NW Port of oltDevice
1095 _, err = nbi.EnablePort(getContext(), cp)
1096 assert.Nil(t, err)
1097
1098 // Wait for the olt device Port to be enabled
1099 vdFunction = func(ports *voltha.Ports) bool {
1100 for _, port := range ports.Items {
1101 if port.PortNo == cp.PortNo {
1102 return port.AdminState == voltha.AdminState_ENABLED
1103 }
1104 }
1105 return false
1106 }
1107 err = waitUntilDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
1108 assert.Nil(t, err)
1109 // Wait for the logical device to satisfy the expected condition
1110 vlFunction = func(ports []*voltha.LogicalPort) bool {
1111 for _, lp := range ports {
1112 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
1113 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
1114 return false
1115 }
1116 }
1117 return true
1118 }
1119 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
1120 assert.Nil(t, err)
1121
1122 // Disable a non-PON port
1123 for _, cp = range oltPorts.Items {
1124 if cp.Type != voltha.Port_PON_OLT {
1125 break
1126 }
1127
1128 }
1129 assert.NotNil(t, cp)
1130 cp.DeviceId = oltDevice.Id
1131
1132 // Disable the NW Port of oltDevice
1133 _, err = nbi.DisablePort(getContext(), cp)
1134 assert.NotNil(t, err)
1135
1136 //Remove the device
1137 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1138 assert.Nil(t, err)
1139}
1140
1141func (nb *NBTest) testDeviceRebootWhenOltIsEnabled(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1142 //Create an OLT device
1143 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1144 assert.Nil(t, err)
1145 assert.NotNil(t, oltDevice)
1146
1147 // Reboot the OLT and very that Connection Status goes to UNREACHABLE and operation status to UNKNOWN
1148 _, err = nbi.RebootDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1149 assert.Nil(t, err)
1150
1151 var vlFunction0 = func(d *voltha.Device) bool {
1152 return d.ConnectStatus == voltha.ConnectStatus_UNREACHABLE && d.OperStatus == voltha.OperStatus_UNKNOWN
1153 }
1154
1155 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction0, nbi)
1156 assert.Nil(t, err)
1157
Abhilash Laxmeshwar723ed742022-06-01 12:24:18 +05301158 oltAdapter, err := nb.getOLTAdapterInstance(t, nbi, oltDevice.Id)
1159 assert.Nil(t, err)
1160
1161 oltAdapter.SetDeviceRebooted(oltDevice.Id)
1162
1163 var vlFunctionreb = func(d *voltha.Device) bool {
1164 return d.ConnectStatus == voltha.ConnectStatus_REACHABLE && d.OperStatus == voltha.OperStatus_REBOOTED
1165 }
1166
1167 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunctionreb, nbi)
1168 assert.Nil(t, err)
1169
khenaidood948f772021-08-11 17:49:24 -04001170 // Wait for the logical device to satisfy the expected condition
1171 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
1172 return ld == nil
1173 }
1174
1175 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
1176 assert.Nil(t, err)
1177
1178 // Wait for the device to satisfy the expected condition (device does not have flows)
1179 var vlFunction2 = func(d *voltha.Device) bool {
1180 var deviceFlows *ofp.Flows
1181 var err error
1182 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
1183 return false
1184 }
1185 return len(deviceFlows.Items) == 0
1186 }
1187
1188 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
1189 assert.Nil(t, err)
1190
1191 // Wait for the device to satisfy the expected condition (there are no child devices)
1192 var vlFunction3 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
1193 if (devices == nil) || (len(devices.Items) == 0) {
1194 return false
1195 }
1196 for _, d := range devices.Items {
1197 if !d.Root && d.ParentId == oltDevice.Id {
1198 return false
1199 }
1200 }
1201 return true
1202 }
1203 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vlFunction3)
1204 assert.Nil(t, err)
1205
1206 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
1207 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
Abhilash Laxmeshwar723ed742022-06-01 12:24:18 +05301208 oltAdapter, err = nb.getOLTAdapterInstance(t, nbi, oltDevice.Id)
khenaidood948f772021-08-11 17:49:24 -04001209 assert.Nil(t, err)
1210 oltAdapter.SetDeviceActive(oltDevice.Id)
1211
1212 // Verify the device connection and operation states
1213 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1214 assert.Nil(t, err)
1215 assert.NotNil(t, oltDevice)
1216 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
1217 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
1218
1219 // Wait for the logical device to satisfy the expected condition
1220 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
1221 return ld != nil
1222 }
1223 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
1224 assert.Nil(t, err)
1225
1226 // Verify that we have no ONUs
1227 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
1228 assert.Nil(t, err)
1229 assert.NotNil(t, onuDevices)
1230 assert.Equal(t, 0, len(onuDevices.Items))
khenaidood948f772021-08-11 17:49:24 -04001231 //Remove the device
1232 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1233 assert.Nil(t, err)
1234}
1235
1236func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1237 // -----------------------------------------------------------------------
1238 // SubTest 1: Omci test action should fail due to nonexistent device id
1239
khenaidoo9beaaf12021-10-19 17:32:01 -04001240 request := &omci.OmciTestRequest{Id: "123", Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001241 _, err := nbi.StartOmciTestAction(getContext(), request)
1242 assert.NotNil(t, err)
1243 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
1244
1245 // -----------------------------------------------------------------------
1246 // SubTest 2: Error should be returned for device with no adapter registered
1247
1248 // Create a device that has no adapter registered
1249 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: getRandomMacAddress()})
1250 assert.Nil(t, err)
1251 assert.NotNil(t, deviceNoAdapter)
1252
1253 // Omci test action should fail due to nonexistent adapter
khenaidoo9beaaf12021-10-19 17:32:01 -04001254 request = &omci.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001255 _, err = nbi.StartOmciTestAction(getContext(), request)
1256 assert.NotNil(t, err)
1257 assert.True(t, strings.Contains(err.Error(), "noAdapterRegisteredOmciTest"))
1258
1259 //Remove the device
1260 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
1261 assert.Nil(t, err)
1262
1263 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
1264 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
1265 if (devices == nil) || (len(devices.Items) == 0) {
1266 return true
1267 }
1268 for _, d := range devices.Items {
1269 if (d.Root && d.Id == deviceNoAdapter.Id) || (!d.Root && d.ParentId == deviceNoAdapter.Id) {
1270 return false
1271 }
1272 }
1273 return true
1274 }
1275 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
1276 assert.Nil(t, err)
1277
1278 // -----------------------------------------------------------------------
1279 // SubTest 3: Omci test action should succeed on valid ONU
1280
1281 // Create and enable device with valid data
1282 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1283 assert.Nil(t, err)
1284 assert.NotNil(t, oltDevice)
1285
1286 // Wait for the logical device to be in the ready state
1287 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1288 return len(ports) == nb.numONUPerOLT+1
1289 }
1290 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1291 assert.Nil(t, err)
1292
1293 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
1294 assert.Nil(t, err)
1295 assert.NotNil(t, onuDevices)
1296 assert.Greater(t, len(onuDevices.Items), 0)
1297
1298 onuDevice := onuDevices.Items[0]
1299
1300 // Omci test action should succeed
khenaidoo9beaaf12021-10-19 17:32:01 -04001301 request = &omci.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001302 resp, err := nbi.StartOmciTestAction(getContext(), request)
1303 assert.Nil(t, err)
khenaidoo9beaaf12021-10-19 17:32:01 -04001304 assert.Equal(t, resp.Result, omci.TestResponse_SUCCESS)
khenaidood948f772021-08-11 17:49:24 -04001305
1306 //Remove the device
1307 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, false)
1308 assert.Nil(t, err)
1309}
1310
1311func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
1312 matchFields := make([]*ofp.OfpOxmField, 0)
1313 for _, val := range fa.MatchFields {
1314 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
1315 }
1316 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
1317}
1318
1319func createMetadata(cTag int, techProfile int, port int) uint64 {
1320 md := 0
1321 md = (md | (cTag & 0xFFFF)) << 16
1322 md = (md | (techProfile & 0xFFFF)) << 32
1323 return uint64(md | (port & 0xFFFFFFFF))
1324}
1325
1326func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string, numNNIPorts int, numUNIPorts int, flowAddFail bool) {
1327 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
1328 if flowAddFail {
1329 expectedNumFlows = 0
1330 }
1331
1332 // Wait for logical device to have the flows (or none
1333 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
1334 f, _ := nbi.ListLogicalDeviceFlows(getContext(), &voltha.ID{Id: ld.Id})
1335 return f != nil && len(f.Items) == expectedNumFlows
1336 }
1337 // No timeout implies a success
1338 err := waitUntilLogicalDeviceReadiness(oltDeviceID, nb.maxTimeout, nbi, vlFunction)
1339 assert.Nil(t, err)
1340}
1341
1342func (nb *NBTest) sendTrapFlows(t *testing.T, nbi voltha.VolthaServiceClient, logicalDeviceID string, ports []*voltha.LogicalPort, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
1343 // Send flows for the parent device
1344 var nniPorts []*voltha.LogicalPort
1345 var uniPorts []*voltha.LogicalPort
1346 for _, p := range ports {
1347 if p.RootPort {
1348 nniPorts = append(nniPorts, p)
1349 } else {
1350 uniPorts = append(uniPorts, p)
1351 }
1352 }
1353 assert.Equal(t, 1, len(nniPorts))
1354 //assert.Greater(t, len(uniPorts), 1 )
1355 nniPort := nniPorts[0].OfpPort.PortNo
1356 maxInt32 := uint64(0xFFFFFFFF)
1357 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1358 var fa *flows.FlowArgs
1359 fa = &flows.FlowArgs{
1360 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1361 MatchFields: []*ofp.OfpOxmOfbField{
1362 flows.InPort(nniPort),
1363 flows.EthType(35020),
1364 },
1365 Actions: []*ofp.OfpAction{
1366 flows.Output(controllerPortMask),
1367 },
1368 }
1369 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1370 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
1371 assert.Nil(t, err)
1372
1373 fa = &flows.FlowArgs{
1374 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1375 MatchFields: []*ofp.OfpOxmOfbField{
1376 flows.InPort(nniPort),
1377 flows.EthType(2048),
1378 flows.IpProto(17),
1379 flows.UdpSrc(67),
1380 flows.UdpDst(68),
1381 },
1382 Actions: []*ofp.OfpAction{
1383 flows.Output(controllerPortMask),
1384 },
1385 }
1386 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1387 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
1388 assert.Nil(t, err)
1389
1390 fa = &flows.FlowArgs{
1391 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1392 MatchFields: []*ofp.OfpOxmOfbField{
1393 flows.InPort(nniPort),
1394 flows.EthType(34525),
1395 flows.IpProto(17),
1396 flows.UdpSrc(546),
1397 flows.UdpDst(547),
1398 },
1399 Actions: []*ofp.OfpAction{
1400 flows.Output(controllerPortMask),
1401 },
1402 }
1403 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1404 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
1405 assert.Nil(t, err)
1406
1407 return len(nniPorts), len(uniPorts)
1408}
1409
1410func (nb *NBTest) sendEAPFlows(t *testing.T, nbi voltha.VolthaServiceClient, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
1411 maxInt32 := uint64(0xFFFFFFFF)
1412 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1413 fa := &flows.FlowArgs{
1414 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1, "write_metadata": createMetadata(vlan, 64, 0), "meter_id": meterID},
1415 MatchFields: []*ofp.OfpOxmOfbField{
1416 flows.InPort(port.PortNo),
1417 flows.EthType(34958),
1418 flows.VlanVid(8187),
1419 },
1420 Actions: []*ofp.OfpAction{
1421 flows.Output(controllerPortMask),
1422 },
1423 }
1424 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1425 maxTries := 3
1426 var err error
1427 for {
1428 if _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP); err == nil {
1429 if maxTries < 3 {
1430 t.Log("Re-sending EAPOL flow succeeded for port:", port)
1431 }
1432 break
1433 }
1434 t.Log("Sending EAPOL flows fail:", err)
1435 time.Sleep(50 * time.Millisecond)
1436 maxTries--
1437 if maxTries == 0 {
1438 break
1439 }
1440 }
1441 assert.Nil(t, err)
1442}
1443
1444func (nb *NBTest) receiveChangeEvents(ctx context.Context, nbi voltha.VolthaServiceClient, ch chan *ofp.ChangeEvent) {
1445 opt := grpc.EmptyCallOption{}
1446 streamCtx, streamDone := context.WithCancel(log.WithSpanFromContext(context.Background(), ctx))
1447 defer streamDone()
1448 stream, err := nbi.ReceiveChangeEvents(streamCtx, &empty.Empty{}, opt)
1449 if err != nil {
1450 logger.Errorw(ctx, "cannot-establish-receive-change-events", log.Fields{"error": err})
1451 return
1452 }
1453
1454 for {
1455 ce, err := stream.Recv()
1456 if err == nil {
1457 ch <- ce
1458 continue
1459 }
1460 if err == io.EOF || strings.Contains(err.Error(), "Unavailable") {
1461 logger.Debug(context.Background(), "receive-events-stream-closing")
1462 } else {
1463 logger.Errorw(ctx, "error-receiving-change-event", log.Fields{"error": err})
1464 }
1465 return
1466 }
1467}
1468
1469func (nb *NBTest) getOLTAdapterInstance(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string) (*cm.OLTAdapter, error) {
1470 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
1471 assert.Nil(t, err)
1472 nb.oltAdaptersLock.RLock()
1473 defer nb.oltAdaptersLock.RUnlock()
1474 for _, d := range devices.Items {
1475 if d.Id == oltDeviceID {
1476 for _, oltAdapters := range nb.oltAdapters {
1477 for _, oAdapter := range oltAdapters {
1478 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1479 return oAdapter, nil
1480 }
1481 }
1482 }
1483 }
1484 }
1485 return nil, fmt.Errorf("no-adapter-for-%s", oltDeviceID)
1486}
1487
1488func (nb *NBTest) getAdapterInstancesWithDeviceIds(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string) (*cm.OLTAdapter, map[string]*cm.ONUAdapter, []string, error) {
1489 var oltAdapter *cm.OLTAdapter
1490 onuAdapters := make(map[string]*cm.ONUAdapter)
1491 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
1492 onuDeviceIDs := make([]string, 0)
1493 assert.Nil(t, err)
1494 oltAdapterFound := false
1495 nb.oltAdaptersLock.RLock()
1496 defer nb.oltAdaptersLock.RUnlock()
1497 nb.onuAdaptersLock.RLock()
1498 defer nb.onuAdaptersLock.RUnlock()
1499 for _, d := range devices.Items {
1500 if !oltAdapterFound && d.Id == oltDeviceID {
1501 for _, oltAdapters := range nb.oltAdapters {
1502 for _, oAdapter := range oltAdapters {
1503 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1504 oltAdapter = oAdapter
1505 oltAdapterFound = true
1506 }
1507 }
1508 }
1509 }
1510 // We can have multiple ONU adapters managing the ONU devices off an OLT
1511 if !d.Root && d.ParentId == oltDeviceID {
1512 onuDeviceIDs = append(onuDeviceIDs, d.Id)
1513 for _, adapters := range nb.onuAdapters {
1514 for _, oAdapter := range adapters {
1515 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1516 onuAdapters[d.AdapterEndpoint] = oAdapter
1517 }
1518 }
1519 }
1520 }
1521 }
1522 if len(onuAdapters) > 0 && oltAdapter != nil && len(onuDeviceIDs) > 0 {
1523 return oltAdapter, onuAdapters, onuDeviceIDs, nil
1524 }
1525 return nil, nil, nil, fmt.Errorf("no-adapter-for-%s", oltDeviceID)
1526}
1527
1528func (nb *NBTest) monitorLogicalDevices(
1529 ctx context.Context,
1530 t *testing.T,
1531 nbi voltha.VolthaServiceClient,
1532 numNNIPorts int,
1533 numUNIPorts int,
1534 wg *sync.WaitGroup,
1535 flowAddFail bool,
1536 flowDeleteFail bool,
1537 oltID string,
1538 eventCh chan *ofp.ChangeEvent) {
1539
1540 defer wg.Done()
1541
1542 // Wait until a logical device is ready
1543 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
1544 if lds == nil || len(lds.Items) == 0 {
1545 return false
1546 }
1547 // Ensure there are both NNI ports and at least one UNI port on the logical devices discovered
1548 for _, ld := range lds.Items {
1549 if ld.RootDeviceId != oltID {
1550 continue
1551 }
1552 ports, err := nbi.ListLogicalDevicePorts(getContext(), &voltha.ID{Id: ld.Id})
1553 if err != nil {
1554 return false
1555 }
1556 return len(ports.Items) == numNNIPorts+numUNIPorts // wait until all logical ports are created
1557 }
1558 return false
1559 }
1560 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
1561 assert.Nil(t, err)
1562
1563 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
1564 assert.Nil(t, err)
1565 assert.NotNil(t, logicalDevices)
1566 var logicalDevice *voltha.LogicalDevice
1567 for _, ld := range logicalDevices.Items {
1568 if ld.RootDeviceId == oltID {
1569 logicalDevice = ld
1570 break
1571 }
1572 }
1573 assert.NotNil(t, logicalDevice)
1574 logicalDeviceID := logicalDevice.Id
1575
1576 // Figure out the olt and onuAdapter being used by that logicalDeviceld\DeviceId
1577 // Clear any existing flows on these adapters
1578 oltAdapter, onuAdapters, onuDeviceIDs, err := nb.getAdapterInstancesWithDeviceIds(t, nbi, oltID)
1579 assert.Nil(t, err)
1580 assert.NotNil(t, oltAdapter)
1581 assert.Greater(t, len(onuAdapters), 0)
1582
1583 // Clear flows for that olt device and set the flow action
1584 oltAdapter.RemoveDevice(oltID)
1585 oltAdapter.SetFlowAction(oltID, flowAddFail, flowDeleteFail)
1586
1587 // Clear flows for the onu devices and set the flow action
1588 for _, a := range onuAdapters {
1589 for _, id := range onuDeviceIDs {
1590 a.RemoveDevice(id)
1591 a.SetFlowAction(id, flowAddFail, flowDeleteFail)
1592 }
1593 }
1594
1595 meterID := rand.Uint32()
1596
1597 // Add a meter to the logical device
1598 meterMod := &ofp.OfpMeterMod{
1599 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1600 Flags: rand.Uint32(),
1601 MeterId: meterID,
1602 Bands: []*ofp.OfpMeterBandHeader{
1603 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1604 Rate: rand.Uint32(),
1605 BurstSize: rand.Uint32(),
1606 Data: nil,
1607 },
1608 },
1609 }
1610 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{Id: logicalDeviceID, MeterMod: meterMod})
1611 assert.Nil(t, err)
1612
1613 ports, err := nbi.ListLogicalDevicePorts(getContext(), &voltha.ID{Id: logicalDeviceID})
1614 assert.Nil(t, err)
1615
1616 // Send initial set of Trap flows
1617 startingVlan := 4091
1618 nb.sendTrapFlows(t, nbi, logicalDeviceID, ports.Items, uint64(meterID), startingVlan)
1619
1620 //Listen for port events
1621 processedNniLogicalPorts := 0
1622 processedUniLogicalPorts := 0
1623
1624 for event := range eventCh {
1625 if event.Id != logicalDeviceID {
1626 continue
1627 }
1628 startingVlan++
1629 if portStatus, ok := (event.Event).(*ofp.ChangeEvent_PortStatus); ok {
1630 ps := portStatus.PortStatus
1631 if ps.Reason == ofp.OfpPortReason_OFPPR_ADD {
1632 if ps.Desc.PortNo >= uint32(nb.startingUNIPortNo) {
1633 processedUniLogicalPorts++
1634 nb.sendEAPFlows(t, nbi, logicalDeviceID, ps.Desc, startingVlan, uint64(meterID))
1635 } else {
1636 processedNniLogicalPorts++
1637 }
1638 }
1639 }
1640
1641 if processedNniLogicalPorts >= numNNIPorts && processedUniLogicalPorts >= numUNIPorts {
1642 break
1643 }
1644 }
1645
1646 //Verify the flow count on the logical device
1647 nb.verifyLogicalDeviceFlowCount(t, nbi, oltID, numNNIPorts, numUNIPorts, flowAddFail)
1648
1649 // Wait until all flows have been sent to the OLT adapters (or all failed)
1650 expectedFlowCount := (numNNIPorts * 3) + numNNIPorts*numUNIPorts
1651 if flowAddFail {
1652 expectedFlowCount = 0
1653 }
1654 var oltVFunc isConditionSatisfied = func() bool {
1655 return oltAdapter.GetFlowCount(oltID) >= expectedFlowCount
1656 }
1657 err = waitUntilCondition(nb.maxTimeout, oltVFunc)
1658 assert.Nil(t, err)
1659
1660 // Wait until all flows have been sent to the ONU adapters (or all failed)
1661 expectedFlowCount = numUNIPorts
1662 if flowAddFail {
1663 expectedFlowCount = 0
1664 }
1665 var onuVFunc isConditionSatisfied = func() bool {
1666 count := 0
1667 for _, a := range onuAdapters {
1668 for _, id := range onuDeviceIDs {
1669 count = count + a.GetFlowCount(id)
1670 }
1671 }
1672 return count == expectedFlowCount
1673 }
1674 err = waitUntilCondition(nb.maxTimeout, onuVFunc)
1675 assert.Nil(t, err)
1676}
1677
1678func (nb *NBTest) testFlowAddFailure(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1679 // Subscribe to the event listener
1680 eventCh := nb.changeEventLister.Subscribe((nb.numONUPerOLT + 1) * nb.getNumAdapters())
1681
1682 defer nb.changeEventLister.Unsubscribe(eventCh)
1683
1684 // Create and enable device with valid data
1685 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1686 assert.Nil(t, err)
1687 assert.NotNil(t, oltDevice)
1688
1689 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
1690 var wg sync.WaitGroup
1691 wg.Add(1)
1692 subCtx, cancel := context.WithCancel(context.Background())
1693 defer cancel()
1694 go nb.monitorLogicalDevices(subCtx, t, nbi, 1, nb.numONUPerOLT, &wg, true, false, oltDevice.Id, eventCh)
1695
1696 // Wait for the logical device to be in the ready state
1697 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1698 return len(ports) == nb.numONUPerOLT+1
1699 }
1700 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1701 assert.Nil(t, err)
1702
1703 // Verify that the devices have been setup correctly
1704 nb.verifyDevices(t, nbi, oltDevice.Id)
1705
1706 // Get latest oltDevice data
1707 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1708 assert.Nil(t, err)
1709
1710 // Verify that the logical device has been setup correctly
1711 nb.verifyLogicalDevices(t, oltDevice, nbi)
1712
1713 // Wait until all flows has been sent to the devices successfully
1714 wg.Wait()
1715
1716 //Remove the device
1717 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1718 assert.Nil(t, err)
1719}
1720
1721func (nb *NBTest) testMPLSFlowsAddition(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
khenaidood948f772021-08-11 17:49:24 -04001722 // Create and enable device with valid data
1723 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1724 assert.Nil(t, err)
1725 assert.NotNil(t, oltDevice)
1726
1727 // Wait for the logical device to be in the ready state
1728 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1729 return len(ports) == nb.numONUPerOLT+1
1730 }
1731 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1732 assert.Nil(t, err)
1733
1734 // Get latest oltDevice data
1735 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1736 assert.Nil(t, err)
1737 assert.NotNil(t, oltDevice)
1738 testLogger.Infow(getContext(), "olt-device-created-and-verified", log.Fields{"device-id": oltDevice.GetId()})
1739
1740 // Verify that the logical device has been setup correctly
1741 nb.verifyLogicalDevices(t, oltDevice, nbi)
1742
1743 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
khenaidoo5d126902021-10-07 10:04:43 -04001744 assert.Nil(t, err)
1745 assert.NotNil(t, logicalDevices)
1746 var logicalDevice *voltha.LogicalDevice
1747 for _, ld := range logicalDevices.Items {
1748 if ld.RootDeviceId == oltDevice.Id {
1749 logicalDevice = ld
1750 break
1751 }
1752 }
1753 assert.NotNil(t, logicalDevice)
khenaidood948f772021-08-11 17:49:24 -04001754
khenaidoo5d126902021-10-07 10:04:43 -04001755 testLogger.Infow(getContext(), "list-logical-devices", log.Fields{"logical-device": logicalDevice})
khenaidood948f772021-08-11 17:49:24 -04001756 // Add a meter to the logical device, which the flow can refer to
1757 meterMod := &ofp.OfpMeterMod{
1758 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1759 Flags: rand.Uint32(),
1760 MeterId: 1,
1761 Bands: []*ofp.OfpMeterBandHeader{
1762 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1763 Rate: rand.Uint32(),
1764 BurstSize: rand.Uint32(),
1765 Data: nil,
1766 },
1767 },
1768 }
1769 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{
1770 Id: logicalDevices.GetItems()[0].GetId(),
1771 MeterMod: meterMod,
1772 })
1773 assert.NoError(t, err)
1774
khenaidoo5d126902021-10-07 10:04:43 -04001775 meters, err := nbi.ListLogicalDeviceMeters(getContext(), &voltha.ID{Id: logicalDevice.Id})
khenaidood948f772021-08-11 17:49:24 -04001776 assert.NoError(t, err)
1777
1778 for _, item := range meters.GetItems() {
1779 testLogger.Infow(getContext(), "list-logical-device-meters", log.Fields{"meter-config": item.GetConfig()})
1780 }
1781
khenaidoo5d126902021-10-07 10:04:43 -04001782 logicalPorts, err := nbi.ListLogicalDevicePorts(context.Background(), &voltha.ID{Id: logicalDevice.Id})
khenaidood948f772021-08-11 17:49:24 -04001783 assert.NoError(t, err)
1784 m := jsonpb.Marshaler{}
1785 logicalPortsJson, err := m.MarshalToString(logicalPorts)
1786 assert.NoError(t, err)
1787
1788 testLogger.Infow(getContext(), "list-logical-ports", log.Fields{"ports": logicalPortsJson})
1789
1790 callables := []func() *ofp.OfpFlowMod{getOnuUpstreamRules, getOltUpstreamRules, getOLTDownstreamMplsSingleTagRules,
1791 getOLTDownstreamMplsDoubleTagRules, getOLTDownstreamRules, getOnuDownstreamRules}
1792
1793 for _, callable := range callables {
khenaidoo5d126902021-10-07 10:04:43 -04001794 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &ofp.FlowTableUpdate{Id: logicalDevice.Id, FlowMod: callable()})
khenaidood948f772021-08-11 17:49:24 -04001795 assert.NoError(t, err)
1796 }
1797
1798 //Remove the device
1799 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1800 assert.Nil(t, err)
1801}
1802
1803func getOnuUpstreamRules() (flowMod *ofp.OfpFlowMod) {
1804 fa := &flows.FlowArgs{
1805 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1, "meter_id": 1, "write_metadata": 4100100000},
1806 MatchFields: []*ofp.OfpOxmOfbField{
1807 flows.InPort(103),
1808 flows.VlanVid(4096),
1809 },
1810 Actions: []*ofp.OfpAction{},
1811 }
1812
1813 flowMod = makeSimpleFlowMod(fa)
1814 flowMod.TableId = 0
1815 m := jsonpb.Marshaler{}
1816 flowModJson, _ := m.MarshalToString(flowMod)
1817 testLogger.Infow(getContext(), "onu-upstream-flow", log.Fields{"flow-mod": flowModJson})
1818 return
1819}
1820
1821func getOltUpstreamRules() (flowMod *ofp.OfpFlowMod) {
1822 fa := &flows.FlowArgs{
1823 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1, "meter_id": 1, "write_metadata": 4100000000},
1824 MatchFields: []*ofp.OfpOxmOfbField{
1825 flows.InPort(103),
1826 flows.VlanVid(4096),
1827 },
1828 Actions: []*ofp.OfpAction{
1829 flows.PushVlan(0x8100),
1830 flows.SetField(flows.VlanVid(2)),
1831 flows.SetField(flows.EthSrc(1111)),
1832 flows.SetField(flows.EthDst(2222)),
1833 flows.PushVlan(0x8847),
1834 flows.SetField(flows.MplsLabel(100)),
1835 flows.SetField(flows.MplsBos(1)),
1836 flows.PushVlan(0x8847),
1837 flows.SetField(flows.MplsLabel(200)),
1838 flows.MplsTtl(64),
1839 flows.Output(2),
1840 },
1841 }
1842 flowMod = makeSimpleFlowMod(fa)
1843 flowMod.TableId = 1
1844 m := jsonpb.Marshaler{}
1845 flowModJson, _ := m.MarshalToString(flowMod)
1846 testLogger.Infow(getContext(), "olt-upstream-flow", log.Fields{"flow-mod": flowModJson})
1847 return
1848}
1849
1850func getOLTDownstreamMplsSingleTagRules() (flowMod *ofp.OfpFlowMod) {
1851 fa := &flows.FlowArgs{
1852 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1853 MatchFields: []*ofp.OfpOxmOfbField{
1854 flows.InPort(2),
1855 flows.Metadata_ofp((1000 << 32) | 1),
1856 flows.EthType(0x8847),
1857 flows.MplsBos(1),
1858 flows.EthSrc(2222),
1859 },
1860 Actions: []*ofp.OfpAction{
1861 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1862 flows.PopMpls(0x8847),
1863 },
1864 }
1865 flowMod = makeSimpleFlowMod(fa)
1866 flowMod.TableId = 0
1867 m := jsonpb.Marshaler{}
1868 flowModJson, _ := m.MarshalToString(flowMod)
1869 testLogger.Infow(getContext(), "olt-mpls-downstream-single-tag-flow", log.Fields{"flow-mod": flowModJson})
1870 return
1871}
1872
1873func getOLTDownstreamMplsDoubleTagRules() (flowMod *ofp.OfpFlowMod) {
1874 fa := &flows.FlowArgs{
1875 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1876 MatchFields: []*ofp.OfpOxmOfbField{
1877 flows.InPort(2),
1878 flows.EthType(0x8847),
1879 flows.EthSrc(2222),
1880 },
1881 Actions: []*ofp.OfpAction{
1882 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1883 flows.PopMpls(0x8847),
1884 flows.PopMpls(0x8847),
1885 },
1886 }
1887 flowMod = makeSimpleFlowMod(fa)
1888 flowMod.TableId = 0
1889 m := jsonpb.Marshaler{}
1890 flowModJson, _ := m.MarshalToString(flowMod)
1891 testLogger.Infow(getContext(), "olt-mpls-downstream-double-tagged-flow", log.Fields{"flow-mod": flowModJson})
1892 return
1893}
1894
1895func getOLTDownstreamRules() (flowMod *ofp.OfpFlowMod) {
1896 fa := &flows.FlowArgs{
1897 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 2, "meter_id": 1},
1898 MatchFields: []*ofp.OfpOxmOfbField{
1899 flows.InPort(2),
1900 flows.VlanVid(2),
1901 },
1902 Actions: []*ofp.OfpAction{
1903 flows.PopVlan(),
1904 },
1905 }
1906 flowMod = makeSimpleFlowMod(fa)
1907 flowMod.TableId = 1
1908 m := jsonpb.Marshaler{}
1909 flowModJson, _ := m.MarshalToString(flowMod)
1910 testLogger.Infow(getContext(), "olt-downstream-flow", log.Fields{"flow-mod": flowModJson})
1911 return
1912}
1913
1914func getOnuDownstreamRules() (flowMod *ofp.OfpFlowMod) {
1915 fa := &flows.FlowArgs{
1916 KV: flows.OfpFlowModArgs{"priority": 1000, "meter_id": 1},
1917 MatchFields: []*ofp.OfpOxmOfbField{
1918 flows.InPort(2),
1919 flows.Metadata_ofp((1000 << 32) | 1),
1920 flows.VlanVid(4096),
1921 },
1922 Actions: []*ofp.OfpAction{
1923 flows.Output(103),
1924 },
1925 }
1926 flowMod = makeSimpleFlowMod(fa)
1927 flowMod.TableId = 2
1928 m := jsonpb.Marshaler{}
1929 flowModJson, _ := m.MarshalToString(flowMod)
1930 testLogger.Infow(getContext(), "onu-downstream-flow", log.Fields{"flow-mod": flowModJson})
1931 return
1932}
1933
1934func (nb *NBTest) runTestSuite(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string, testWg *sync.WaitGroup) {
1935 defer testWg.Done()
1936
1937 // Test create device
1938 nb.testCreateDevice(t, nbi, oltDeviceType)
1939
1940 //Test Delete Device Scenarios
1941 nb.testForceDeletePreProvDevice(t, nbi, oltDeviceType)
1942 nb.testDeletePreProvDevice(t, nbi, oltDeviceType)
1943 nb.testForceDeleteEnabledDevice(t, nbi, oltDeviceType)
1944 nb.testDeleteEnabledDevice(t, nbi, oltDeviceType)
1945 nb.testForceDeleteDeviceFailure(t, nbi, oltDeviceType)
1946 nb.testDeleteDeviceFailure(t, nbi, oltDeviceType)
1947
1948 ////Test failed enable device
1949 nb.testEnableDeviceFailed(t, nbi, oltDeviceType)
1950
1951 //Test Enable a device
1952 nb.testEnableDevice(t, nbi, oltDeviceType)
1953
1954 //Test disable and ReEnable a root device
1955 nb.testDisableAndReEnableRootDevice(t, nbi, oltDeviceType)
1956
1957 // Test disable and Enable pon port of OLT device
1958 nb.testDisableAndEnablePort(t, nbi, oltDeviceType)
1959
1960 // Test Device unreachable when OLT is enabled
1961 nb.testDeviceRebootWhenOltIsEnabled(t, nbi, oltDeviceType)
1962
1963 // Test disable and delete all devices
1964 nb.testDisableAndDeleteAllDevice(t, nbi, oltDeviceType)
1965
1966 // Test enable and delete all devices
1967 nb.testEnableAndDeleteAllDevice(t, nbi, oltDeviceType)
1968
1969 // Test omci test
1970 nb.testStartOmciTestAction(t, nbi, oltDeviceType)
1971
1972 // Test flow add failure
1973 nb.testFlowAddFailure(t, nbi, oltDeviceType)
1974
1975 // Test MPLS flows addition where:
1976 /*
1977 Upstream
1978 ONU
1979 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:32, VLAN_VID:ANY], treatment=[immediate=[],
1980 transition=TABLE:1, meter=METER:1, metadata=METADATA:4100010000/0]
1981 OLT
1982 ADDED, bytes=0, packets=0, table=1, priority=1000, selector=[IN_PORT:32, VLAN_VID:ANY], treatment=[immediate=[VLAN_PUSH:vlan,
1983 VLAN_ID:2, MPLS_PUSH:mpls_unicast, MPLS_LABEL:YYY,MPLS_BOS:true, MPLS_PUSH:mpls_unicast ,MPLS_LABEL:XXX, MPLS_BOS:false,
1984 EXTENSION:of:0000000000000227/VolthaPushL2Header{​​​​​​​}​​​​​​​, ETH_SRC:OLT_MAC, ETH_DST:LEAF_MAC, TTL:64, OUTPUT:65536],
1985 meter=METER:1, metadata=METADATA:4100000000/0]
1986
1987 Downstream
1988 OLT
1989 //Below flow rule to pop L2 Ethernet headers from packets which have a single MPLS label
1990 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:65536, ETH_TYPE:mpls_unicast, MPLS_BOS:true, ETH_SRC:LEAF_MAC],
1991 treatment=[DefaultTrafficTreatment{immediate=[DEC_MPLS_TTL, TTL_IN, MPLS_POP:mpls_unicast, EXTENSION:of:0000000000000227/VolthaPopL2Header{},
1992 transition=TABLE:1]
1993
1994 //Below flow rule to pop L2 Ethernet headers from packets which have two MPLS label
1995 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:65536, ETH_TYPE:mpls_unicast, MPLS_BOS:false, ETH_SRC:LEAF_MAC],
1996 treatment=[DefaultTrafficTreatment{immediate=[DEC_MPLS_TTL, TTL_IN, MPLS_POP:mpls_unicast, MPLS_POP:mpls_unicast ,
1997 EXTENSION:of:0000000000000227/VolthaPopL2Header{}, transition=TABLE:1]
1998
1999 //Below flow rules are unchanged from the current implementations except for the table numbers
2000 ADDED, bytes=0, packets=0, table=1, priority=1000, selector=[IN_PORT:65536, VLAN_VID:2], treatment=[immediate=[VLAN_POP], transition=TABLE:2,
2001 meter=METER:2, metadata=METADATA:1000004100000020/0]
2002 ONU
2003 ADDED, bytes=0, packets=0, table=2, priority=1000, selector=[IN_PORT:65536, METADATA:20 VLAN_VID:ANY], treatment=[immediate=[OUTPUT:32],
2004 meter=METER:2, metadata=METADATA:4100000000/0]
2005 */
2006 nb.testMPLSFlowsAddition(t, nbi, oltDeviceType)
2007}
2008
2009func setUpCore(ctx context.Context, t *testing.T, nb *NBTest) (voltha.VolthaServiceClient, string) {
2010 // Start the Core
2011 coreAPIEndpoint, nbiEndpoint := nb.startGRPCCore(ctx, t)
2012
2013 // Wait until the core is ready
2014 start := time.Now()
2015 logger.Infow(ctx, "waiting-for-core-to-be-ready", log.Fields{"start": start, "api-endpoint": coreAPIEndpoint})
2016
2017 var vFunction isConditionSatisfied = func() bool {
2018 return nb.probe.IsReady()
2019 }
2020 err := waitUntilCondition(nb.internalTimeout, vFunction)
2021 assert.Nil(t, err)
2022 logger.Infow(ctx, "core-is-ready", log.Fields{"time-taken": time.Since(start)})
2023
2024 // Create a grpc client to communicate with the Core
2025 conn, err := grpc.Dial(nbiEndpoint, grpc.WithInsecure())
2026 if err != nil {
2027 logger.Fatalw(ctx, "cannot connect to core", log.Fields{"error": err})
2028 }
2029 nbi := voltha.NewVolthaServiceClient(conn)
2030 if nbi == nil {
2031 logger.Fatalw(ctx, "cannot create a service to core", log.Fields{"error": err})
2032 }
2033
2034 // Basic test with no data in Core
2035 nb.testCoreWithoutData(t, nbi)
2036
2037 logger.Infow(ctx, "core-setup-complete", log.Fields{"time": time.Since(start), "api-endpoint": coreAPIEndpoint})
2038
2039 return nbi, coreAPIEndpoint
2040}
2041
2042func setupAdapters(ctx context.Context, t *testing.T, nb *NBTest, coreAPIEndpoint string, nbi voltha.VolthaServiceClient) {
2043 // Create/register the adapters
2044 start := time.Now()
2045 nb.oltAdaptersLock.Lock()
2046 nb.onuAdaptersLock.Lock()
2047 nb.oltAdapters, nb.onuAdapters = CreateAndRegisterAdapters(ctx, t, oltAdapters, onuAdapters, coreAPIEndpoint)
2048 nb.oltAdaptersLock.Unlock()
2049 nb.onuAdaptersLock.Unlock()
2050
2051 nb.numONUPerOLT = cm.GetNumONUPerOLT()
2052 nb.startingUNIPortNo = cm.GetStartingUNIPortNo()
2053
2054 // Wait for adapters to be fully running
2055 var areAdaptersRunning isConditionSatisfied = func() bool {
2056 ready := true
khenaidoo5d126902021-10-07 10:04:43 -04002057 nb.onuAdaptersLock.RLock()
2058 defer nb.onuAdaptersLock.RUnlock()
khenaidood948f772021-08-11 17:49:24 -04002059 for _, adapters := range nb.onuAdapters {
2060 for _, a := range adapters {
2061 ready = ready && a.IsReady()
2062 if !ready {
2063 return false
2064 }
2065 }
2066 }
khenaidoo5d126902021-10-07 10:04:43 -04002067 nb.oltAdaptersLock.RLock()
2068 defer nb.oltAdaptersLock.RUnlock()
khenaidood948f772021-08-11 17:49:24 -04002069 for _, adapters := range nb.oltAdapters {
2070 for _, a := range adapters {
2071 ready = ready && a.IsReady()
2072 if !ready {
2073 return false
2074 }
2075 }
2076 }
2077 return true
2078 }
2079 err := waitUntilCondition(nb.internalTimeout, areAdaptersRunning)
2080 assert.Nil(t, err)
2081 logger.Infow(ctx, "adapters-are-ready", log.Fields{"time-taken": time.Since(start)})
2082
2083 // Test adapter registration
2084 nb.testAdapterRegistration(t, nbi)
2085}
2086
khenaidoo5d126902021-10-07 10:04:43 -04002087func WaitForCoreConnectionToAdapters(ctx context.Context, t *testing.T, nb *NBTest, nbi voltha.VolthaServiceClient) {
2088 // Create/register the adapters
2089 start := time.Now()
2090 numAdapters := 0
2091 nb.oltAdaptersLock.RLock()
2092 numAdapters += len(nb.onuAdapters)
2093 nb.oltAdaptersLock.RUnlock()
2094 nb.onuAdaptersLock.RLock()
2095 numAdapters += len(nb.oltAdapters)
2096 nb.onuAdaptersLock.RUnlock()
2097
2098 // Wait for adapters to be fully running
2099 var isCoreConnectedToAdapters isConditionSatisfied = func() bool {
2100 adpts, err := nbi.ListAdapters(getContext(), &empty.Empty{})
2101 if err != nil || len(adpts.Items) < numAdapters {
2102 return false
2103 }
2104 // Now check the last communication time
2105 for _, adpt := range adpts.Items {
2106 if time.Since(time.Unix(adpt.LastCommunication, 0)) > 5*time.Second {
2107 return false
2108 }
2109 }
2110 return true
2111 }
2112 err := waitUntilCondition(nb.internalTimeout, isCoreConnectedToAdapters)
2113 assert.Nil(t, err)
2114 logger.Infow(ctx, "core-connection-to-adapters-is-ready", log.Fields{"time-taken": time.Since(start)})
2115
2116 // Test adapter registration
2117 nb.testAdapterRegistration(t, nbi)
2118}
2119
khenaidood948f772021-08-11 17:49:24 -04002120//TestLogDeviceUpdate is used to extract and format device updates. Not to be run on jenkins.
2121func TestLogDeviceUpdate(t *testing.T) {
2122 t.Skip()
2123 var inputFile = os.Getenv("LGF")
2124 var deviceID = os.Getenv("DID")
2125
2126 prettyPrintDeviceUpdateLog(inputFile, deviceID)
2127}
2128
2129func TestOMCIData(t *testing.T) {
2130 t.Skip()
2131 var inputFile = os.Getenv("LGF")
2132 var deviceID = os.Getenv("DID")
2133 omciLog(inputFile, deviceID)
2134}
2135
2136func TestRandomMacGenerator(t *testing.T) {
2137 t.Skip()
2138 var wg sync.WaitGroup
2139 myMap := make(map[string]int)
2140 var myMapLock sync.Mutex
2141 max := 1000000
2142 for i := 0; i < max; i++ {
2143 wg.Add(1)
2144 go func() {
2145 str := getRandomMacAddress()
2146 myMapLock.Lock()
2147 myMap[str]++
2148 myMapLock.Unlock()
2149 wg.Done()
2150 }()
2151 }
2152 wg.Wait()
2153 // Look for duplicates
2154 for str, val := range myMap {
2155 if val != 1 {
2156 fmt.Println("duplicate", str)
2157 }
2158 }
2159}
2160
2161func TestSuite(t *testing.T) {
khenaidoo25057da2021-12-08 14:40:45 -05002162 log.SetAllLogLevel(log.DebugLevel)
khenaidood948f772021-08-11 17:49:24 -04002163
2164 // Create a context to be cancelled at the end of all tests. This will trigger closing of any ressources used.
2165 ctx, cancel := context.WithCancel(context.Background())
2166
2167 // Setup CPU profiling
2168 f, err := os.Create("grpc_profile.cpu")
2169 // f, err := os.Create("../../../tests/results/grpc_profile.cpu")
2170 if err != nil {
2171 logger.Fatalf(ctx, "could not create CPU profile: %v\n ", err)
2172 }
2173 defer f.Close()
2174 runtime.SetBlockProfileRate(1)
2175 runtime.SetMutexProfileFraction(-1)
2176 runtime.SetCPUProfileRate(200)
2177 if err := pprof.StartCPUProfile(f); err != nil {
2178 logger.Fatalf(ctx, "could not start CPU profile: %v\n", err)
2179 }
2180 defer pprof.StopCPUProfile()
2181
2182 // Create test object
2183 nb := newNBTest(ctx, false)
2184 assert.NotNil(t, nb)
2185 defer nb.stopAll(ctx)
2186
2187 // Setup the Core
2188 nbi, coreAPIEndpoint := setUpCore(ctx, t, nb)
2189
2190 // Setup the adapters
2191 setupAdapters(ctx, t, nb, coreAPIEndpoint, nbi)
2192
khenaidoo5d126902021-10-07 10:04:43 -04002193 // Wait until the Core can connect to the adapters
2194 WaitForCoreConnectionToAdapters(ctx, t, nb, nbi)
2195
khenaidood948f772021-08-11 17:49:24 -04002196 // Start the change events listener and dispatcher to receive all change events from the Core
2197 nb.changeEventLister = NewChangedEventListener(len(nb.oltAdapters))
2198 ch := make(chan *ofp.ChangeEvent, (nb.numONUPerOLT+1)*len(nb.oltAdapters))
2199 go nb.changeEventLister.Start(ctx, ch)
2200 go nb.receiveChangeEvents(ctx, nbi, ch)
2201
2202 // Run the full set of tests in parallel for each olt device type
2203 start := time.Now()
2204 fmt.Println("starting test at:", start)
2205 var wg sync.WaitGroup
2206 nb.oltAdaptersLock.RLock()
2207 numTestCycles := 1
2208 for i := 1; i <= numTestCycles; i++ {
2209 for oltAdapterType, oltAdapters := range nb.oltAdapters {
2210 for _, a := range oltAdapters {
2211 wg.Add(1)
2212 fmt.Printf("Launching test for OLT adapter type:%s supporting OLT device type:%s and ONU device type:%s\n", oltAdapterType, a.DeviceType, a.ChildDeviceType)
2213 go nb.runTestSuite(t, nbi, a.DeviceType, &wg)
2214 }
2215 }
2216 }
2217 nb.oltAdaptersLock.RUnlock()
2218
2219 // Wait for all tests to complete
2220 wg.Wait()
2221 fmt.Println("Execution time:", time.Since(start))
2222
2223 // Cleanup before leaving
2224 fmt.Println("Cleaning up ... grpc warnings can be safely ignored")
2225 cancel()
2226}