blob: e54c14c6bacbcceb7986e28f5b643487f68f4085 [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"
Matteo Scandolod525ae32020-04-02 17:27:29 -070037 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
38 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080039 "github.com/opencord/voltha-lib-go/v3/pkg/version"
40 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
41 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob64fc8a2019-11-27 15:08:19 -050042 "github.com/phayes/freeport"
43 "github.com/stretchr/testify/assert"
44 "google.golang.org/grpc/codes"
45 "google.golang.org/grpc/status"
khenaidoob64fc8a2019-11-27 15:08:19 -050046)
47
48type NBTest struct {
Matteo Scandolod525ae32020-04-02 17:27:29 -070049 etcdServer *mock_etcd.EtcdServer
khenaidoo67b22152020-03-02 16:01:25 -050050 core *Core
51 kClient kafka.Client
52 kvClientPort int
53 numONUPerOLT int
54 startingUNIPortNo int
55 oltAdapter *cm.OLTAdapter
56 onuAdapter *cm.ONUAdapter
57 oltAdapterName string
58 onuAdapterName string
59 coreInstanceID string
60 defaultTimeout time.Duration
61 maxTimeout time.Duration
khenaidoob64fc8a2019-11-27 15:08:19 -050062}
63
64func newNBTest() *NBTest {
65 test := &NBTest{}
66 // Start the embedded etcd server
67 var err error
68 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.nb.test", "voltha.rwcore.nb.etcd", "error")
69 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000070 logger.Fatal(err)
khenaidoob64fc8a2019-11-27 15:08:19 -050071 }
72 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -070073 test.kClient = mock_kafka.NewKafkaClient()
khenaidoob64fc8a2019-11-27 15:08:19 -050074 test.oltAdapterName = "olt_adapter_mock"
75 test.onuAdapterName = "onu_adapter_mock"
76 test.coreInstanceID = "rw-nbi-test"
khenaidoo32836732020-03-05 16:10:44 -050077 test.defaultTimeout = 10 * time.Second
78 test.maxTimeout = 20 * time.Second
khenaidoob64fc8a2019-11-27 15:08:19 -050079 return test
80}
81
82func (nb *NBTest) startCore(inCompeteMode bool) {
Thomas Lee Se5a44012019-11-07 20:32:24 +053083 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
84 defer cancel()
khenaidoob64fc8a2019-11-27 15:08:19 -050085 cfg := config.NewRWCoreFlags()
86 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -040087 cfg.DefaultRequestTimeout = nb.defaultTimeout
88 cfg.DefaultCoreTimeout = nb.defaultTimeout
khenaidoob64fc8a2019-11-27 15:08:19 -050089 cfg.KVStorePort = nb.kvClientPort
90 cfg.InCompetingMode = inCompeteMode
91 grpcPort, err := freeport.GetFreePort()
92 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000093 logger.Fatal("Cannot get a freeport for grpc")
khenaidoob64fc8a2019-11-27 15:08:19 -050094 }
95 cfg.GrpcPort = grpcPort
96 cfg.GrpcHost = "127.0.0.1"
97 setCoreCompeteMode(inCompeteMode)
98 client := setupKVClient(cfg, nb.coreInstanceID)
Thomas Lee Se5a44012019-11-07 20:32:24 +053099 nb.core = NewCore(ctx, nb.coreInstanceID, cfg, client, nb.kClient)
100 err = nb.core.Start(context.Background())
101 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000102 logger.Fatal("Cannot start core")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530103 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500104}
105
Thomas Lee Se5a44012019-11-07 20:32:24 +0530106func (nb *NBTest) createAndregisterAdapters(t *testing.T) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500107 // Setup the mock OLT adapter
108 oltAdapter, err := createMockAdapter(OltAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.oltAdapterName)
109 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000110 logger.Fatalw("setting-mock-olt-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500111 }
khenaidoo67b22152020-03-02 16:01:25 -0500112 nb.oltAdapter = (oltAdapter).(*cm.OLTAdapter)
113 nb.numONUPerOLT = nb.oltAdapter.GetNumONUPerOLT()
114 nb.startingUNIPortNo = nb.oltAdapter.GetStartingUNIPortNo()
115
khenaidoob64fc8a2019-11-27 15:08:19 -0500116 // Register the adapter
117 registrationData := &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700118 Id: nb.oltAdapterName,
119 Vendor: "Voltha-olt",
120 Version: version.VersionInfo.Version,
121 Type: nb.oltAdapterName,
122 CurrentReplica: 1,
123 TotalReplicas: 1,
124 Endpoint: nb.oltAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500125 }
126 types := []*voltha.DeviceType{{Id: nb.oltAdapterName, Adapter: nb.oltAdapterName, AcceptsAddRemoveFlowUpdates: true}}
127 deviceTypes := &voltha.DeviceTypes{Items: types}
Thomas Lee Se5a44012019-11-07 20:32:24 +0530128 if _, err := nb.core.adapterMgr.registerAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000129 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530130 assert.NotNil(t, err)
131 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500132
133 // Setup the mock ONU adapter
khenaidoo67b22152020-03-02 16:01:25 -0500134 onuAdapter, err := createMockAdapter(OnuAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.onuAdapterName)
135 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000136 logger.Fatalw("setting-mock-onu-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500137 }
khenaidoo67b22152020-03-02 16:01:25 -0500138 nb.onuAdapter = (onuAdapter).(*cm.ONUAdapter)
139
khenaidoob64fc8a2019-11-27 15:08:19 -0500140 // Register the adapter
141 registrationData = &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700142 Id: nb.onuAdapterName,
143 Vendor: "Voltha-onu",
144 Version: version.VersionInfo.Version,
145 Type: nb.onuAdapterName,
146 CurrentReplica: 1,
147 TotalReplicas: 1,
148 Endpoint: nb.onuAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500149 }
150 types = []*voltha.DeviceType{{Id: nb.onuAdapterName, Adapter: nb.onuAdapterName, AcceptsAddRemoveFlowUpdates: true}}
151 deviceTypes = &voltha.DeviceTypes{Items: types}
Thomas Lee Se5a44012019-11-07 20:32:24 +0530152 if _, err := nb.core.adapterMgr.registerAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000153 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530154 assert.NotNil(t, err)
155 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500156}
157
158func (nb *NBTest) stopAll() {
159 if nb.kClient != nil {
160 nb.kClient.Stop()
161 }
162 if nb.core != nil {
163 nb.core.Stop(context.Background())
164 }
165 if nb.etcdServer != nil {
166 stopEmbeddedEtcdServer(nb.etcdServer)
167 }
168}
169
170func (nb *NBTest) verifyLogicalDevices(t *testing.T, oltDevice *voltha.Device, nbi *APIHandler) {
171 // Get the latest set of logical devices
172 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
173 assert.Nil(t, err)
174 assert.NotNil(t, logicalDevices)
175 assert.Equal(t, 1, len(logicalDevices.Items))
176
177 ld := logicalDevices.Items[0]
178 assert.NotEqual(t, "", ld.Id)
179 assert.NotEqual(t, uint64(0), ld.DatapathId)
180 assert.Equal(t, "olt_adapter_mock", ld.Desc.HwDesc)
181 assert.Equal(t, "olt_adapter_mock", ld.Desc.SwDesc)
182 assert.NotEqual(t, "", ld.RootDeviceId)
183 assert.NotEqual(t, "", ld.Desc.SerialNum)
184 assert.Equal(t, uint32(256), ld.SwitchFeatures.NBuffers)
185 assert.Equal(t, uint32(2), ld.SwitchFeatures.NTables)
186 assert.Equal(t, uint32(15), ld.SwitchFeatures.Capabilities)
187 assert.Equal(t, 1+nb.numONUPerOLT, len(ld.Ports))
188 assert.Equal(t, oltDevice.ParentId, ld.Id)
189 //Expected port no
190 expectedPortNo := make(map[uint32]bool)
191 expectedPortNo[uint32(2)] = false
192 for i := 0; i < nb.numONUPerOLT; i++ {
193 expectedPortNo[uint32(i+100)] = false
194 }
195 for _, p := range ld.Ports {
196 assert.Equal(t, p.OfpPort.PortNo, p.DevicePortNo)
197 assert.Equal(t, uint32(4), p.OfpPort.State)
198 expectedPortNo[p.OfpPort.PortNo] = true
199 if strings.HasPrefix(p.Id, "nni") {
200 assert.Equal(t, true, p.RootPort)
201 //assert.Equal(t, uint32(2), p.OfpPort.PortNo)
202 assert.Equal(t, p.Id, fmt.Sprintf("nni-%d", p.DevicePortNo))
203 } else {
204 assert.Equal(t, p.Id, fmt.Sprintf("uni-%d", p.DevicePortNo))
205 assert.Equal(t, false, p.RootPort)
206 }
207 }
208}
209
210func (nb *NBTest) verifyDevices(t *testing.T, nbi *APIHandler) {
211 // Get the latest set of devices
212 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
213 assert.Nil(t, err)
214 assert.NotNil(t, devices)
215
khenaidoo67b22152020-03-02 16:01:25 -0500216 // A device is ready to be examined when its ADMIN state is ENABLED and OPERATIONAL state is ACTIVE
khenaidoob64fc8a2019-11-27 15:08:19 -0500217 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
218 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
219 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500220
khenaidoo67b22152020-03-02 16:01:25 -0500221 var wg sync.WaitGroup
222 for _, device := range devices.Items {
223 wg.Add(1)
224 go func(wg *sync.WaitGroup, device *voltha.Device) {
225 // Wait until the device is in the right state
226 err := waitUntilDeviceReadiness(device.Id, nb.maxTimeout, vFunction, nbi)
227 assert.Nil(t, err)
228
229 // Now, verify the details of the device. First get the latest update
230 d, err := nbi.GetDevice(getContext(), &voltha.ID{Id: device.Id})
231 assert.Nil(t, err)
232 assert.Equal(t, voltha.AdminState_ENABLED, d.AdminState)
233 assert.Equal(t, voltha.ConnectStatus_REACHABLE, d.ConnectStatus)
234 assert.Equal(t, voltha.OperStatus_ACTIVE, d.OperStatus)
235 assert.Equal(t, d.Type, d.Adapter)
236 assert.NotEqual(t, "", d.MacAddress)
237 assert.NotEqual(t, "", d.SerialNumber)
238
239 if d.Type == "olt_adapter_mock" {
240 assert.Equal(t, true, d.Root)
241 assert.NotEqual(t, "", d.Id)
242 assert.NotEqual(t, "", d.ParentId)
243 assert.Nil(t, d.ProxyAddress)
244 } else if d.Type == "onu_adapter_mock" {
245 assert.Equal(t, false, d.Root)
246 assert.NotEqual(t, uint32(0), d.Vlan)
247 assert.NotEqual(t, "", d.Id)
248 assert.NotEqual(t, "", d.ParentId)
249 assert.NotEqual(t, "", d.ProxyAddress.DeviceId)
250 assert.Equal(t, "olt_adapter_mock", d.ProxyAddress.DeviceType)
khenaidoob64fc8a2019-11-27 15:08:19 -0500251 } else {
khenaidoo67b22152020-03-02 16:01:25 -0500252 assert.Error(t, errors.New("invalid-device-type"))
khenaidoob64fc8a2019-11-27 15:08:19 -0500253 }
khenaidoo67b22152020-03-02 16:01:25 -0500254 assert.Equal(t, 2, len(d.Ports))
255 for _, p := range d.Ports {
256 assert.Equal(t, voltha.AdminState_ENABLED, p.AdminState)
257 assert.Equal(t, voltha.OperStatus_ACTIVE, p.OperStatus)
258 if p.Type == voltha.Port_ETHERNET_NNI || p.Type == voltha.Port_ETHERNET_UNI {
259 assert.Equal(t, 0, len(p.Peers))
260 } else if p.Type == voltha.Port_PON_OLT {
261 assert.Equal(t, nb.numONUPerOLT, len(p.Peers))
262 assert.Equal(t, uint32(1), p.PortNo)
263 } else if p.Type == voltha.Port_PON_ONU {
264 assert.Equal(t, 1, len(p.Peers))
265 assert.Equal(t, uint32(1), p.PortNo)
266 } else {
267 assert.Error(t, errors.New("invalid-port"))
268 }
269 }
270 wg.Done()
271 }(&wg, device)
khenaidoob64fc8a2019-11-27 15:08:19 -0500272 }
khenaidoo67b22152020-03-02 16:01:25 -0500273 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500274}
275
276func (nb *NBTest) getADevice(rootDevice bool, nbi *APIHandler) (*voltha.Device, error) {
277 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
278 if err != nil {
279 return nil, err
280 }
281 for _, d := range devices.Items {
282 if d.Root == rootDevice {
283 return d, nil
284 }
285 }
286 return nil, status.Errorf(codes.NotFound, "%v device not found", rootDevice)
287}
288
289func (nb *NBTest) testCoreWithoutData(t *testing.T, nbi *APIHandler) {
290 lds, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
291 assert.Nil(t, err)
292 assert.NotNil(t, lds)
293 assert.Equal(t, 0, len(lds.Items))
294 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
295 assert.Nil(t, err)
296 assert.NotNil(t, devices)
297 assert.Equal(t, 0, len(devices.Items))
298 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
khenaidoo442e7c72020-03-10 16:13:48 -0400299 assert.Equal(t, 0, len(adapters.Items))
khenaidoob64fc8a2019-11-27 15:08:19 -0500300 assert.Nil(t, err)
301 assert.NotNil(t, adapters)
khenaidoob64fc8a2019-11-27 15:08:19 -0500302}
303
304func (nb *NBTest) testAdapterRegistration(t *testing.T, nbi *APIHandler) {
305 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
306 assert.Nil(t, err)
307 assert.NotNil(t, adapters)
308 assert.Equal(t, 2, len(adapters.Items))
309 for _, a := range adapters.Items {
310 switch a.Id {
311 case nb.oltAdapterName:
312 assert.Equal(t, "Voltha-olt", a.Vendor)
313 case nb.onuAdapterName:
314 assert.Equal(t, "Voltha-onu", a.Vendor)
315 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000316 logger.Fatal("unregistered-adapter", a.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500317 }
318 }
319 deviceTypes, err := nbi.ListDeviceTypes(getContext(), &empty.Empty{})
320 assert.Nil(t, err)
321 assert.NotNil(t, deviceTypes)
322 assert.Equal(t, 2, len(deviceTypes.Items))
323 for _, dt := range deviceTypes.Items {
324 switch dt.Id {
325 case nb.oltAdapterName:
326 assert.Equal(t, nb.oltAdapterName, dt.Adapter)
327 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
328 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
329 case nb.onuAdapterName:
330 assert.Equal(t, nb.onuAdapterName, dt.Adapter)
331 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
332 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
333 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000334 logger.Fatal("invalid-device-type", dt.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500335 }
336 }
337}
338
339func (nb *NBTest) testCreateDevice(t *testing.T, nbi *APIHandler) {
340 // Create a valid device
341 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
342 assert.Nil(t, err)
343 assert.NotNil(t, oltDevice)
344 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
345 assert.Nil(t, err)
346 assert.NotNil(t, device)
347 assert.Equal(t, oltDevice.String(), device.String())
348
349 // Try to create the same device
350 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
351 assert.NotNil(t, err)
352 assert.Equal(t, "Device is already pre-provisioned", err.Error())
353
354 // Try to create a device with invalid data
355 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName})
356 assert.NotNil(t, err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530357 assert.Equal(t, "no-device-info-present; MAC or HOSTIP&PORT", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500358
359 // Ensure we only have 1 device in the Core
360 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
361 assert.Nil(t, err)
362 assert.NotNil(t, devices)
363 assert.Equal(t, 1, len(devices.Items))
364 assert.Equal(t, oltDevice.String(), devices.Items[0].String())
365
366 //Remove the device
367 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
368 assert.Nil(t, err)
369
370 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
371 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
372 return devices != nil && len(devices.Items) == 0
373 }
khenaidoo442e7c72020-03-10 16:13:48 -0400374 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500375 assert.Nil(t, err)
376}
377
378func (nb *NBTest) testEnableDevice(t *testing.T, nbi *APIHandler) {
379 // Create a device that has no adapter registered
380 oltDeviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegistered", MacAddress: "aa:bb:cc:cc:ee:ff"})
381 assert.Nil(t, err)
382 assert.NotNil(t, oltDeviceNoAdapter)
383
384 // Try to enable the oltDevice and check the error message
385 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
386 assert.NotNil(t, err)
387 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegistered", err.Error())
388
389 //Remove the device
390 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
391 assert.Nil(t, err)
392
393 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
394 var vdFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
395 return devices != nil && len(devices.Items) == 0
396 }
khenaidoo442e7c72020-03-10 16:13:48 -0400397 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vdFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500398 assert.Nil(t, err)
399
khenaidoo67b22152020-03-02 16:01:25 -0500400 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
401 var wg sync.WaitGroup
402 wg.Add(1)
403 go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg)
404
khenaidoob64fc8a2019-11-27 15:08:19 -0500405 // Create the device with valid data
406 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
407 assert.Nil(t, err)
408 assert.NotNil(t, oltDevice)
409
410 // Verify oltDevice exist in the core
411 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
412 assert.Nil(t, err)
413 assert.Equal(t, 1, len(devices.Items))
414 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
415
416 // Enable the oltDevice
417 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
418 assert.Nil(t, err)
419
420 // Wait for the logical device to be in the ready state
421 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
422 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
423 }
424 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
425 assert.Nil(t, err)
426
427 // Verify that the devices have been setup correctly
428 nb.verifyDevices(t, nbi)
429
430 // Get latest oltDevice data
431 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
432 assert.Nil(t, err)
433
434 // Verify that the logical device has been setup correctly
435 nb.verifyLogicalDevices(t, oltDevice, nbi)
khenaidoo67b22152020-03-02 16:01:25 -0500436
437 // Wait until all flows has been sent to the devices successfully
438 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500439}
440
441func (nb *NBTest) testDisableAndReEnableRootDevice(t *testing.T, nbi *APIHandler) {
442 //Get an OLT device
443 oltDevice, err := nb.getADevice(true, nbi)
444 assert.Nil(t, err)
445 assert.NotNil(t, oltDevice)
446
447 // Disable the oltDevice
448 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
449 assert.Nil(t, err)
450
451 // Wait for the old device to be disabled
452 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
453 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
454 }
455 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
456 assert.Nil(t, err)
457
458 // Verify that all onu devices are disabled as well
npujar467fe752020-01-16 20:17:45 +0530459 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500460 assert.Nil(t, err)
461 for _, onu := range onuDevices.Items {
462 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
463 assert.Nil(t, err)
464 }
465
466 // Wait for the logical device to satisfy the expected condition
467 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500468 if ld == nil {
469 return false
470 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500471 for _, lp := range ld.Ports {
472 if (lp.OfpPort.Config&uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
473 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LINK_DOWN) {
474 return false
475 }
476 }
477 return true
478 }
479 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
480 assert.Nil(t, err)
481
482 // Reenable the oltDevice
483 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
484 assert.Nil(t, err)
485
486 // Wait for the old device to be enabled
487 vdFunction = func(device *voltha.Device) bool {
488 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
489 }
490 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
491 assert.Nil(t, err)
492
493 // Verify that all onu devices are enabled as well
npujar467fe752020-01-16 20:17:45 +0530494 onuDevices, err = nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500495 assert.Nil(t, err)
496 for _, onu := range onuDevices.Items {
497 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
498 assert.Nil(t, err)
499 }
500
501 // Wait for the logical device to satisfy the expected condition
502 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500503 if ld == nil {
504 return false
505 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500506 for _, lp := range ld.Ports {
507 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
508 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
509 return false
510 }
511 }
512 return true
513 }
514 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
515 assert.Nil(t, err)
516}
517
khenaidoo93d5a3d2020-01-15 12:37:05 -0500518func (nb *NBTest) testDisableAndDeleteAllDevice(t *testing.T, nbi *APIHandler) {
519 //Get an OLT device
520 oltDevice, err := nb.getADevice(true, nbi)
521 assert.Nil(t, err)
522 assert.NotNil(t, oltDevice)
523
524 // Disable the oltDevice
525 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
526 assert.Nil(t, err)
527
528 // Wait for the olt device to be disabled
529 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
530 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
531 }
532 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
533 assert.Nil(t, err)
534
535 // Verify that all onu devices are disabled as well
npujar467fe752020-01-16 20:17:45 +0530536 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
khenaidoo93d5a3d2020-01-15 12:37:05 -0500537 assert.Nil(t, err)
538 for _, onu := range onuDevices.Items {
539 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
540 assert.Nil(t, err)
541 }
542
543 // Delete the oltDevice
544 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
545 assert.Nil(t, err)
546
547 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
548 return devices != nil && len(devices.Items) == 0
549 }
550 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
551 assert.Nil(t, err)
552
553 // Wait for absence of logical device
554 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
555 return lds != nil && len(lds.Items) == 0
556 }
557
558 err = waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
559 assert.Nil(t, err)
560}
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500561func (nb *NBTest) testEnableAndDeleteAllDevice(t *testing.T, nbi *APIHandler) {
562 //Create the device with valid data
563 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
564 assert.Nil(t, err)
565 assert.NotNil(t, oltDevice)
566
567 //Get an OLT device
568 oltDevice, err = nb.getADevice(true, nbi)
569 assert.Nil(t, err)
570 assert.NotNil(t, oltDevice)
571
572 // Enable the oltDevice
573 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
574 assert.Nil(t, err)
575
576 // Wait for the logical device to be in the ready state
577 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
578 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
579 }
580 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
581 assert.Nil(t, err)
582
583 //Get all child devices
584 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
585 assert.Nil(t, err)
586
587 // Wait for the all onu devices to be enabled
588 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
589 return device.AdminState == voltha.AdminState_ENABLED
590 }
591 for _, onu := range onuDevices.Items {
592 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
593 assert.Nil(t, err)
594 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500595 // Wait for each onu device to get deleted
596 var vdFunc isDeviceConditionSatisfied = func(device *voltha.Device) bool {
597 return device == nil
598 }
599
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500600 // Delete the onuDevice
601 for _, onu := range onuDevices.Items {
602 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: onu.Id})
603 assert.Nil(t, err)
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500604 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunc, nbi)
605 assert.Nil(t, err)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500606 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500607
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500608 // Disable the oltDevice
609 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
610 assert.Nil(t, err)
611
612 // Wait for the olt device to be disabled
613 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
614 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
615 }
616 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vFunction, nbi)
617 assert.Nil(t, err)
618
619 // Delete the oltDevice
620 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
621 assert.Nil(t, err)
622
623 var vFunc isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
624 return devices != nil && len(devices.Items) == 0
625 }
626 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunc)
627 assert.Nil(t, err)
628}
kesavandbc2d1622020-01-21 00:42:01 -0500629func (nb *NBTest) testDisableAndEnablePort(t *testing.T, nbi *APIHandler) {
630 //Get an OLT device
631 var cp *voltha.Port
632 oltDevice, err := nb.getADevice(true, nbi)
633 assert.Nil(t, err)
634 assert.NotNil(t, oltDevice)
635
636 for _, cp = range oltDevice.Ports {
637 if cp.Type == voltha.Port_PON_OLT {
638 break
639 }
640
641 }
642 assert.NotNil(t, cp)
643 cp.DeviceId = oltDevice.Id
644
645 // Disable the NW Port of oltDevice
646 _, err = nbi.DisablePort(getContext(), cp)
647 assert.Nil(t, err)
648 // Wait for the olt device Port to be disabled
649 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
650 for _, port := range device.Ports {
651 if port.PortNo == cp.PortNo {
652 return port.AdminState == voltha.AdminState_DISABLED
653 }
654 }
655 return false
656 }
657 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
658 assert.Nil(t, err)
659 // Wait for the logical device to satisfy the expected condition
660 var vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500661 if ld == nil {
662 return false
663 }
kesavandbc2d1622020-01-21 00:42:01 -0500664 for _, lp := range ld.Ports {
665 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
666 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
667 return false
668 }
669 }
670 return true
671 }
672 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
673 assert.Nil(t, err)
674
675 // Enable the NW Port of oltDevice
676 _, err = nbi.EnablePort(getContext(), cp)
677 assert.Nil(t, err)
678
679 // Wait for the olt device Port to be enabled
680 vdFunction = func(device *voltha.Device) bool {
681 for _, port := range device.Ports {
682 if port.PortNo == cp.PortNo {
683 return port.AdminState == voltha.AdminState_ENABLED
684 }
685 }
686 return false
687 }
688 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
689 assert.Nil(t, err)
690 // Wait for the logical device to satisfy the expected condition
691 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500692 if ld == nil {
693 return false
694 }
kesavandbc2d1622020-01-21 00:42:01 -0500695 for _, lp := range ld.Ports {
696 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
697 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
698 return false
699 }
700 }
701 return true
702 }
703 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
704 assert.Nil(t, err)
705
706 // Disable a non-PON port
707 for _, cp = range oltDevice.Ports {
708 if cp.Type != voltha.Port_PON_OLT {
709 break
710 }
711
712 }
713 assert.NotNil(t, cp)
714 cp.DeviceId = oltDevice.Id
715
716 // Disable the NW Port of oltDevice
717 _, err = nbi.DisablePort(getContext(), cp)
718 assert.NotNil(t, err)
719
720}
khenaidoo93d5a3d2020-01-15 12:37:05 -0500721
Girish Gowdra408cd962020-03-11 14:31:31 -0700722func (nb *NBTest) testDeviceRebootWhenOltIsEnabled(t *testing.T, nbi *APIHandler) {
723 //Get an OLT device
724 oltDevice, err := nb.getADevice(true, nbi)
725 assert.Nil(t, err)
726 assert.NotNil(t, oltDevice)
727 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
728 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
729
730 // Verify that we have one or more ONUs to start with
731 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
732 assert.Nil(t, err)
733 assert.NotNil(t, onuDevices)
734 assert.Greater(t, len(onuDevices.Items), 0)
735
736 // Reboot the OLT and very that Connection Status goes to UNREACHABLE and operation status to UNKNOWN
737 _, err = nbi.RebootDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
738 assert.Nil(t, err)
739
740 var vlFunction0 = func(d *voltha.Device) bool {
741 return d.ConnectStatus == voltha.ConnectStatus_UNREACHABLE && d.OperStatus == voltha.OperStatus_UNKNOWN
742 }
743
744 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction0, nbi)
745 assert.Nil(t, err)
746
747 // Wait for the logical device to satisfy the expected condition
748 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
749 return ld == nil
750 }
751
752 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
753 assert.Nil(t, err)
754
755 // Wait for the device to satisfy the expected condition (device does not have flows)
756 var vlFunction2 = func(d *voltha.Device) bool {
757 var deviceFlows *ofp.Flows
758 var err error
759 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
760 return false
761 }
762 return len(deviceFlows.Items) == 0
763 }
764
765 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
766 assert.Nil(t, err)
767
768 // Wait for the device to satisfy the expected condition (there are no child devices)
769 var vlFunction3 = func(d *voltha.Device) bool {
770 var devices *voltha.Devices
771 var err error
772 if devices, err = nbi.ListDevices(getContext(), nil); err != nil {
773 return false
774 }
775 for _, device := range devices.Items {
776 if device.ParentId == d.Id {
777 // We have a child device still left
778 return false
779 }
780 }
781 return true
782 }
783
784 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction3, nbi)
785 assert.Nil(t, err)
786
787 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
788 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
789 deviceAgent := nbi.deviceMgr.getDeviceAgent(getContext(), oltDevice.Id)
790 err = deviceAgent.updateDeviceStatus(getContext(), voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
791 assert.Nil(t, err)
792
793 // Verify the device connection and operation states
794 oltDevice, err = nb.getADevice(true, nbi)
795 assert.Nil(t, err)
796 assert.NotNil(t, oltDevice)
797 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
798 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
799
800 // Wait for the logical device to satisfy the expected condition
801 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
802 return ld != nil
803 }
804 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
805 assert.Nil(t, err)
806
807 // Verify that logical device is created again
808 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
809 assert.Nil(t, err)
810 assert.NotNil(t, logicalDevices)
811 assert.Equal(t, 1, len(logicalDevices.Items))
812
813 // Verify that we have no ONUs left
814 onuDevices, err = nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
815 assert.Nil(t, err)
816 assert.NotNil(t, onuDevices)
817 assert.Equal(t, 0, len(onuDevices.Items))
818}
819
Scott Baker432f9be2020-03-26 11:56:30 -0700820func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi *APIHandler) {
821 // -----------------------------------------------------------------------
822 // SubTest 1: Omci test action should fail due to nonexistent device id
823
824 request := &voltha.OmciTestRequest{Id: "123", Uuid: "456"}
825 _, err := nbi.StartOmciTestAction(getContext(), request)
826 assert.NotNil(t, err)
827 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
828
829 // -----------------------------------------------------------------------
830 // SubTest 2: Error should be returned for device with no adapter registered
831
832 // Create a device that has no adapter registered
833 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: "aa:bb:cc:cc:ee:01"})
834 assert.Nil(t, err)
835 assert.NotNil(t, deviceNoAdapter)
836
837 // Omci test action should fail due to nonexistent adapter
838 request = &voltha.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
839 _, err = nbi.StartOmciTestAction(getContext(), request)
840 assert.NotNil(t, err)
841 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegisteredOmciTest", err.Error())
842
843 //Remove the device
844 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
845 assert.Nil(t, err)
846
847 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
848 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
849 return devices != nil && len(devices.Items) == 0
850 }
851 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
852 assert.Nil(t, err)
853
854 // -----------------------------------------------------------------------
855 // SubTest 3: Omci test action should succeed on valid ONU
856
857 // Create the device with valid data
858 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
859 assert.Nil(t, err)
860 assert.NotNil(t, oltDevice)
861
862 // Verify oltDevice exist in the core
863 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
864 assert.Nil(t, err)
865 assert.Equal(t, 1, len(devices.Items))
866 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
867
868 // Enable the oltDevice
869 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
870 assert.Nil(t, err)
871
872 // Wait for the logical device to be in the ready state
873 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
874 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
875 }
876 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
877 assert.Nil(t, err)
878
879 // Wait for the olt device to be enabled
880 vdFunction := func(device *voltha.Device) bool {
881 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
882 }
883 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
884 assert.Nil(t, err)
885
886 onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
887 assert.Nil(t, err)
888 assert.Greater(t, len(onuDevices.Items), 0)
889
890 onuDevice := onuDevices.Items[0]
891
892 // Omci test action should succeed
893 request = &voltha.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
894 resp, err := nbi.StartOmciTestAction(getContext(), request)
895 assert.Nil(t, err)
896 assert.Equal(t, resp.Result, voltha.TestResponse_SUCCESS)
897
898 //Remove the device
899 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
900 assert.Nil(t, err)
901 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
902 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
903 assert.Nil(t, err)
904}
905
khenaidoo67b22152020-03-02 16:01:25 -0500906func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
907 matchFields := make([]*ofp.OfpOxmField, 0)
908 for _, val := range fa.MatchFields {
909 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
910 }
911 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
912}
913
914func createMetadata(cTag int, techProfile int, port int) uint64 {
915 md := 0
916 md = (md | (cTag & 0xFFFF)) << 16
917 md = (md | (techProfile & 0xFFFF)) << 32
918 return uint64(md | (port & 0xFFFFFFFF))
919}
920
921func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi *APIHandler, numNNIPorts int, numUNIPorts int) {
922 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
923 // Wait for logical device to have all the flows
924 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
925 return lds != nil && len(lds.Items) == 1 && len(lds.Items[0].Flows.Items) == expectedNumFlows
926 }
927 // No timeout implies a success
928 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
929 assert.Nil(t, err)
930}
931
932func (nb *NBTest) sendTrapFlows(t *testing.T, nbi *APIHandler, logicalDevice *voltha.LogicalDevice, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
933 // Send flows for the parent device
934 var nniPorts []*voltha.LogicalPort
935 var uniPorts []*voltha.LogicalPort
936 for _, p := range logicalDevice.Ports {
937 if p.RootPort {
938 nniPorts = append(nniPorts, p)
939 } else {
940 uniPorts = append(uniPorts, p)
941 }
942 }
943 assert.Equal(t, 1, len(nniPorts))
944 //assert.Greater(t, len(uniPorts), 1 )
945 nniPort := nniPorts[0].OfpPort.PortNo
946 maxInt32 := uint64(0xFFFFFFFF)
947 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
948 var fa *flows.FlowArgs
949 fa = &flows.FlowArgs{
950 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
951 MatchFields: []*ofp.OfpOxmOfbField{
952 flows.InPort(nniPort),
953 flows.EthType(35020),
954 },
955 Actions: []*ofp.OfpAction{
956 flows.Output(controllerPortMask),
957 },
958 }
959 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
960 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
961 assert.Nil(t, err)
962
963 fa = &flows.FlowArgs{
964 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
965 MatchFields: []*ofp.OfpOxmOfbField{
966 flows.InPort(nniPort),
967 flows.EthType(2048),
968 flows.IpProto(17),
969 flows.UdpSrc(67),
970 flows.UdpDst(68),
971 },
972 Actions: []*ofp.OfpAction{
973 flows.Output(controllerPortMask),
974 },
975 }
976 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
977 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
978 assert.Nil(t, err)
979
980 fa = &flows.FlowArgs{
981 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
982 MatchFields: []*ofp.OfpOxmOfbField{
983 flows.InPort(nniPort),
984 flows.EthType(34525),
985 flows.IpProto(17),
986 flows.UdpSrc(546),
987 flows.UdpDst(547),
988 },
989 Actions: []*ofp.OfpAction{
990 flows.Output(controllerPortMask),
991 },
992 }
993 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
994 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
995 assert.Nil(t, err)
996
997 return len(nniPorts), len(uniPorts)
998}
999
1000func (nb *NBTest) sendEAPFlows(t *testing.T, nbi *APIHandler, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
1001 maxInt32 := uint64(0xFFFFFFFF)
1002 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1003 fa := &flows.FlowArgs{
1004 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},
1005 MatchFields: []*ofp.OfpOxmOfbField{
1006 flows.InPort(port.PortNo),
1007 flows.EthType(34958),
1008 flows.VlanVid(8187),
1009 },
1010 Actions: []*ofp.OfpAction{
1011 flows.Output(controllerPortMask),
1012 },
1013 }
1014 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1015 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP)
1016 assert.Nil(t, err)
1017}
1018
1019func (nb *NBTest) monitorLogicalDevice(t *testing.T, nbi *APIHandler, numNNIPorts int, numUNIPorts int, wg *sync.WaitGroup) {
1020 defer wg.Done()
1021 if nb.core.logicalDeviceMgr.grpcNbiHdlr != nbi {
1022 nb.core.logicalDeviceMgr.setGrpcNbiHandler(nbi)
1023 }
1024
1025 // Clear any existing flows on the adapters
1026 nb.oltAdapter.ClearFlows()
1027 nb.onuAdapter.ClearFlows()
1028
1029 // Wait until a logical device is ready
1030 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
1031 if lds == nil || len(lds.Items) != 1 {
1032 return false
1033 }
1034 // Ensure there are both NNI ports and at least one UNI port on the logical device
1035 ld := lds.Items[0]
1036 nniPort := false
1037 uniPort := false
1038 for _, p := range ld.Ports {
1039 nniPort = nniPort || p.RootPort == true
1040 uniPort = uniPort || p.RootPort == false
1041 if nniPort && uniPort {
1042 return true
1043 }
1044 }
1045 return false
1046 }
1047 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
1048 assert.Nil(t, err)
1049
1050 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
1051 assert.Nil(t, err)
1052 assert.NotNil(t, logicalDevices)
1053 assert.Equal(t, 1, len(logicalDevices.Items))
1054
1055 logicalDevice := logicalDevices.Items[0]
1056 meterID := rand.Uint32()
1057
1058 // Add a meter to the logical device
1059 meterMod := &ofp.OfpMeterMod{
1060 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1061 Flags: rand.Uint32(),
1062 MeterId: meterID,
1063 Bands: []*ofp.OfpMeterBandHeader{
1064 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1065 Rate: rand.Uint32(),
1066 BurstSize: rand.Uint32(),
1067 Data: nil,
1068 },
1069 },
1070 }
1071 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{Id: logicalDevice.Id, MeterMod: meterMod})
1072 assert.Nil(t, err)
1073
1074 // Send initial set of Trap flows
1075 startingVlan := 4091
1076 nb.sendTrapFlows(t, nbi, logicalDevice, uint64(meterID), startingVlan)
1077
1078 // Listen for port events
khenaidoo442e7c72020-03-10 16:13:48 -04001079 start := time.Now()
Girish Gowdra408cd962020-03-11 14:31:31 -07001080 processedNniLogicalPorts := 0
1081 processedUniLogicalPorts := 0
1082
khenaidoo67b22152020-03-02 16:01:25 -05001083 for event := range nbi.changeEventQueue {
1084 startingVlan++
1085 if portStatus, ok := (event.Event).(*ofp.ChangeEvent_PortStatus); ok {
1086 ps := portStatus.PortStatus
1087 if ps.Reason == ofp.OfpPortReason_OFPPR_ADD {
khenaidoo67b22152020-03-02 16:01:25 -05001088 if ps.Desc.PortNo >= uint32(nb.startingUNIPortNo) {
Girish Gowdra408cd962020-03-11 14:31:31 -07001089 processedUniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001090 nb.sendEAPFlows(t, nbi, logicalDevice.Id, ps.Desc, startingVlan, uint64(meterID))
Girish Gowdra408cd962020-03-11 14:31:31 -07001091 } else {
1092 processedNniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001093 }
1094 }
1095 }
Girish Gowdra408cd962020-03-11 14:31:31 -07001096
1097 if processedNniLogicalPorts >= numNNIPorts && processedUniLogicalPorts >= numUNIPorts {
khenaidoo442e7c72020-03-10 16:13:48 -04001098 fmt.Println("Total time to send all flows:", time.Since(start))
khenaidoo67b22152020-03-02 16:01:25 -05001099 break
1100 }
1101 }
1102 //Verify the flow count on the logical device
1103 nb.verifyLogicalDeviceFlowCount(t, nbi, numNNIPorts, numUNIPorts)
1104
1105 // Wait until all flows have been sent to the OLT adapters
1106 var oltVFunc isConditionSatisfied = func() bool {
1107 return nb.oltAdapter.GetFlowCount() >= (numNNIPorts*3)+numNNIPorts*numUNIPorts
1108 }
1109 err = waitUntilCondition(nb.maxTimeout, nbi, oltVFunc)
1110 assert.Nil(t, err)
1111
1112 // Wait until all flows have been sent to the ONU adapters
1113 var onuVFunc isConditionSatisfied = func() bool {
1114 return nb.onuAdapter.GetFlowCount() == numUNIPorts
1115 }
1116 err = waitUntilCondition(nb.maxTimeout, nbi, onuVFunc)
1117 assert.Nil(t, err)
1118}
1119
Matteo Scandolod525ae32020-04-02 17:27:29 -07001120func TestSuiteNbiApiHandler(t *testing.T) {
khenaidoo67b22152020-03-02 16:01:25 -05001121 f, err := os.Create("profile.cpu")
1122 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001123 logger.Fatalf("could not create CPU profile: %v\n ", err)
khenaidoo67b22152020-03-02 16:01:25 -05001124 }
1125 defer f.Close()
1126 runtime.SetBlockProfileRate(1)
1127 runtime.SetMutexProfileFraction(-1)
1128 if err := pprof.StartCPUProfile(f); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001129 logger.Fatalf("could not start CPU profile: %v\n", err)
khenaidoo67b22152020-03-02 16:01:25 -05001130 }
1131 defer pprof.StopCPUProfile()
1132
khenaidoo442e7c72020-03-10 16:13:48 -04001133 //log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
1134
khenaidoob64fc8a2019-11-27 15:08:19 -05001135 nb := newNBTest()
1136 assert.NotNil(t, nb)
1137
1138 defer nb.stopAll()
1139
1140 // Start the Core
1141 nb.startCore(false)
1142
1143 // Set the grpc API interface - no grpc server is running in unit test
1144 nbi := NewAPIHandler(nb.core)
1145
1146 // 1. Basic test with no data in Core
1147 nb.testCoreWithoutData(t, nbi)
1148
1149 // Create/register the adapters
Thomas Lee Se5a44012019-11-07 20:32:24 +05301150 nb.createAndregisterAdapters(t)
khenaidoob64fc8a2019-11-27 15:08:19 -05001151
1152 // 2. Test adapter registration
1153 nb.testAdapterRegistration(t, nbi)
1154
Scott Baker8cb47bb2020-04-01 09:57:20 -07001155 numberOfDeviceTestRuns := 2
khenaidoo93d5a3d2020-01-15 12:37:05 -05001156 for i := 1; i <= numberOfDeviceTestRuns; i++ {
khenaidoo67b22152020-03-02 16:01:25 -05001157 //3. Test create device
khenaidoo93d5a3d2020-01-15 12:37:05 -05001158 nb.testCreateDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001159
khenaidoo93d5a3d2020-01-15 12:37:05 -05001160 // 4. Test Enable a device
1161 nb.testEnableDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001162
khenaidoo93d5a3d2020-01-15 12:37:05 -05001163 // 5. Test disable and ReEnable a root device
1164 nb.testDisableAndReEnableRootDevice(t, nbi)
khenaidoo67b22152020-03-02 16:01:25 -05001165
kesavandbc2d1622020-01-21 00:42:01 -05001166 // 6. Test disable and Enable pon port of OLT device
1167 nb.testDisableAndEnablePort(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001168
Girish Gowdra408cd962020-03-11 14:31:31 -07001169 // 7.Test Device unreachable when OLT is enabled
1170 nb.testDeviceRebootWhenOltIsEnabled(t, nbi)
1171
1172 // 8. Test disable and delete all devices
khenaidoo93d5a3d2020-01-15 12:37:05 -05001173 nb.testDisableAndDeleteAllDevice(t, nbi)
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001174
Girish Gowdra408cd962020-03-11 14:31:31 -07001175 // 9. Test enable and delete all devices
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001176 nb.testEnableAndDeleteAllDevice(t, nbi)
Scott Baker432f9be2020-03-26 11:56:30 -07001177
1178 // 10. Test omci test
1179 nb.testStartOmciTestAction(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001180 }
khenaidoob64fc8a2019-11-27 15:08:19 -05001181
1182 //x. TODO - More tests to come
1183}