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