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