blob: a8f9a0e9152c4db92dae7d70e339f401b88f882d [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 {
266 nb.core.Stop()
267 }
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
1159 // Wait for the logical device to satisfy the expected condition
1160 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
1161 return ld == nil
1162 }
1163
1164 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
1165 assert.Nil(t, err)
1166
1167 // Wait for the device to satisfy the expected condition (device does not have flows)
1168 var vlFunction2 = func(d *voltha.Device) bool {
1169 var deviceFlows *ofp.Flows
1170 var err error
1171 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
1172 return false
1173 }
1174 return len(deviceFlows.Items) == 0
1175 }
1176
1177 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
1178 assert.Nil(t, err)
1179
1180 // Wait for the device to satisfy the expected condition (there are no child devices)
1181 var vlFunction3 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
1182 if (devices == nil) || (len(devices.Items) == 0) {
1183 return false
1184 }
1185 for _, d := range devices.Items {
1186 if !d.Root && d.ParentId == oltDevice.Id {
1187 return false
1188 }
1189 }
1190 return true
1191 }
1192 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vlFunction3)
1193 assert.Nil(t, err)
1194
1195 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
1196 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
1197 oltAdapter, err := nb.getOLTAdapterInstance(t, nbi, oltDevice.Id)
1198 assert.Nil(t, err)
1199 oltAdapter.SetDeviceActive(oltDevice.Id)
1200
1201 // Verify the device connection and operation states
1202 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1203 assert.Nil(t, err)
1204 assert.NotNil(t, oltDevice)
1205 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
1206 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
1207
1208 // Wait for the logical device to satisfy the expected condition
1209 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
1210 return ld != nil
1211 }
1212 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
1213 assert.Nil(t, err)
1214
1215 // Verify that we have no ONUs
1216 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
1217 assert.Nil(t, err)
1218 assert.NotNil(t, onuDevices)
1219 assert.Equal(t, 0, len(onuDevices.Items))
1220
1221 //Remove the device
1222 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1223 assert.Nil(t, err)
1224}
1225
1226func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1227 // -----------------------------------------------------------------------
1228 // SubTest 1: Omci test action should fail due to nonexistent device id
1229
khenaidoo9beaaf12021-10-19 17:32:01 -04001230 request := &omci.OmciTestRequest{Id: "123", Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001231 _, err := nbi.StartOmciTestAction(getContext(), request)
1232 assert.NotNil(t, err)
1233 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
1234
1235 // -----------------------------------------------------------------------
1236 // SubTest 2: Error should be returned for device with no adapter registered
1237
1238 // Create a device that has no adapter registered
1239 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: getRandomMacAddress()})
1240 assert.Nil(t, err)
1241 assert.NotNil(t, deviceNoAdapter)
1242
1243 // Omci test action should fail due to nonexistent adapter
khenaidoo9beaaf12021-10-19 17:32:01 -04001244 request = &omci.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001245 _, err = nbi.StartOmciTestAction(getContext(), request)
1246 assert.NotNil(t, err)
1247 assert.True(t, strings.Contains(err.Error(), "noAdapterRegisteredOmciTest"))
1248
1249 //Remove the device
1250 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
1251 assert.Nil(t, err)
1252
1253 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
1254 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
1255 if (devices == nil) || (len(devices.Items) == 0) {
1256 return true
1257 }
1258 for _, d := range devices.Items {
1259 if (d.Root && d.Id == deviceNoAdapter.Id) || (!d.Root && d.ParentId == deviceNoAdapter.Id) {
1260 return false
1261 }
1262 }
1263 return true
1264 }
1265 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
1266 assert.Nil(t, err)
1267
1268 // -----------------------------------------------------------------------
1269 // SubTest 3: Omci test action should succeed on valid ONU
1270
1271 // Create and enable device with valid data
1272 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1273 assert.Nil(t, err)
1274 assert.NotNil(t, oltDevice)
1275
1276 // Wait for the logical device to be in the ready state
1277 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1278 return len(ports) == nb.numONUPerOLT+1
1279 }
1280 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1281 assert.Nil(t, err)
1282
1283 onuDevices, err := nb.getChildDevices(oltDevice.Id, nbi)
1284 assert.Nil(t, err)
1285 assert.NotNil(t, onuDevices)
1286 assert.Greater(t, len(onuDevices.Items), 0)
1287
1288 onuDevice := onuDevices.Items[0]
1289
1290 // Omci test action should succeed
khenaidoo9beaaf12021-10-19 17:32:01 -04001291 request = &omci.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
khenaidood948f772021-08-11 17:49:24 -04001292 resp, err := nbi.StartOmciTestAction(getContext(), request)
1293 assert.Nil(t, err)
khenaidoo9beaaf12021-10-19 17:32:01 -04001294 assert.Equal(t, resp.Result, omci.TestResponse_SUCCESS)
khenaidood948f772021-08-11 17:49:24 -04001295
1296 //Remove the device
1297 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, false)
1298 assert.Nil(t, err)
1299}
1300
1301func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
1302 matchFields := make([]*ofp.OfpOxmField, 0)
1303 for _, val := range fa.MatchFields {
1304 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
1305 }
1306 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
1307}
1308
1309func createMetadata(cTag int, techProfile int, port int) uint64 {
1310 md := 0
1311 md = (md | (cTag & 0xFFFF)) << 16
1312 md = (md | (techProfile & 0xFFFF)) << 32
1313 return uint64(md | (port & 0xFFFFFFFF))
1314}
1315
1316func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string, numNNIPorts int, numUNIPorts int, flowAddFail bool) {
1317 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
1318 if flowAddFail {
1319 expectedNumFlows = 0
1320 }
1321
1322 // Wait for logical device to have the flows (or none
1323 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
1324 f, _ := nbi.ListLogicalDeviceFlows(getContext(), &voltha.ID{Id: ld.Id})
1325 return f != nil && len(f.Items) == expectedNumFlows
1326 }
1327 // No timeout implies a success
1328 err := waitUntilLogicalDeviceReadiness(oltDeviceID, nb.maxTimeout, nbi, vlFunction)
1329 assert.Nil(t, err)
1330}
1331
1332func (nb *NBTest) sendTrapFlows(t *testing.T, nbi voltha.VolthaServiceClient, logicalDeviceID string, ports []*voltha.LogicalPort, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
1333 // Send flows for the parent device
1334 var nniPorts []*voltha.LogicalPort
1335 var uniPorts []*voltha.LogicalPort
1336 for _, p := range ports {
1337 if p.RootPort {
1338 nniPorts = append(nniPorts, p)
1339 } else {
1340 uniPorts = append(uniPorts, p)
1341 }
1342 }
1343 assert.Equal(t, 1, len(nniPorts))
1344 //assert.Greater(t, len(uniPorts), 1 )
1345 nniPort := nniPorts[0].OfpPort.PortNo
1346 maxInt32 := uint64(0xFFFFFFFF)
1347 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1348 var fa *flows.FlowArgs
1349 fa = &flows.FlowArgs{
1350 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1351 MatchFields: []*ofp.OfpOxmOfbField{
1352 flows.InPort(nniPort),
1353 flows.EthType(35020),
1354 },
1355 Actions: []*ofp.OfpAction{
1356 flows.Output(controllerPortMask),
1357 },
1358 }
1359 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1360 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
1361 assert.Nil(t, err)
1362
1363 fa = &flows.FlowArgs{
1364 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1365 MatchFields: []*ofp.OfpOxmOfbField{
1366 flows.InPort(nniPort),
1367 flows.EthType(2048),
1368 flows.IpProto(17),
1369 flows.UdpSrc(67),
1370 flows.UdpDst(68),
1371 },
1372 Actions: []*ofp.OfpAction{
1373 flows.Output(controllerPortMask),
1374 },
1375 }
1376 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1377 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
1378 assert.Nil(t, err)
1379
1380 fa = &flows.FlowArgs{
1381 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1382 MatchFields: []*ofp.OfpOxmOfbField{
1383 flows.InPort(nniPort),
1384 flows.EthType(34525),
1385 flows.IpProto(17),
1386 flows.UdpSrc(546),
1387 flows.UdpDst(547),
1388 },
1389 Actions: []*ofp.OfpAction{
1390 flows.Output(controllerPortMask),
1391 },
1392 }
1393 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1394 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
1395 assert.Nil(t, err)
1396
1397 return len(nniPorts), len(uniPorts)
1398}
1399
1400func (nb *NBTest) sendEAPFlows(t *testing.T, nbi voltha.VolthaServiceClient, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
1401 maxInt32 := uint64(0xFFFFFFFF)
1402 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1403 fa := &flows.FlowArgs{
1404 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},
1405 MatchFields: []*ofp.OfpOxmOfbField{
1406 flows.InPort(port.PortNo),
1407 flows.EthType(34958),
1408 flows.VlanVid(8187),
1409 },
1410 Actions: []*ofp.OfpAction{
1411 flows.Output(controllerPortMask),
1412 },
1413 }
1414 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1415 maxTries := 3
1416 var err error
1417 for {
1418 if _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP); err == nil {
1419 if maxTries < 3 {
1420 t.Log("Re-sending EAPOL flow succeeded for port:", port)
1421 }
1422 break
1423 }
1424 t.Log("Sending EAPOL flows fail:", err)
1425 time.Sleep(50 * time.Millisecond)
1426 maxTries--
1427 if maxTries == 0 {
1428 break
1429 }
1430 }
1431 assert.Nil(t, err)
1432}
1433
1434func (nb *NBTest) receiveChangeEvents(ctx context.Context, nbi voltha.VolthaServiceClient, ch chan *ofp.ChangeEvent) {
1435 opt := grpc.EmptyCallOption{}
1436 streamCtx, streamDone := context.WithCancel(log.WithSpanFromContext(context.Background(), ctx))
1437 defer streamDone()
1438 stream, err := nbi.ReceiveChangeEvents(streamCtx, &empty.Empty{}, opt)
1439 if err != nil {
1440 logger.Errorw(ctx, "cannot-establish-receive-change-events", log.Fields{"error": err})
1441 return
1442 }
1443
1444 for {
1445 ce, err := stream.Recv()
1446 if err == nil {
1447 ch <- ce
1448 continue
1449 }
1450 if err == io.EOF || strings.Contains(err.Error(), "Unavailable") {
1451 logger.Debug(context.Background(), "receive-events-stream-closing")
1452 } else {
1453 logger.Errorw(ctx, "error-receiving-change-event", log.Fields{"error": err})
1454 }
1455 return
1456 }
1457}
1458
1459func (nb *NBTest) getOLTAdapterInstance(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string) (*cm.OLTAdapter, error) {
1460 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
1461 assert.Nil(t, err)
1462 nb.oltAdaptersLock.RLock()
1463 defer nb.oltAdaptersLock.RUnlock()
1464 for _, d := range devices.Items {
1465 if d.Id == oltDeviceID {
1466 for _, oltAdapters := range nb.oltAdapters {
1467 for _, oAdapter := range oltAdapters {
1468 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1469 return oAdapter, nil
1470 }
1471 }
1472 }
1473 }
1474 }
1475 return nil, fmt.Errorf("no-adapter-for-%s", oltDeviceID)
1476}
1477
1478func (nb *NBTest) getAdapterInstancesWithDeviceIds(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceID string) (*cm.OLTAdapter, map[string]*cm.ONUAdapter, []string, error) {
1479 var oltAdapter *cm.OLTAdapter
1480 onuAdapters := make(map[string]*cm.ONUAdapter)
1481 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
1482 onuDeviceIDs := make([]string, 0)
1483 assert.Nil(t, err)
1484 oltAdapterFound := false
1485 nb.oltAdaptersLock.RLock()
1486 defer nb.oltAdaptersLock.RUnlock()
1487 nb.onuAdaptersLock.RLock()
1488 defer nb.onuAdaptersLock.RUnlock()
1489 for _, d := range devices.Items {
1490 if !oltAdapterFound && d.Id == oltDeviceID {
1491 for _, oltAdapters := range nb.oltAdapters {
1492 for _, oAdapter := range oltAdapters {
1493 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1494 oltAdapter = oAdapter
1495 oltAdapterFound = true
1496 }
1497 }
1498 }
1499 }
1500 // We can have multiple ONU adapters managing the ONU devices off an OLT
1501 if !d.Root && d.ParentId == oltDeviceID {
1502 onuDeviceIDs = append(onuDeviceIDs, d.Id)
1503 for _, adapters := range nb.onuAdapters {
1504 for _, oAdapter := range adapters {
1505 if oAdapter.Adapter.GetEndPoint() == d.AdapterEndpoint {
1506 onuAdapters[d.AdapterEndpoint] = oAdapter
1507 }
1508 }
1509 }
1510 }
1511 }
1512 if len(onuAdapters) > 0 && oltAdapter != nil && len(onuDeviceIDs) > 0 {
1513 return oltAdapter, onuAdapters, onuDeviceIDs, nil
1514 }
1515 return nil, nil, nil, fmt.Errorf("no-adapter-for-%s", oltDeviceID)
1516}
1517
1518func (nb *NBTest) monitorLogicalDevices(
1519 ctx context.Context,
1520 t *testing.T,
1521 nbi voltha.VolthaServiceClient,
1522 numNNIPorts int,
1523 numUNIPorts int,
1524 wg *sync.WaitGroup,
1525 flowAddFail bool,
1526 flowDeleteFail bool,
1527 oltID string,
1528 eventCh chan *ofp.ChangeEvent) {
1529
1530 defer wg.Done()
1531
1532 // Wait until a logical device is ready
1533 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
1534 if lds == nil || len(lds.Items) == 0 {
1535 return false
1536 }
1537 // Ensure there are both NNI ports and at least one UNI port on the logical devices discovered
1538 for _, ld := range lds.Items {
1539 if ld.RootDeviceId != oltID {
1540 continue
1541 }
1542 ports, err := nbi.ListLogicalDevicePorts(getContext(), &voltha.ID{Id: ld.Id})
1543 if err != nil {
1544 return false
1545 }
1546 return len(ports.Items) == numNNIPorts+numUNIPorts // wait until all logical ports are created
1547 }
1548 return false
1549 }
1550 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
1551 assert.Nil(t, err)
1552
1553 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
1554 assert.Nil(t, err)
1555 assert.NotNil(t, logicalDevices)
1556 var logicalDevice *voltha.LogicalDevice
1557 for _, ld := range logicalDevices.Items {
1558 if ld.RootDeviceId == oltID {
1559 logicalDevice = ld
1560 break
1561 }
1562 }
1563 assert.NotNil(t, logicalDevice)
1564 logicalDeviceID := logicalDevice.Id
1565
1566 // Figure out the olt and onuAdapter being used by that logicalDeviceld\DeviceId
1567 // Clear any existing flows on these adapters
1568 oltAdapter, onuAdapters, onuDeviceIDs, err := nb.getAdapterInstancesWithDeviceIds(t, nbi, oltID)
1569 assert.Nil(t, err)
1570 assert.NotNil(t, oltAdapter)
1571 assert.Greater(t, len(onuAdapters), 0)
1572
1573 // Clear flows for that olt device and set the flow action
1574 oltAdapter.RemoveDevice(oltID)
1575 oltAdapter.SetFlowAction(oltID, flowAddFail, flowDeleteFail)
1576
1577 // Clear flows for the onu devices and set the flow action
1578 for _, a := range onuAdapters {
1579 for _, id := range onuDeviceIDs {
1580 a.RemoveDevice(id)
1581 a.SetFlowAction(id, flowAddFail, flowDeleteFail)
1582 }
1583 }
1584
1585 meterID := rand.Uint32()
1586
1587 // Add a meter to the logical device
1588 meterMod := &ofp.OfpMeterMod{
1589 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1590 Flags: rand.Uint32(),
1591 MeterId: meterID,
1592 Bands: []*ofp.OfpMeterBandHeader{
1593 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1594 Rate: rand.Uint32(),
1595 BurstSize: rand.Uint32(),
1596 Data: nil,
1597 },
1598 },
1599 }
1600 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{Id: logicalDeviceID, MeterMod: meterMod})
1601 assert.Nil(t, err)
1602
1603 ports, err := nbi.ListLogicalDevicePorts(getContext(), &voltha.ID{Id: logicalDeviceID})
1604 assert.Nil(t, err)
1605
1606 // Send initial set of Trap flows
1607 startingVlan := 4091
1608 nb.sendTrapFlows(t, nbi, logicalDeviceID, ports.Items, uint64(meterID), startingVlan)
1609
1610 //Listen for port events
1611 processedNniLogicalPorts := 0
1612 processedUniLogicalPorts := 0
1613
1614 for event := range eventCh {
1615 if event.Id != logicalDeviceID {
1616 continue
1617 }
1618 startingVlan++
1619 if portStatus, ok := (event.Event).(*ofp.ChangeEvent_PortStatus); ok {
1620 ps := portStatus.PortStatus
1621 if ps.Reason == ofp.OfpPortReason_OFPPR_ADD {
1622 if ps.Desc.PortNo >= uint32(nb.startingUNIPortNo) {
1623 processedUniLogicalPorts++
1624 nb.sendEAPFlows(t, nbi, logicalDeviceID, ps.Desc, startingVlan, uint64(meterID))
1625 } else {
1626 processedNniLogicalPorts++
1627 }
1628 }
1629 }
1630
1631 if processedNniLogicalPorts >= numNNIPorts && processedUniLogicalPorts >= numUNIPorts {
1632 break
1633 }
1634 }
1635
1636 //Verify the flow count on the logical device
1637 nb.verifyLogicalDeviceFlowCount(t, nbi, oltID, numNNIPorts, numUNIPorts, flowAddFail)
1638
1639 // Wait until all flows have been sent to the OLT adapters (or all failed)
1640 expectedFlowCount := (numNNIPorts * 3) + numNNIPorts*numUNIPorts
1641 if flowAddFail {
1642 expectedFlowCount = 0
1643 }
1644 var oltVFunc isConditionSatisfied = func() bool {
1645 return oltAdapter.GetFlowCount(oltID) >= expectedFlowCount
1646 }
1647 err = waitUntilCondition(nb.maxTimeout, oltVFunc)
1648 assert.Nil(t, err)
1649
1650 // Wait until all flows have been sent to the ONU adapters (or all failed)
1651 expectedFlowCount = numUNIPorts
1652 if flowAddFail {
1653 expectedFlowCount = 0
1654 }
1655 var onuVFunc isConditionSatisfied = func() bool {
1656 count := 0
1657 for _, a := range onuAdapters {
1658 for _, id := range onuDeviceIDs {
1659 count = count + a.GetFlowCount(id)
1660 }
1661 }
1662 return count == expectedFlowCount
1663 }
1664 err = waitUntilCondition(nb.maxTimeout, onuVFunc)
1665 assert.Nil(t, err)
1666}
1667
1668func (nb *NBTest) testFlowAddFailure(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
1669 // Subscribe to the event listener
1670 eventCh := nb.changeEventLister.Subscribe((nb.numONUPerOLT + 1) * nb.getNumAdapters())
1671
1672 defer nb.changeEventLister.Unsubscribe(eventCh)
1673
1674 // Create and enable device with valid data
1675 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1676 assert.Nil(t, err)
1677 assert.NotNil(t, oltDevice)
1678
1679 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
1680 var wg sync.WaitGroup
1681 wg.Add(1)
1682 subCtx, cancel := context.WithCancel(context.Background())
1683 defer cancel()
1684 go nb.monitorLogicalDevices(subCtx, t, nbi, 1, nb.numONUPerOLT, &wg, true, false, oltDevice.Id, eventCh)
1685
1686 // Wait for the logical device to be in the ready state
1687 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1688 return len(ports) == nb.numONUPerOLT+1
1689 }
1690 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1691 assert.Nil(t, err)
1692
1693 // Verify that the devices have been setup correctly
1694 nb.verifyDevices(t, nbi, oltDevice.Id)
1695
1696 // Get latest oltDevice data
1697 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1698 assert.Nil(t, err)
1699
1700 // Verify that the logical device has been setup correctly
1701 nb.verifyLogicalDevices(t, oltDevice, nbi)
1702
1703 // Wait until all flows has been sent to the devices successfully
1704 wg.Wait()
1705
1706 //Remove the device
1707 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1708 assert.Nil(t, err)
1709}
1710
1711func (nb *NBTest) testMPLSFlowsAddition(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string) {
khenaidood948f772021-08-11 17:49:24 -04001712 // Create and enable device with valid data
1713 oltDevice, err := nb.createAndEnableOLTDevice(t, nbi, oltDeviceType)
1714 assert.Nil(t, err)
1715 assert.NotNil(t, oltDevice)
1716
1717 // Wait for the logical device to be in the ready state
1718 var vldFunction = func(ports []*voltha.LogicalPort) bool {
1719 return len(ports) == nb.numONUPerOLT+1
1720 }
1721 err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
1722 assert.Nil(t, err)
1723
1724 // Get latest oltDevice data
1725 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
1726 assert.Nil(t, err)
1727 assert.NotNil(t, oltDevice)
1728 testLogger.Infow(getContext(), "olt-device-created-and-verified", log.Fields{"device-id": oltDevice.GetId()})
1729
1730 // Verify that the logical device has been setup correctly
1731 nb.verifyLogicalDevices(t, oltDevice, nbi)
1732
1733 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
khenaidoo5d126902021-10-07 10:04:43 -04001734 assert.Nil(t, err)
1735 assert.NotNil(t, logicalDevices)
1736 var logicalDevice *voltha.LogicalDevice
1737 for _, ld := range logicalDevices.Items {
1738 if ld.RootDeviceId == oltDevice.Id {
1739 logicalDevice = ld
1740 break
1741 }
1742 }
1743 assert.NotNil(t, logicalDevice)
khenaidood948f772021-08-11 17:49:24 -04001744
khenaidoo5d126902021-10-07 10:04:43 -04001745 testLogger.Infow(getContext(), "list-logical-devices", log.Fields{"logical-device": logicalDevice})
khenaidood948f772021-08-11 17:49:24 -04001746 // Add a meter to the logical device, which the flow can refer to
1747 meterMod := &ofp.OfpMeterMod{
1748 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1749 Flags: rand.Uint32(),
1750 MeterId: 1,
1751 Bands: []*ofp.OfpMeterBandHeader{
1752 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1753 Rate: rand.Uint32(),
1754 BurstSize: rand.Uint32(),
1755 Data: nil,
1756 },
1757 },
1758 }
1759 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{
1760 Id: logicalDevices.GetItems()[0].GetId(),
1761 MeterMod: meterMod,
1762 })
1763 assert.NoError(t, err)
1764
khenaidoo5d126902021-10-07 10:04:43 -04001765 meters, err := nbi.ListLogicalDeviceMeters(getContext(), &voltha.ID{Id: logicalDevice.Id})
khenaidood948f772021-08-11 17:49:24 -04001766 assert.NoError(t, err)
1767
1768 for _, item := range meters.GetItems() {
1769 testLogger.Infow(getContext(), "list-logical-device-meters", log.Fields{"meter-config": item.GetConfig()})
1770 }
1771
khenaidoo5d126902021-10-07 10:04:43 -04001772 logicalPorts, err := nbi.ListLogicalDevicePorts(context.Background(), &voltha.ID{Id: logicalDevice.Id})
khenaidood948f772021-08-11 17:49:24 -04001773 assert.NoError(t, err)
1774 m := jsonpb.Marshaler{}
1775 logicalPortsJson, err := m.MarshalToString(logicalPorts)
1776 assert.NoError(t, err)
1777
1778 testLogger.Infow(getContext(), "list-logical-ports", log.Fields{"ports": logicalPortsJson})
1779
1780 callables := []func() *ofp.OfpFlowMod{getOnuUpstreamRules, getOltUpstreamRules, getOLTDownstreamMplsSingleTagRules,
1781 getOLTDownstreamMplsDoubleTagRules, getOLTDownstreamRules, getOnuDownstreamRules}
1782
1783 for _, callable := range callables {
khenaidoo5d126902021-10-07 10:04:43 -04001784 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &ofp.FlowTableUpdate{Id: logicalDevice.Id, FlowMod: callable()})
khenaidood948f772021-08-11 17:49:24 -04001785 assert.NoError(t, err)
1786 }
1787
1788 //Remove the device
1789 err = cleanUpDevices(nb.maxTimeout, nbi, oltDevice.Id, true)
1790 assert.Nil(t, err)
1791}
1792
1793func getOnuUpstreamRules() (flowMod *ofp.OfpFlowMod) {
1794 fa := &flows.FlowArgs{
1795 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1, "meter_id": 1, "write_metadata": 4100100000},
1796 MatchFields: []*ofp.OfpOxmOfbField{
1797 flows.InPort(103),
1798 flows.VlanVid(4096),
1799 },
1800 Actions: []*ofp.OfpAction{},
1801 }
1802
1803 flowMod = makeSimpleFlowMod(fa)
1804 flowMod.TableId = 0
1805 m := jsonpb.Marshaler{}
1806 flowModJson, _ := m.MarshalToString(flowMod)
1807 testLogger.Infow(getContext(), "onu-upstream-flow", log.Fields{"flow-mod": flowModJson})
1808 return
1809}
1810
1811func getOltUpstreamRules() (flowMod *ofp.OfpFlowMod) {
1812 fa := &flows.FlowArgs{
1813 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1, "meter_id": 1, "write_metadata": 4100000000},
1814 MatchFields: []*ofp.OfpOxmOfbField{
1815 flows.InPort(103),
1816 flows.VlanVid(4096),
1817 },
1818 Actions: []*ofp.OfpAction{
1819 flows.PushVlan(0x8100),
1820 flows.SetField(flows.VlanVid(2)),
1821 flows.SetField(flows.EthSrc(1111)),
1822 flows.SetField(flows.EthDst(2222)),
1823 flows.PushVlan(0x8847),
1824 flows.SetField(flows.MplsLabel(100)),
1825 flows.SetField(flows.MplsBos(1)),
1826 flows.PushVlan(0x8847),
1827 flows.SetField(flows.MplsLabel(200)),
1828 flows.MplsTtl(64),
1829 flows.Output(2),
1830 },
1831 }
1832 flowMod = makeSimpleFlowMod(fa)
1833 flowMod.TableId = 1
1834 m := jsonpb.Marshaler{}
1835 flowModJson, _ := m.MarshalToString(flowMod)
1836 testLogger.Infow(getContext(), "olt-upstream-flow", log.Fields{"flow-mod": flowModJson})
1837 return
1838}
1839
1840func getOLTDownstreamMplsSingleTagRules() (flowMod *ofp.OfpFlowMod) {
1841 fa := &flows.FlowArgs{
1842 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1843 MatchFields: []*ofp.OfpOxmOfbField{
1844 flows.InPort(2),
1845 flows.Metadata_ofp((1000 << 32) | 1),
1846 flows.EthType(0x8847),
1847 flows.MplsBos(1),
1848 flows.EthSrc(2222),
1849 },
1850 Actions: []*ofp.OfpAction{
1851 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1852 flows.PopMpls(0x8847),
1853 },
1854 }
1855 flowMod = makeSimpleFlowMod(fa)
1856 flowMod.TableId = 0
1857 m := jsonpb.Marshaler{}
1858 flowModJson, _ := m.MarshalToString(flowMod)
1859 testLogger.Infow(getContext(), "olt-mpls-downstream-single-tag-flow", log.Fields{"flow-mod": flowModJson})
1860 return
1861}
1862
1863func getOLTDownstreamMplsDoubleTagRules() (flowMod *ofp.OfpFlowMod) {
1864 fa := &flows.FlowArgs{
1865 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1866 MatchFields: []*ofp.OfpOxmOfbField{
1867 flows.InPort(2),
1868 flows.EthType(0x8847),
1869 flows.EthSrc(2222),
1870 },
1871 Actions: []*ofp.OfpAction{
1872 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1873 flows.PopMpls(0x8847),
1874 flows.PopMpls(0x8847),
1875 },
1876 }
1877 flowMod = makeSimpleFlowMod(fa)
1878 flowMod.TableId = 0
1879 m := jsonpb.Marshaler{}
1880 flowModJson, _ := m.MarshalToString(flowMod)
1881 testLogger.Infow(getContext(), "olt-mpls-downstream-double-tagged-flow", log.Fields{"flow-mod": flowModJson})
1882 return
1883}
1884
1885func getOLTDownstreamRules() (flowMod *ofp.OfpFlowMod) {
1886 fa := &flows.FlowArgs{
1887 KV: flows.OfpFlowModArgs{"priority": 1000, "table_id": 2, "meter_id": 1},
1888 MatchFields: []*ofp.OfpOxmOfbField{
1889 flows.InPort(2),
1890 flows.VlanVid(2),
1891 },
1892 Actions: []*ofp.OfpAction{
1893 flows.PopVlan(),
1894 },
1895 }
1896 flowMod = makeSimpleFlowMod(fa)
1897 flowMod.TableId = 1
1898 m := jsonpb.Marshaler{}
1899 flowModJson, _ := m.MarshalToString(flowMod)
1900 testLogger.Infow(getContext(), "olt-downstream-flow", log.Fields{"flow-mod": flowModJson})
1901 return
1902}
1903
1904func getOnuDownstreamRules() (flowMod *ofp.OfpFlowMod) {
1905 fa := &flows.FlowArgs{
1906 KV: flows.OfpFlowModArgs{"priority": 1000, "meter_id": 1},
1907 MatchFields: []*ofp.OfpOxmOfbField{
1908 flows.InPort(2),
1909 flows.Metadata_ofp((1000 << 32) | 1),
1910 flows.VlanVid(4096),
1911 },
1912 Actions: []*ofp.OfpAction{
1913 flows.Output(103),
1914 },
1915 }
1916 flowMod = makeSimpleFlowMod(fa)
1917 flowMod.TableId = 2
1918 m := jsonpb.Marshaler{}
1919 flowModJson, _ := m.MarshalToString(flowMod)
1920 testLogger.Infow(getContext(), "onu-downstream-flow", log.Fields{"flow-mod": flowModJson})
1921 return
1922}
1923
1924func (nb *NBTest) runTestSuite(t *testing.T, nbi voltha.VolthaServiceClient, oltDeviceType string, testWg *sync.WaitGroup) {
1925 defer testWg.Done()
1926
1927 // Test create device
1928 nb.testCreateDevice(t, nbi, oltDeviceType)
1929
1930 //Test Delete Device Scenarios
1931 nb.testForceDeletePreProvDevice(t, nbi, oltDeviceType)
1932 nb.testDeletePreProvDevice(t, nbi, oltDeviceType)
1933 nb.testForceDeleteEnabledDevice(t, nbi, oltDeviceType)
1934 nb.testDeleteEnabledDevice(t, nbi, oltDeviceType)
1935 nb.testForceDeleteDeviceFailure(t, nbi, oltDeviceType)
1936 nb.testDeleteDeviceFailure(t, nbi, oltDeviceType)
1937
1938 ////Test failed enable device
1939 nb.testEnableDeviceFailed(t, nbi, oltDeviceType)
1940
1941 //Test Enable a device
1942 nb.testEnableDevice(t, nbi, oltDeviceType)
1943
1944 //Test disable and ReEnable a root device
1945 nb.testDisableAndReEnableRootDevice(t, nbi, oltDeviceType)
1946
1947 // Test disable and Enable pon port of OLT device
1948 nb.testDisableAndEnablePort(t, nbi, oltDeviceType)
1949
1950 // Test Device unreachable when OLT is enabled
1951 nb.testDeviceRebootWhenOltIsEnabled(t, nbi, oltDeviceType)
1952
1953 // Test disable and delete all devices
1954 nb.testDisableAndDeleteAllDevice(t, nbi, oltDeviceType)
1955
1956 // Test enable and delete all devices
1957 nb.testEnableAndDeleteAllDevice(t, nbi, oltDeviceType)
1958
1959 // Test omci test
1960 nb.testStartOmciTestAction(t, nbi, oltDeviceType)
1961
1962 // Test flow add failure
1963 nb.testFlowAddFailure(t, nbi, oltDeviceType)
1964
1965 // Test MPLS flows addition where:
1966 /*
1967 Upstream
1968 ONU
1969 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:32, VLAN_VID:ANY], treatment=[immediate=[],
1970 transition=TABLE:1, meter=METER:1, metadata=METADATA:4100010000/0]
1971 OLT
1972 ADDED, bytes=0, packets=0, table=1, priority=1000, selector=[IN_PORT:32, VLAN_VID:ANY], treatment=[immediate=[VLAN_PUSH:vlan,
1973 VLAN_ID:2, MPLS_PUSH:mpls_unicast, MPLS_LABEL:YYY,MPLS_BOS:true, MPLS_PUSH:mpls_unicast ,MPLS_LABEL:XXX, MPLS_BOS:false,
1974 EXTENSION:of:0000000000000227/VolthaPushL2Header{​​​​​​​}​​​​​​​, ETH_SRC:OLT_MAC, ETH_DST:LEAF_MAC, TTL:64, OUTPUT:65536],
1975 meter=METER:1, metadata=METADATA:4100000000/0]
1976
1977 Downstream
1978 OLT
1979 //Below flow rule to pop L2 Ethernet headers from packets which have a single MPLS label
1980 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:65536, ETH_TYPE:mpls_unicast, MPLS_BOS:true, ETH_SRC:LEAF_MAC],
1981 treatment=[DefaultTrafficTreatment{immediate=[DEC_MPLS_TTL, TTL_IN, MPLS_POP:mpls_unicast, EXTENSION:of:0000000000000227/VolthaPopL2Header{},
1982 transition=TABLE:1]
1983
1984 //Below flow rule to pop L2 Ethernet headers from packets which have two MPLS label
1985 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:65536, ETH_TYPE:mpls_unicast, MPLS_BOS:false, ETH_SRC:LEAF_MAC],
1986 treatment=[DefaultTrafficTreatment{immediate=[DEC_MPLS_TTL, TTL_IN, MPLS_POP:mpls_unicast, MPLS_POP:mpls_unicast ,
1987 EXTENSION:of:0000000000000227/VolthaPopL2Header{}, transition=TABLE:1]
1988
1989 //Below flow rules are unchanged from the current implementations except for the table numbers
1990 ADDED, bytes=0, packets=0, table=1, priority=1000, selector=[IN_PORT:65536, VLAN_VID:2], treatment=[immediate=[VLAN_POP], transition=TABLE:2,
1991 meter=METER:2, metadata=METADATA:1000004100000020/0]
1992 ONU
1993 ADDED, bytes=0, packets=0, table=2, priority=1000, selector=[IN_PORT:65536, METADATA:20 VLAN_VID:ANY], treatment=[immediate=[OUTPUT:32],
1994 meter=METER:2, metadata=METADATA:4100000000/0]
1995 */
1996 nb.testMPLSFlowsAddition(t, nbi, oltDeviceType)
1997}
1998
1999func setUpCore(ctx context.Context, t *testing.T, nb *NBTest) (voltha.VolthaServiceClient, string) {
2000 // Start the Core
2001 coreAPIEndpoint, nbiEndpoint := nb.startGRPCCore(ctx, t)
2002
2003 // Wait until the core is ready
2004 start := time.Now()
2005 logger.Infow(ctx, "waiting-for-core-to-be-ready", log.Fields{"start": start, "api-endpoint": coreAPIEndpoint})
2006
2007 var vFunction isConditionSatisfied = func() bool {
2008 return nb.probe.IsReady()
2009 }
2010 err := waitUntilCondition(nb.internalTimeout, vFunction)
2011 assert.Nil(t, err)
2012 logger.Infow(ctx, "core-is-ready", log.Fields{"time-taken": time.Since(start)})
2013
2014 // Create a grpc client to communicate with the Core
2015 conn, err := grpc.Dial(nbiEndpoint, grpc.WithInsecure())
2016 if err != nil {
2017 logger.Fatalw(ctx, "cannot connect to core", log.Fields{"error": err})
2018 }
2019 nbi := voltha.NewVolthaServiceClient(conn)
2020 if nbi == nil {
2021 logger.Fatalw(ctx, "cannot create a service to core", log.Fields{"error": err})
2022 }
2023
2024 // Basic test with no data in Core
2025 nb.testCoreWithoutData(t, nbi)
2026
2027 logger.Infow(ctx, "core-setup-complete", log.Fields{"time": time.Since(start), "api-endpoint": coreAPIEndpoint})
2028
2029 return nbi, coreAPIEndpoint
2030}
2031
2032func setupAdapters(ctx context.Context, t *testing.T, nb *NBTest, coreAPIEndpoint string, nbi voltha.VolthaServiceClient) {
2033 // Create/register the adapters
2034 start := time.Now()
2035 nb.oltAdaptersLock.Lock()
2036 nb.onuAdaptersLock.Lock()
2037 nb.oltAdapters, nb.onuAdapters = CreateAndRegisterAdapters(ctx, t, oltAdapters, onuAdapters, coreAPIEndpoint)
2038 nb.oltAdaptersLock.Unlock()
2039 nb.onuAdaptersLock.Unlock()
2040
2041 nb.numONUPerOLT = cm.GetNumONUPerOLT()
2042 nb.startingUNIPortNo = cm.GetStartingUNIPortNo()
2043
2044 // Wait for adapters to be fully running
2045 var areAdaptersRunning isConditionSatisfied = func() bool {
2046 ready := true
khenaidoo5d126902021-10-07 10:04:43 -04002047 nb.onuAdaptersLock.RLock()
2048 defer nb.onuAdaptersLock.RUnlock()
khenaidood948f772021-08-11 17:49:24 -04002049 for _, adapters := range nb.onuAdapters {
2050 for _, a := range adapters {
2051 ready = ready && a.IsReady()
2052 if !ready {
2053 return false
2054 }
2055 }
2056 }
khenaidoo5d126902021-10-07 10:04:43 -04002057 nb.oltAdaptersLock.RLock()
2058 defer nb.oltAdaptersLock.RUnlock()
khenaidood948f772021-08-11 17:49:24 -04002059 for _, adapters := range nb.oltAdapters {
2060 for _, a := range adapters {
2061 ready = ready && a.IsReady()
2062 if !ready {
2063 return false
2064 }
2065 }
2066 }
2067 return true
2068 }
2069 err := waitUntilCondition(nb.internalTimeout, areAdaptersRunning)
2070 assert.Nil(t, err)
2071 logger.Infow(ctx, "adapters-are-ready", log.Fields{"time-taken": time.Since(start)})
2072
2073 // Test adapter registration
2074 nb.testAdapterRegistration(t, nbi)
2075}
2076
khenaidoo5d126902021-10-07 10:04:43 -04002077func WaitForCoreConnectionToAdapters(ctx context.Context, t *testing.T, nb *NBTest, nbi voltha.VolthaServiceClient) {
2078 // Create/register the adapters
2079 start := time.Now()
2080 numAdapters := 0
2081 nb.oltAdaptersLock.RLock()
2082 numAdapters += len(nb.onuAdapters)
2083 nb.oltAdaptersLock.RUnlock()
2084 nb.onuAdaptersLock.RLock()
2085 numAdapters += len(nb.oltAdapters)
2086 nb.onuAdaptersLock.RUnlock()
2087
2088 // Wait for adapters to be fully running
2089 var isCoreConnectedToAdapters isConditionSatisfied = func() bool {
2090 adpts, err := nbi.ListAdapters(getContext(), &empty.Empty{})
2091 if err != nil || len(adpts.Items) < numAdapters {
2092 return false
2093 }
2094 // Now check the last communication time
2095 for _, adpt := range adpts.Items {
2096 if time.Since(time.Unix(adpt.LastCommunication, 0)) > 5*time.Second {
2097 return false
2098 }
2099 }
2100 return true
2101 }
2102 err := waitUntilCondition(nb.internalTimeout, isCoreConnectedToAdapters)
2103 assert.Nil(t, err)
2104 logger.Infow(ctx, "core-connection-to-adapters-is-ready", log.Fields{"time-taken": time.Since(start)})
2105
2106 // Test adapter registration
2107 nb.testAdapterRegistration(t, nbi)
2108}
2109
khenaidood948f772021-08-11 17:49:24 -04002110//TestLogDeviceUpdate is used to extract and format device updates. Not to be run on jenkins.
2111func TestLogDeviceUpdate(t *testing.T) {
2112 t.Skip()
2113 var inputFile = os.Getenv("LGF")
2114 var deviceID = os.Getenv("DID")
2115
2116 prettyPrintDeviceUpdateLog(inputFile, deviceID)
2117}
2118
2119func TestOMCIData(t *testing.T) {
2120 t.Skip()
2121 var inputFile = os.Getenv("LGF")
2122 var deviceID = os.Getenv("DID")
2123 omciLog(inputFile, deviceID)
2124}
2125
2126func TestRandomMacGenerator(t *testing.T) {
2127 t.Skip()
2128 var wg sync.WaitGroup
2129 myMap := make(map[string]int)
2130 var myMapLock sync.Mutex
2131 max := 1000000
2132 for i := 0; i < max; i++ {
2133 wg.Add(1)
2134 go func() {
2135 str := getRandomMacAddress()
2136 myMapLock.Lock()
2137 myMap[str]++
2138 myMapLock.Unlock()
2139 wg.Done()
2140 }()
2141 }
2142 wg.Wait()
2143 // Look for duplicates
2144 for str, val := range myMap {
2145 if val != 1 {
2146 fmt.Println("duplicate", str)
2147 }
2148 }
2149}
2150
2151func TestSuite(t *testing.T) {
2152 log.SetAllLogLevel(log.FatalLevel)
2153
2154 // Create a context to be cancelled at the end of all tests. This will trigger closing of any ressources used.
2155 ctx, cancel := context.WithCancel(context.Background())
2156
2157 // Setup CPU profiling
2158 f, err := os.Create("grpc_profile.cpu")
2159 // f, err := os.Create("../../../tests/results/grpc_profile.cpu")
2160 if err != nil {
2161 logger.Fatalf(ctx, "could not create CPU profile: %v\n ", err)
2162 }
2163 defer f.Close()
2164 runtime.SetBlockProfileRate(1)
2165 runtime.SetMutexProfileFraction(-1)
2166 runtime.SetCPUProfileRate(200)
2167 if err := pprof.StartCPUProfile(f); err != nil {
2168 logger.Fatalf(ctx, "could not start CPU profile: %v\n", err)
2169 }
2170 defer pprof.StopCPUProfile()
2171
2172 // Create test object
2173 nb := newNBTest(ctx, false)
2174 assert.NotNil(t, nb)
2175 defer nb.stopAll(ctx)
2176
2177 // Setup the Core
2178 nbi, coreAPIEndpoint := setUpCore(ctx, t, nb)
2179
2180 // Setup the adapters
2181 setupAdapters(ctx, t, nb, coreAPIEndpoint, nbi)
2182
khenaidoo5d126902021-10-07 10:04:43 -04002183 // Wait until the Core can connect to the adapters
2184 WaitForCoreConnectionToAdapters(ctx, t, nb, nbi)
2185
khenaidood948f772021-08-11 17:49:24 -04002186 // Start the change events listener and dispatcher to receive all change events from the Core
2187 nb.changeEventLister = NewChangedEventListener(len(nb.oltAdapters))
2188 ch := make(chan *ofp.ChangeEvent, (nb.numONUPerOLT+1)*len(nb.oltAdapters))
2189 go nb.changeEventLister.Start(ctx, ch)
2190 go nb.receiveChangeEvents(ctx, nbi, ch)
2191
2192 // Run the full set of tests in parallel for each olt device type
2193 start := time.Now()
2194 fmt.Println("starting test at:", start)
2195 var wg sync.WaitGroup
2196 nb.oltAdaptersLock.RLock()
2197 numTestCycles := 1
2198 for i := 1; i <= numTestCycles; i++ {
2199 for oltAdapterType, oltAdapters := range nb.oltAdapters {
2200 for _, a := range oltAdapters {
2201 wg.Add(1)
2202 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)
2203 go nb.runTestSuite(t, nbi, a.DeviceType, &wg)
2204 }
2205 }
2206 }
2207 nb.oltAdaptersLock.RUnlock()
2208
2209 // Wait for all tests to complete
2210 wg.Wait()
2211 fmt.Println("Execution time:", time.Since(start))
2212
2213 // Cleanup before leaving
2214 fmt.Println("Cleaning up ... grpc warnings can be safely ignored")
2215 cancel()
2216}