blob: 0490c5ffa5e5504b9d33cf718f179c96b9b4d8f7 [file] [log] [blame]
khenaidoob64fc8a2019-11-27 15:08:19 -05001/*
2* Copyright 2019-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 */
16package core
17
18import (
19 "context"
20 "errors"
21 "fmt"
khenaidoo67b22152020-03-02 16:01:25 -050022 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
23 "math/rand"
24 "os"
25 "runtime"
26 "runtime/pprof"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080027 "strings"
khenaidoo67b22152020-03-02 16:01:25 -050028 "sync"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080029 "testing"
30 "time"
31
khenaidoob64fc8a2019-11-27 15:08:19 -050032 "github.com/golang/protobuf/ptypes/empty"
33 "github.com/opencord/voltha-go/rw_core/config"
34 cm "github.com/opencord/voltha-go/rw_core/mocks"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080035 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
36 "github.com/opencord/voltha-lib-go/v3/pkg/log"
37 lm "github.com/opencord/voltha-lib-go/v3/pkg/mocks"
38 "github.com/opencord/voltha-lib-go/v3/pkg/version"
39 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
40 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob64fc8a2019-11-27 15:08:19 -050041 "github.com/phayes/freeport"
42 "github.com/stretchr/testify/assert"
43 "google.golang.org/grpc/codes"
44 "google.golang.org/grpc/status"
khenaidoob64fc8a2019-11-27 15:08:19 -050045)
46
47type NBTest struct {
khenaidoo67b22152020-03-02 16:01:25 -050048 etcdServer *lm.EtcdServer
49 core *Core
50 kClient kafka.Client
51 kvClientPort int
52 numONUPerOLT int
53 startingUNIPortNo int
54 oltAdapter *cm.OLTAdapter
55 onuAdapter *cm.ONUAdapter
56 oltAdapterName string
57 onuAdapterName string
58 coreInstanceID string
59 defaultTimeout time.Duration
60 maxTimeout time.Duration
khenaidoob64fc8a2019-11-27 15:08:19 -050061}
62
63func newNBTest() *NBTest {
64 test := &NBTest{}
65 // Start the embedded etcd server
66 var err error
67 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.nb.test", "voltha.rwcore.nb.etcd", "error")
68 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000069 logger.Fatal(err)
khenaidoob64fc8a2019-11-27 15:08:19 -050070 }
71 // Create the kafka client
72 test.kClient = lm.NewKafkaClient()
73 test.oltAdapterName = "olt_adapter_mock"
74 test.onuAdapterName = "onu_adapter_mock"
75 test.coreInstanceID = "rw-nbi-test"
khenaidoo32836732020-03-05 16:10:44 -050076 test.defaultTimeout = 10 * time.Second
77 test.maxTimeout = 20 * time.Second
khenaidoob64fc8a2019-11-27 15:08:19 -050078 return test
79}
80
81func (nb *NBTest) startCore(inCompeteMode bool) {
Thomas Lee Se5a44012019-11-07 20:32:24 +053082 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
83 defer cancel()
khenaidoob64fc8a2019-11-27 15:08:19 -050084 cfg := config.NewRWCoreFlags()
85 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -040086 cfg.DefaultRequestTimeout = nb.defaultTimeout
87 cfg.DefaultCoreTimeout = nb.defaultTimeout
khenaidoob64fc8a2019-11-27 15:08:19 -050088 cfg.KVStorePort = nb.kvClientPort
89 cfg.InCompetingMode = inCompeteMode
90 grpcPort, err := freeport.GetFreePort()
91 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000092 logger.Fatal("Cannot get a freeport for grpc")
khenaidoob64fc8a2019-11-27 15:08:19 -050093 }
94 cfg.GrpcPort = grpcPort
95 cfg.GrpcHost = "127.0.0.1"
96 setCoreCompeteMode(inCompeteMode)
97 client := setupKVClient(cfg, nb.coreInstanceID)
Thomas Lee Se5a44012019-11-07 20:32:24 +053098 nb.core = NewCore(ctx, nb.coreInstanceID, cfg, client, nb.kClient)
99 err = nb.core.Start(context.Background())
100 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000101 logger.Fatal("Cannot start core")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530102 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500103}
104
Thomas Lee Se5a44012019-11-07 20:32:24 +0530105func (nb *NBTest) createAndregisterAdapters(t *testing.T) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500106 // Setup the mock OLT adapter
107 oltAdapter, err := createMockAdapter(OltAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.oltAdapterName)
108 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000109 logger.Fatalw("setting-mock-olt-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500110 }
khenaidoo67b22152020-03-02 16:01:25 -0500111 nb.oltAdapter = (oltAdapter).(*cm.OLTAdapter)
112 nb.numONUPerOLT = nb.oltAdapter.GetNumONUPerOLT()
113 nb.startingUNIPortNo = nb.oltAdapter.GetStartingUNIPortNo()
114
khenaidoob64fc8a2019-11-27 15:08:19 -0500115 // Register the adapter
116 registrationData := &voltha.Adapter{
117 Id: nb.oltAdapterName,
118 Vendor: "Voltha-olt",
119 Version: version.VersionInfo.Version,
120 }
121 types := []*voltha.DeviceType{{Id: nb.oltAdapterName, Adapter: nb.oltAdapterName, AcceptsAddRemoveFlowUpdates: true}}
122 deviceTypes := &voltha.DeviceTypes{Items: types}
Thomas Lee Se5a44012019-11-07 20:32:24 +0530123 if _, err := nb.core.adapterMgr.registerAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000124 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530125 assert.NotNil(t, err)
126 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500127
128 // Setup the mock ONU adapter
khenaidoo67b22152020-03-02 16:01:25 -0500129 onuAdapter, err := createMockAdapter(OnuAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.onuAdapterName)
130 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000131 logger.Fatalw("setting-mock-onu-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500132 }
khenaidoo67b22152020-03-02 16:01:25 -0500133 nb.onuAdapter = (onuAdapter).(*cm.ONUAdapter)
134
khenaidoob64fc8a2019-11-27 15:08:19 -0500135 // Register the adapter
136 registrationData = &voltha.Adapter{
137 Id: nb.onuAdapterName,
138 Vendor: "Voltha-onu",
139 Version: version.VersionInfo.Version,
140 }
141 types = []*voltha.DeviceType{{Id: nb.onuAdapterName, Adapter: nb.onuAdapterName, AcceptsAddRemoveFlowUpdates: true}}
142 deviceTypes = &voltha.DeviceTypes{Items: types}
Thomas Lee Se5a44012019-11-07 20:32:24 +0530143 if _, err := nb.core.adapterMgr.registerAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000144 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530145 assert.NotNil(t, err)
146 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500147}
148
149func (nb *NBTest) stopAll() {
150 if nb.kClient != nil {
151 nb.kClient.Stop()
152 }
153 if nb.core != nil {
154 nb.core.Stop(context.Background())
155 }
156 if nb.etcdServer != nil {
157 stopEmbeddedEtcdServer(nb.etcdServer)
158 }
159}
160
161func (nb *NBTest) verifyLogicalDevices(t *testing.T, oltDevice *voltha.Device, nbi *APIHandler) {
162 // Get the latest set of logical devices
163 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
164 assert.Nil(t, err)
165 assert.NotNil(t, logicalDevices)
166 assert.Equal(t, 1, len(logicalDevices.Items))
167
168 ld := logicalDevices.Items[0]
169 assert.NotEqual(t, "", ld.Id)
170 assert.NotEqual(t, uint64(0), ld.DatapathId)
171 assert.Equal(t, "olt_adapter_mock", ld.Desc.HwDesc)
172 assert.Equal(t, "olt_adapter_mock", ld.Desc.SwDesc)
173 assert.NotEqual(t, "", ld.RootDeviceId)
174 assert.NotEqual(t, "", ld.Desc.SerialNum)
175 assert.Equal(t, uint32(256), ld.SwitchFeatures.NBuffers)
176 assert.Equal(t, uint32(2), ld.SwitchFeatures.NTables)
177 assert.Equal(t, uint32(15), ld.SwitchFeatures.Capabilities)
178 assert.Equal(t, 1+nb.numONUPerOLT, len(ld.Ports))
179 assert.Equal(t, oltDevice.ParentId, ld.Id)
180 //Expected port no
181 expectedPortNo := make(map[uint32]bool)
182 expectedPortNo[uint32(2)] = false
183 for i := 0; i < nb.numONUPerOLT; i++ {
184 expectedPortNo[uint32(i+100)] = false
185 }
186 for _, p := range ld.Ports {
187 assert.Equal(t, p.OfpPort.PortNo, p.DevicePortNo)
188 assert.Equal(t, uint32(4), p.OfpPort.State)
189 expectedPortNo[p.OfpPort.PortNo] = true
190 if strings.HasPrefix(p.Id, "nni") {
191 assert.Equal(t, true, p.RootPort)
192 //assert.Equal(t, uint32(2), p.OfpPort.PortNo)
193 assert.Equal(t, p.Id, fmt.Sprintf("nni-%d", p.DevicePortNo))
194 } else {
195 assert.Equal(t, p.Id, fmt.Sprintf("uni-%d", p.DevicePortNo))
196 assert.Equal(t, false, p.RootPort)
197 }
198 }
199}
200
201func (nb *NBTest) verifyDevices(t *testing.T, nbi *APIHandler) {
202 // Get the latest set of devices
203 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
204 assert.Nil(t, err)
205 assert.NotNil(t, devices)
206
khenaidoo67b22152020-03-02 16:01:25 -0500207 // A device is ready to be examined when its ADMIN state is ENABLED and OPERATIONAL state is ACTIVE
khenaidoob64fc8a2019-11-27 15:08:19 -0500208 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
209 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
210 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500211
khenaidoo67b22152020-03-02 16:01:25 -0500212 var wg sync.WaitGroup
213 for _, device := range devices.Items {
214 wg.Add(1)
215 go func(wg *sync.WaitGroup, device *voltha.Device) {
216 // Wait until the device is in the right state
217 err := waitUntilDeviceReadiness(device.Id, nb.maxTimeout, vFunction, nbi)
218 assert.Nil(t, err)
219
220 // Now, verify the details of the device. First get the latest update
221 d, err := nbi.GetDevice(getContext(), &voltha.ID{Id: device.Id})
222 assert.Nil(t, err)
223 assert.Equal(t, voltha.AdminState_ENABLED, d.AdminState)
224 assert.Equal(t, voltha.ConnectStatus_REACHABLE, d.ConnectStatus)
225 assert.Equal(t, voltha.OperStatus_ACTIVE, d.OperStatus)
226 assert.Equal(t, d.Type, d.Adapter)
227 assert.NotEqual(t, "", d.MacAddress)
228 assert.NotEqual(t, "", d.SerialNumber)
229
230 if d.Type == "olt_adapter_mock" {
231 assert.Equal(t, true, d.Root)
232 assert.NotEqual(t, "", d.Id)
233 assert.NotEqual(t, "", d.ParentId)
234 assert.Nil(t, d.ProxyAddress)
235 } else if d.Type == "onu_adapter_mock" {
236 assert.Equal(t, false, d.Root)
237 assert.NotEqual(t, uint32(0), d.Vlan)
238 assert.NotEqual(t, "", d.Id)
239 assert.NotEqual(t, "", d.ParentId)
240 assert.NotEqual(t, "", d.ProxyAddress.DeviceId)
241 assert.Equal(t, "olt_adapter_mock", d.ProxyAddress.DeviceType)
khenaidoob64fc8a2019-11-27 15:08:19 -0500242 } else {
khenaidoo67b22152020-03-02 16:01:25 -0500243 assert.Error(t, errors.New("invalid-device-type"))
khenaidoob64fc8a2019-11-27 15:08:19 -0500244 }
khenaidoo67b22152020-03-02 16:01:25 -0500245 assert.Equal(t, 2, len(d.Ports))
246 for _, p := range d.Ports {
247 assert.Equal(t, voltha.AdminState_ENABLED, p.AdminState)
248 assert.Equal(t, voltha.OperStatus_ACTIVE, p.OperStatus)
249 if p.Type == voltha.Port_ETHERNET_NNI || p.Type == voltha.Port_ETHERNET_UNI {
250 assert.Equal(t, 0, len(p.Peers))
251 } else if p.Type == voltha.Port_PON_OLT {
252 assert.Equal(t, nb.numONUPerOLT, len(p.Peers))
253 assert.Equal(t, uint32(1), p.PortNo)
254 } else if p.Type == voltha.Port_PON_ONU {
255 assert.Equal(t, 1, len(p.Peers))
256 assert.Equal(t, uint32(1), p.PortNo)
257 } else {
258 assert.Error(t, errors.New("invalid-port"))
259 }
260 }
261 wg.Done()
262 }(&wg, device)
khenaidoob64fc8a2019-11-27 15:08:19 -0500263 }
khenaidoo67b22152020-03-02 16:01:25 -0500264 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500265}
266
267func (nb *NBTest) getADevice(rootDevice bool, nbi *APIHandler) (*voltha.Device, error) {
268 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
269 if err != nil {
270 return nil, err
271 }
272 for _, d := range devices.Items {
273 if d.Root == rootDevice {
274 return d, nil
275 }
276 }
277 return nil, status.Errorf(codes.NotFound, "%v device not found", rootDevice)
278}
279
280func (nb *NBTest) testCoreWithoutData(t *testing.T, nbi *APIHandler) {
281 lds, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
282 assert.Nil(t, err)
283 assert.NotNil(t, lds)
284 assert.Equal(t, 0, len(lds.Items))
285 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
286 assert.Nil(t, err)
287 assert.NotNil(t, devices)
288 assert.Equal(t, 0, len(devices.Items))
289 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
khenaidoo442e7c72020-03-10 16:13:48 -0400290 assert.Equal(t, 0, len(adapters.Items))
khenaidoob64fc8a2019-11-27 15:08:19 -0500291 assert.Nil(t, err)
292 assert.NotNil(t, adapters)
khenaidoob64fc8a2019-11-27 15:08:19 -0500293}
294
295func (nb *NBTest) testAdapterRegistration(t *testing.T, nbi *APIHandler) {
296 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
297 assert.Nil(t, err)
298 assert.NotNil(t, adapters)
299 assert.Equal(t, 2, len(adapters.Items))
300 for _, a := range adapters.Items {
301 switch a.Id {
302 case nb.oltAdapterName:
303 assert.Equal(t, "Voltha-olt", a.Vendor)
304 case nb.onuAdapterName:
305 assert.Equal(t, "Voltha-onu", a.Vendor)
306 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000307 logger.Fatal("unregistered-adapter", a.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500308 }
309 }
310 deviceTypes, err := nbi.ListDeviceTypes(getContext(), &empty.Empty{})
311 assert.Nil(t, err)
312 assert.NotNil(t, deviceTypes)
313 assert.Equal(t, 2, len(deviceTypes.Items))
314 for _, dt := range deviceTypes.Items {
315 switch dt.Id {
316 case nb.oltAdapterName:
317 assert.Equal(t, nb.oltAdapterName, dt.Adapter)
318 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
319 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
320 case nb.onuAdapterName:
321 assert.Equal(t, nb.onuAdapterName, dt.Adapter)
322 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
323 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
324 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000325 logger.Fatal("invalid-device-type", dt.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500326 }
327 }
328}
329
330func (nb *NBTest) testCreateDevice(t *testing.T, nbi *APIHandler) {
331 // Create a valid device
332 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
333 assert.Nil(t, err)
334 assert.NotNil(t, oltDevice)
335 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
336 assert.Nil(t, err)
337 assert.NotNil(t, device)
338 assert.Equal(t, oltDevice.String(), device.String())
339
340 // Try to create the same device
341 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
342 assert.NotNil(t, err)
343 assert.Equal(t, "Device is already pre-provisioned", err.Error())
344
345 // Try to create a device with invalid data
346 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName})
347 assert.NotNil(t, err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530348 assert.Equal(t, "no-device-info-present; MAC or HOSTIP&PORT", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500349
350 // Ensure we only have 1 device in the Core
351 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
352 assert.Nil(t, err)
353 assert.NotNil(t, devices)
354 assert.Equal(t, 1, len(devices.Items))
355 assert.Equal(t, oltDevice.String(), devices.Items[0].String())
356
357 //Remove the device
358 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
359 assert.Nil(t, err)
360
361 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
362 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
363 return devices != nil && len(devices.Items) == 0
364 }
khenaidoo442e7c72020-03-10 16:13:48 -0400365 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500366 assert.Nil(t, err)
367}
368
369func (nb *NBTest) testEnableDevice(t *testing.T, nbi *APIHandler) {
370 // Create a device that has no adapter registered
371 oltDeviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegistered", MacAddress: "aa:bb:cc:cc:ee:ff"})
372 assert.Nil(t, err)
373 assert.NotNil(t, oltDeviceNoAdapter)
374
375 // Try to enable the oltDevice and check the error message
376 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
377 assert.NotNil(t, err)
378 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegistered", err.Error())
379
380 //Remove the device
381 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
382 assert.Nil(t, err)
383
384 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
385 var vdFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
386 return devices != nil && len(devices.Items) == 0
387 }
khenaidoo442e7c72020-03-10 16:13:48 -0400388 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vdFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500389 assert.Nil(t, err)
390
khenaidoo67b22152020-03-02 16:01:25 -0500391 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
392 var wg sync.WaitGroup
393 wg.Add(1)
394 go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg)
395
khenaidoob64fc8a2019-11-27 15:08:19 -0500396 // Create the device with valid data
397 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
398 assert.Nil(t, err)
399 assert.NotNil(t, oltDevice)
400
401 // Verify oltDevice exist in the core
402 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
403 assert.Nil(t, err)
404 assert.Equal(t, 1, len(devices.Items))
405 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
406
407 // Enable the oltDevice
408 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
409 assert.Nil(t, err)
410
411 // Wait for the logical device to be in the ready state
412 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
413 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
414 }
415 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
416 assert.Nil(t, err)
417
418 // Verify that the devices have been setup correctly
419 nb.verifyDevices(t, nbi)
420
421 // Get latest oltDevice data
422 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
423 assert.Nil(t, err)
424
425 // Verify that the logical device has been setup correctly
426 nb.verifyLogicalDevices(t, oltDevice, nbi)
khenaidoo67b22152020-03-02 16:01:25 -0500427
428 // Wait until all flows has been sent to the devices successfully
429 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500430}
431
432func (nb *NBTest) testDisableAndReEnableRootDevice(t *testing.T, nbi *APIHandler) {
433 //Get an OLT device
434 oltDevice, err := nb.getADevice(true, nbi)
435 assert.Nil(t, err)
436 assert.NotNil(t, oltDevice)
437
438 // Disable the oltDevice
439 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
440 assert.Nil(t, err)
441
442 // Wait for the old device to be disabled
443 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
444 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
445 }
446 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
447 assert.Nil(t, err)
448
449 // Verify that all onu devices are disabled as well
npujar467fe752020-01-16 20:17:45 +0530450 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500451 assert.Nil(t, err)
452 for _, onu := range onuDevices.Items {
453 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
454 assert.Nil(t, err)
455 }
456
457 // Wait for the logical device to satisfy the expected condition
458 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500459 if ld == nil {
460 return false
461 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500462 for _, lp := range ld.Ports {
463 if (lp.OfpPort.Config&uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
464 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LINK_DOWN) {
465 return false
466 }
467 }
468 return true
469 }
470 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
471 assert.Nil(t, err)
472
473 // Reenable the oltDevice
474 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
475 assert.Nil(t, err)
476
477 // Wait for the old device to be enabled
478 vdFunction = func(device *voltha.Device) bool {
479 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
480 }
481 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
482 assert.Nil(t, err)
483
484 // Verify that all onu devices are enabled as well
npujar467fe752020-01-16 20:17:45 +0530485 onuDevices, err = nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500486 assert.Nil(t, err)
487 for _, onu := range onuDevices.Items {
488 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
489 assert.Nil(t, err)
490 }
491
492 // Wait for the logical device to satisfy the expected condition
493 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500494 if ld == nil {
495 return false
496 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500497 for _, lp := range ld.Ports {
498 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
499 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
500 return false
501 }
502 }
503 return true
504 }
505 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
506 assert.Nil(t, err)
507}
508
khenaidoo93d5a3d2020-01-15 12:37:05 -0500509func (nb *NBTest) testDisableAndDeleteAllDevice(t *testing.T, nbi *APIHandler) {
510 //Get an OLT device
511 oltDevice, err := nb.getADevice(true, nbi)
512 assert.Nil(t, err)
513 assert.NotNil(t, oltDevice)
514
515 // Disable the oltDevice
516 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
517 assert.Nil(t, err)
518
519 // Wait for the olt device to be disabled
520 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
521 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
522 }
523 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
524 assert.Nil(t, err)
525
526 // Verify that all onu devices are disabled as well
npujar467fe752020-01-16 20:17:45 +0530527 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoo93d5a3d2020-01-15 12:37:05 -0500528 assert.Nil(t, err)
529 for _, onu := range onuDevices.Items {
530 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
531 assert.Nil(t, err)
532 }
533
534 // Delete the oltDevice
535 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
536 assert.Nil(t, err)
537
538 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
539 return devices != nil && len(devices.Items) == 0
540 }
541 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
542 assert.Nil(t, err)
543
544 // Wait for absence of logical device
545 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
546 return lds != nil && len(lds.Items) == 0
547 }
548
549 err = waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
550 assert.Nil(t, err)
551}
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500552func (nb *NBTest) testEnableAndDeleteAllDevice(t *testing.T, nbi *APIHandler) {
553 //Create the device with valid data
554 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
555 assert.Nil(t, err)
556 assert.NotNil(t, oltDevice)
557
558 //Get an OLT device
559 oltDevice, err = nb.getADevice(true, nbi)
560 assert.Nil(t, err)
561 assert.NotNil(t, oltDevice)
562
563 // Enable the oltDevice
564 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
565 assert.Nil(t, err)
566
567 // Wait for the logical device to be in the ready state
568 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
569 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
570 }
571 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
572 assert.Nil(t, err)
573
574 //Get all child devices
575 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
576 assert.Nil(t, err)
577
578 // Wait for the all onu devices to be enabled
579 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
580 return device.AdminState == voltha.AdminState_ENABLED
581 }
582 for _, onu := range onuDevices.Items {
583 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
584 assert.Nil(t, err)
585 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500586 // Wait for each onu device to get deleted
587 var vdFunc isDeviceConditionSatisfied = func(device *voltha.Device) bool {
588 return device == nil
589 }
590
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500591 // Delete the onuDevice
592 for _, onu := range onuDevices.Items {
593 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: onu.Id})
594 assert.Nil(t, err)
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500595 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunc, nbi)
596 assert.Nil(t, err)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500597 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500598
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500599 // Disable the oltDevice
600 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
601 assert.Nil(t, err)
602
603 // Wait for the olt device to be disabled
604 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
605 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
606 }
607 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vFunction, nbi)
608 assert.Nil(t, err)
609
610 // Delete the oltDevice
611 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
612 assert.Nil(t, err)
613
614 var vFunc isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
615 return devices != nil && len(devices.Items) == 0
616 }
617 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunc)
618 assert.Nil(t, err)
619}
kesavandbc2d1622020-01-21 00:42:01 -0500620func (nb *NBTest) testDisableAndEnablePort(t *testing.T, nbi *APIHandler) {
621 //Get an OLT device
622 var cp *voltha.Port
623 oltDevice, err := nb.getADevice(true, nbi)
624 assert.Nil(t, err)
625 assert.NotNil(t, oltDevice)
626
627 for _, cp = range oltDevice.Ports {
628 if cp.Type == voltha.Port_PON_OLT {
629 break
630 }
631
632 }
633 assert.NotNil(t, cp)
634 cp.DeviceId = oltDevice.Id
635
636 // Disable the NW Port of oltDevice
637 _, err = nbi.DisablePort(getContext(), cp)
638 assert.Nil(t, err)
639 // Wait for the olt device Port to be disabled
640 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
641 for _, port := range device.Ports {
642 if port.PortNo == cp.PortNo {
643 return port.AdminState == voltha.AdminState_DISABLED
644 }
645 }
646 return false
647 }
648 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
649 assert.Nil(t, err)
650 // Wait for the logical device to satisfy the expected condition
651 var vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500652 if ld == nil {
653 return false
654 }
kesavandbc2d1622020-01-21 00:42:01 -0500655 for _, lp := range ld.Ports {
656 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
657 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
658 return false
659 }
660 }
661 return true
662 }
663 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
664 assert.Nil(t, err)
665
666 // Enable the NW Port of oltDevice
667 _, err = nbi.EnablePort(getContext(), cp)
668 assert.Nil(t, err)
669
670 // Wait for the olt device Port to be enabled
671 vdFunction = func(device *voltha.Device) bool {
672 for _, port := range device.Ports {
673 if port.PortNo == cp.PortNo {
674 return port.AdminState == voltha.AdminState_ENABLED
675 }
676 }
677 return false
678 }
679 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
680 assert.Nil(t, err)
681 // Wait for the logical device to satisfy the expected condition
682 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500683 if ld == nil {
684 return false
685 }
kesavandbc2d1622020-01-21 00:42:01 -0500686 for _, lp := range ld.Ports {
687 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
688 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
689 return false
690 }
691 }
692 return true
693 }
694 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
695 assert.Nil(t, err)
696
697 // Disable a non-PON port
698 for _, cp = range oltDevice.Ports {
699 if cp.Type != voltha.Port_PON_OLT {
700 break
701 }
702
703 }
704 assert.NotNil(t, cp)
705 cp.DeviceId = oltDevice.Id
706
707 // Disable the NW Port of oltDevice
708 _, err = nbi.DisablePort(getContext(), cp)
709 assert.NotNil(t, err)
710
711}
khenaidoo93d5a3d2020-01-15 12:37:05 -0500712
Girish Gowdra408cd962020-03-11 14:31:31 -0700713func (nb *NBTest) testDeviceRebootWhenOltIsEnabled(t *testing.T, nbi *APIHandler) {
714 //Get an OLT device
715 oltDevice, err := nb.getADevice(true, nbi)
716 assert.Nil(t, err)
717 assert.NotNil(t, oltDevice)
718 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
719 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
720
721 // Verify that we have one or more ONUs to start with
722 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
723 assert.Nil(t, err)
724 assert.NotNil(t, onuDevices)
725 assert.Greater(t, len(onuDevices.Items), 0)
726
727 // Reboot the OLT and very that Connection Status goes to UNREACHABLE and operation status to UNKNOWN
728 _, err = nbi.RebootDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
729 assert.Nil(t, err)
730
731 var vlFunction0 = func(d *voltha.Device) bool {
732 return d.ConnectStatus == voltha.ConnectStatus_UNREACHABLE && d.OperStatus == voltha.OperStatus_UNKNOWN
733 }
734
735 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction0, nbi)
736 assert.Nil(t, err)
737
738 // Wait for the logical device to satisfy the expected condition
739 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
740 return ld == nil
741 }
742
743 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
744 assert.Nil(t, err)
745
746 // Wait for the device to satisfy the expected condition (device does not have flows)
747 var vlFunction2 = func(d *voltha.Device) bool {
748 var deviceFlows *ofp.Flows
749 var err error
750 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
751 return false
752 }
753 return len(deviceFlows.Items) == 0
754 }
755
756 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
757 assert.Nil(t, err)
758
759 // Wait for the device to satisfy the expected condition (there are no child devices)
760 var vlFunction3 = func(d *voltha.Device) bool {
761 var devices *voltha.Devices
762 var err error
763 if devices, err = nbi.ListDevices(getContext(), nil); err != nil {
764 return false
765 }
766 for _, device := range devices.Items {
767 if device.ParentId == d.Id {
768 // We have a child device still left
769 return false
770 }
771 }
772 return true
773 }
774
775 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction3, nbi)
776 assert.Nil(t, err)
777
778 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
779 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
780 deviceAgent := nbi.deviceMgr.getDeviceAgent(getContext(), oltDevice.Id)
781 err = deviceAgent.updateDeviceStatus(getContext(), voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
782 assert.Nil(t, err)
783
784 // Verify the device connection and operation states
785 oltDevice, err = nb.getADevice(true, nbi)
786 assert.Nil(t, err)
787 assert.NotNil(t, oltDevice)
788 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
789 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
790
791 // Wait for the logical device to satisfy the expected condition
792 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
793 return ld != nil
794 }
795 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
796 assert.Nil(t, err)
797
798 // Verify that logical device is created again
799 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
800 assert.Nil(t, err)
801 assert.NotNil(t, logicalDevices)
802 assert.Equal(t, 1, len(logicalDevices.Items))
803
804 // Verify that we have no ONUs left
805 onuDevices, err = nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
806 assert.Nil(t, err)
807 assert.NotNil(t, onuDevices)
808 assert.Equal(t, 0, len(onuDevices.Items))
809}
810
Scott Baker432f9be2020-03-26 11:56:30 -0700811func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi *APIHandler) {
812 // -----------------------------------------------------------------------
813 // SubTest 1: Omci test action should fail due to nonexistent device id
814
815 request := &voltha.OmciTestRequest{Id: "123", Uuid: "456"}
816 _, err := nbi.StartOmciTestAction(getContext(), request)
817 assert.NotNil(t, err)
818 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
819
820 // -----------------------------------------------------------------------
821 // SubTest 2: Error should be returned for device with no adapter registered
822
823 // Create a device that has no adapter registered
824 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: "aa:bb:cc:cc:ee:01"})
825 assert.Nil(t, err)
826 assert.NotNil(t, deviceNoAdapter)
827
828 // Omci test action should fail due to nonexistent adapter
829 request = &voltha.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
830 _, err = nbi.StartOmciTestAction(getContext(), request)
831 assert.NotNil(t, err)
832 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegisteredOmciTest", err.Error())
833
834 //Remove the device
835 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
836 assert.Nil(t, err)
837
838 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
839 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
840 return devices != nil && len(devices.Items) == 0
841 }
842 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
843 assert.Nil(t, err)
844
845 // -----------------------------------------------------------------------
846 // SubTest 3: Omci test action should succeed on valid ONU
847
848 // Create the device with valid data
849 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
850 assert.Nil(t, err)
851 assert.NotNil(t, oltDevice)
852
853 // Verify oltDevice exist in the core
854 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
855 assert.Nil(t, err)
856 assert.Equal(t, 1, len(devices.Items))
857 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
858
859 // Enable the oltDevice
860 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
861 assert.Nil(t, err)
862
863 // Wait for the logical device to be in the ready state
864 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
865 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
866 }
867 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
868 assert.Nil(t, err)
869
870 // Wait for the olt device to be enabled
871 vdFunction := func(device *voltha.Device) bool {
872 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
873 }
874 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
875 assert.Nil(t, err)
876
877 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
878 assert.Nil(t, err)
879 assert.Greater(t, len(onuDevices.Items), 0)
880
881 onuDevice := onuDevices.Items[0]
882
883 // Omci test action should succeed
884 request = &voltha.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
885 resp, err := nbi.StartOmciTestAction(getContext(), request)
886 assert.Nil(t, err)
887 assert.Equal(t, resp.Result, voltha.TestResponse_SUCCESS)
888
889 //Remove the device
890 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
891 assert.Nil(t, err)
892 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
893 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
894 assert.Nil(t, err)
895}
896
khenaidoo67b22152020-03-02 16:01:25 -0500897func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
898 matchFields := make([]*ofp.OfpOxmField, 0)
899 for _, val := range fa.MatchFields {
900 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
901 }
902 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
903}
904
905func createMetadata(cTag int, techProfile int, port int) uint64 {
906 md := 0
907 md = (md | (cTag & 0xFFFF)) << 16
908 md = (md | (techProfile & 0xFFFF)) << 32
909 return uint64(md | (port & 0xFFFFFFFF))
910}
911
912func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi *APIHandler, numNNIPorts int, numUNIPorts int) {
913 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
914 // Wait for logical device to have all the flows
915 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
916 return lds != nil && len(lds.Items) == 1 && len(lds.Items[0].Flows.Items) == expectedNumFlows
917 }
918 // No timeout implies a success
919 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
920 assert.Nil(t, err)
921}
922
923func (nb *NBTest) sendTrapFlows(t *testing.T, nbi *APIHandler, logicalDevice *voltha.LogicalDevice, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
924 // Send flows for the parent device
925 var nniPorts []*voltha.LogicalPort
926 var uniPorts []*voltha.LogicalPort
927 for _, p := range logicalDevice.Ports {
928 if p.RootPort {
929 nniPorts = append(nniPorts, p)
930 } else {
931 uniPorts = append(uniPorts, p)
932 }
933 }
934 assert.Equal(t, 1, len(nniPorts))
935 //assert.Greater(t, len(uniPorts), 1 )
936 nniPort := nniPorts[0].OfpPort.PortNo
937 maxInt32 := uint64(0xFFFFFFFF)
938 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
939 var fa *flows.FlowArgs
940 fa = &flows.FlowArgs{
941 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
942 MatchFields: []*ofp.OfpOxmOfbField{
943 flows.InPort(nniPort),
944 flows.EthType(35020),
945 },
946 Actions: []*ofp.OfpAction{
947 flows.Output(controllerPortMask),
948 },
949 }
950 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
951 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
952 assert.Nil(t, err)
953
954 fa = &flows.FlowArgs{
955 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
956 MatchFields: []*ofp.OfpOxmOfbField{
957 flows.InPort(nniPort),
958 flows.EthType(2048),
959 flows.IpProto(17),
960 flows.UdpSrc(67),
961 flows.UdpDst(68),
962 },
963 Actions: []*ofp.OfpAction{
964 flows.Output(controllerPortMask),
965 },
966 }
967 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
968 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
969 assert.Nil(t, err)
970
971 fa = &flows.FlowArgs{
972 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
973 MatchFields: []*ofp.OfpOxmOfbField{
974 flows.InPort(nniPort),
975 flows.EthType(34525),
976 flows.IpProto(17),
977 flows.UdpSrc(546),
978 flows.UdpDst(547),
979 },
980 Actions: []*ofp.OfpAction{
981 flows.Output(controllerPortMask),
982 },
983 }
984 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
985 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
986 assert.Nil(t, err)
987
988 return len(nniPorts), len(uniPorts)
989}
990
991func (nb *NBTest) sendEAPFlows(t *testing.T, nbi *APIHandler, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
992 maxInt32 := uint64(0xFFFFFFFF)
993 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
994 fa := &flows.FlowArgs{
995 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},
996 MatchFields: []*ofp.OfpOxmOfbField{
997 flows.InPort(port.PortNo),
998 flows.EthType(34958),
999 flows.VlanVid(8187),
1000 },
1001 Actions: []*ofp.OfpAction{
1002 flows.Output(controllerPortMask),
1003 },
1004 }
1005 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1006 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP)
1007 assert.Nil(t, err)
1008}
1009
1010func (nb *NBTest) monitorLogicalDevice(t *testing.T, nbi *APIHandler, numNNIPorts int, numUNIPorts int, wg *sync.WaitGroup) {
1011 defer wg.Done()
1012 if nb.core.logicalDeviceMgr.grpcNbiHdlr != nbi {
1013 nb.core.logicalDeviceMgr.setGrpcNbiHandler(nbi)
1014 }
1015
1016 // Clear any existing flows on the adapters
1017 nb.oltAdapter.ClearFlows()
1018 nb.onuAdapter.ClearFlows()
1019
1020 // Wait until a logical device is ready
1021 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
1022 if lds == nil || len(lds.Items) != 1 {
1023 return false
1024 }
1025 // Ensure there are both NNI ports and at least one UNI port on the logical device
1026 ld := lds.Items[0]
1027 nniPort := false
1028 uniPort := false
1029 for _, p := range ld.Ports {
1030 nniPort = nniPort || p.RootPort == true
1031 uniPort = uniPort || p.RootPort == false
1032 if nniPort && uniPort {
1033 return true
1034 }
1035 }
1036 return false
1037 }
1038 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
1039 assert.Nil(t, err)
1040
1041 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
1042 assert.Nil(t, err)
1043 assert.NotNil(t, logicalDevices)
1044 assert.Equal(t, 1, len(logicalDevices.Items))
1045
1046 logicalDevice := logicalDevices.Items[0]
1047 meterID := rand.Uint32()
1048
1049 // Add a meter to the logical device
1050 meterMod := &ofp.OfpMeterMod{
1051 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1052 Flags: rand.Uint32(),
1053 MeterId: meterID,
1054 Bands: []*ofp.OfpMeterBandHeader{
1055 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1056 Rate: rand.Uint32(),
1057 BurstSize: rand.Uint32(),
1058 Data: nil,
1059 },
1060 },
1061 }
1062 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{Id: logicalDevice.Id, MeterMod: meterMod})
1063 assert.Nil(t, err)
1064
1065 // Send initial set of Trap flows
1066 startingVlan := 4091
1067 nb.sendTrapFlows(t, nbi, logicalDevice, uint64(meterID), startingVlan)
1068
1069 // Listen for port events
khenaidoo442e7c72020-03-10 16:13:48 -04001070 start := time.Now()
Girish Gowdra408cd962020-03-11 14:31:31 -07001071 processedNniLogicalPorts := 0
1072 processedUniLogicalPorts := 0
1073
khenaidoo67b22152020-03-02 16:01:25 -05001074 for event := range nbi.changeEventQueue {
1075 startingVlan++
1076 if portStatus, ok := (event.Event).(*ofp.ChangeEvent_PortStatus); ok {
1077 ps := portStatus.PortStatus
1078 if ps.Reason == ofp.OfpPortReason_OFPPR_ADD {
khenaidoo67b22152020-03-02 16:01:25 -05001079 if ps.Desc.PortNo >= uint32(nb.startingUNIPortNo) {
Girish Gowdra408cd962020-03-11 14:31:31 -07001080 processedUniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001081 nb.sendEAPFlows(t, nbi, logicalDevice.Id, ps.Desc, startingVlan, uint64(meterID))
Girish Gowdra408cd962020-03-11 14:31:31 -07001082 } else {
1083 processedNniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001084 }
1085 }
1086 }
Girish Gowdra408cd962020-03-11 14:31:31 -07001087
1088 if processedNniLogicalPorts >= numNNIPorts && processedUniLogicalPorts >= numUNIPorts {
khenaidoo442e7c72020-03-10 16:13:48 -04001089 fmt.Println("Total time to send all flows:", time.Since(start))
khenaidoo67b22152020-03-02 16:01:25 -05001090 break
1091 }
1092 }
1093 //Verify the flow count on the logical device
1094 nb.verifyLogicalDeviceFlowCount(t, nbi, numNNIPorts, numUNIPorts)
1095
1096 // Wait until all flows have been sent to the OLT adapters
1097 var oltVFunc isConditionSatisfied = func() bool {
1098 return nb.oltAdapter.GetFlowCount() >= (numNNIPorts*3)+numNNIPorts*numUNIPorts
1099 }
1100 err = waitUntilCondition(nb.maxTimeout, nbi, oltVFunc)
1101 assert.Nil(t, err)
1102
1103 // Wait until all flows have been sent to the ONU adapters
1104 var onuVFunc isConditionSatisfied = func() bool {
1105 return nb.onuAdapter.GetFlowCount() == numUNIPorts
1106 }
1107 err = waitUntilCondition(nb.maxTimeout, nbi, onuVFunc)
1108 assert.Nil(t, err)
1109}
1110
khenaidoob64fc8a2019-11-27 15:08:19 -05001111func TestSuite1(t *testing.T) {
khenaidoo67b22152020-03-02 16:01:25 -05001112 f, err := os.Create("profile.cpu")
1113 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001114 logger.Fatalf("could not create CPU profile: %v\n ", err)
khenaidoo67b22152020-03-02 16:01:25 -05001115 }
1116 defer f.Close()
1117 runtime.SetBlockProfileRate(1)
1118 runtime.SetMutexProfileFraction(-1)
1119 if err := pprof.StartCPUProfile(f); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001120 logger.Fatalf("could not start CPU profile: %v\n", err)
khenaidoo67b22152020-03-02 16:01:25 -05001121 }
1122 defer pprof.StopCPUProfile()
1123
khenaidoo442e7c72020-03-10 16:13:48 -04001124 //log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
1125
khenaidoob64fc8a2019-11-27 15:08:19 -05001126 nb := newNBTest()
1127 assert.NotNil(t, nb)
1128
1129 defer nb.stopAll()
1130
1131 // Start the Core
1132 nb.startCore(false)
1133
1134 // Set the grpc API interface - no grpc server is running in unit test
1135 nbi := NewAPIHandler(nb.core)
1136
1137 // 1. Basic test with no data in Core
1138 nb.testCoreWithoutData(t, nbi)
1139
1140 // Create/register the adapters
Thomas Lee Se5a44012019-11-07 20:32:24 +05301141 nb.createAndregisterAdapters(t)
khenaidoob64fc8a2019-11-27 15:08:19 -05001142
1143 // 2. Test adapter registration
1144 nb.testAdapterRegistration(t, nbi)
1145
Scott Baker8cb47bb2020-04-01 09:57:20 -07001146 numberOfDeviceTestRuns := 2
khenaidoo93d5a3d2020-01-15 12:37:05 -05001147 for i := 1; i <= numberOfDeviceTestRuns; i++ {
khenaidoo67b22152020-03-02 16:01:25 -05001148 //3. Test create device
khenaidoo93d5a3d2020-01-15 12:37:05 -05001149 nb.testCreateDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001150
khenaidoo93d5a3d2020-01-15 12:37:05 -05001151 // 4. Test Enable a device
1152 nb.testEnableDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001153
khenaidoo93d5a3d2020-01-15 12:37:05 -05001154 // 5. Test disable and ReEnable a root device
1155 nb.testDisableAndReEnableRootDevice(t, nbi)
khenaidoo67b22152020-03-02 16:01:25 -05001156
kesavandbc2d1622020-01-21 00:42:01 -05001157 // 6. Test disable and Enable pon port of OLT device
1158 nb.testDisableAndEnablePort(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001159
Girish Gowdra408cd962020-03-11 14:31:31 -07001160 // 7.Test Device unreachable when OLT is enabled
1161 nb.testDeviceRebootWhenOltIsEnabled(t, nbi)
1162
1163 // 8. Test disable and delete all devices
khenaidoo93d5a3d2020-01-15 12:37:05 -05001164 nb.testDisableAndDeleteAllDevice(t, nbi)
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001165
Girish Gowdra408cd962020-03-11 14:31:31 -07001166 // 9. Test enable and delete all devices
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001167 nb.testEnableAndDeleteAllDevice(t, nbi)
Scott Baker432f9be2020-03-26 11:56:30 -07001168
1169 // 10. Test omci test
1170 nb.testStartOmciTestAction(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001171 }
khenaidoob64fc8a2019-11-27 15:08:19 -05001172
1173 //x. TODO - More tests to come
1174}