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