blob: 0579f945f7185b0b78abc4835825996c44f6818f [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 */
Kent Hagerman2b216042020-04-03 18:28:56 -040016package api
khenaidoob64fc8a2019-11-27 15:08:19 -050017
18import (
19 "context"
20 "errors"
21 "fmt"
khenaidoo67b22152020-03-02 16:01:25 -050022 "math/rand"
23 "os"
24 "runtime"
25 "runtime/pprof"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080026 "strings"
khenaidoo67b22152020-03-02 16:01:25 -050027 "sync"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080028 "testing"
29 "time"
30
khenaidoob64fc8a2019-11-27 15:08:19 -050031 "github.com/golang/protobuf/ptypes/empty"
Kent Hagerman2b216042020-04-03 18:28:56 -040032 "github.com/opencord/voltha-go/db/model"
khenaidoob64fc8a2019-11-27 15:08:19 -050033 "github.com/opencord/voltha-go/rw_core/config"
Kent Hagerman2b216042020-04-03 18:28:56 -040034 "github.com/opencord/voltha-go/rw_core/core/adapter"
35 "github.com/opencord/voltha-go/rw_core/core/device"
khenaidoob64fc8a2019-11-27 15:08:19 -050036 cm "github.com/opencord/voltha-go/rw_core/mocks"
Kent Hagerman2b216042020-04-03 18:28:56 -040037 "github.com/opencord/voltha-lib-go/v3/pkg/db"
38 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080039 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
40 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Matteo Scandolod525ae32020-04-02 17:27:29 -070041 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
42 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080043 "github.com/opencord/voltha-lib-go/v3/pkg/version"
44 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
45 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob64fc8a2019-11-27 15:08:19 -050046 "github.com/phayes/freeport"
47 "github.com/stretchr/testify/assert"
48 "google.golang.org/grpc/codes"
49 "google.golang.org/grpc/status"
khenaidoob64fc8a2019-11-27 15:08:19 -050050)
51
Kent Hagerman2b216042020-04-03 18:28:56 -040052const (
53 coreName = "rw_core"
54)
55
khenaidoob64fc8a2019-11-27 15:08:19 -050056type NBTest struct {
Matteo Scandolod525ae32020-04-02 17:27:29 -070057 etcdServer *mock_etcd.EtcdServer
Kent Hagerman2b216042020-04-03 18:28:56 -040058 deviceMgr *device.Manager
59 logicalDeviceMgr *device.LogicalManager
60 adapterMgr *adapter.Manager
61 kmp kafka.InterContainerProxy
khenaidoo67b22152020-03-02 16:01:25 -050062 kClient kafka.Client
63 kvClientPort int
64 numONUPerOLT int
65 startingUNIPortNo int
66 oltAdapter *cm.OLTAdapter
67 onuAdapter *cm.ONUAdapter
68 oltAdapterName string
69 onuAdapterName string
70 coreInstanceID string
71 defaultTimeout time.Duration
72 maxTimeout time.Duration
khenaidoob64fc8a2019-11-27 15:08:19 -050073}
74
75func newNBTest() *NBTest {
76 test := &NBTest{}
77 // Start the embedded etcd server
78 var err error
79 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.nb.test", "voltha.rwcore.nb.etcd", "error")
80 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000081 logger.Fatal(err)
khenaidoob64fc8a2019-11-27 15:08:19 -050082 }
83 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -070084 test.kClient = mock_kafka.NewKafkaClient()
khenaidoob64fc8a2019-11-27 15:08:19 -050085 test.oltAdapterName = "olt_adapter_mock"
86 test.onuAdapterName = "onu_adapter_mock"
87 test.coreInstanceID = "rw-nbi-test"
khenaidoo32836732020-03-05 16:10:44 -050088 test.defaultTimeout = 10 * time.Second
89 test.maxTimeout = 20 * time.Second
khenaidoob64fc8a2019-11-27 15:08:19 -050090 return test
91}
92
93func (nb *NBTest) startCore(inCompeteMode bool) {
Thomas Lee Se5a44012019-11-07 20:32:24 +053094 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
95 defer cancel()
khenaidoob64fc8a2019-11-27 15:08:19 -050096 cfg := config.NewRWCoreFlags()
97 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -040098 cfg.DefaultRequestTimeout = nb.defaultTimeout
99 cfg.DefaultCoreTimeout = nb.defaultTimeout
khenaidoob64fc8a2019-11-27 15:08:19 -0500100 cfg.KVStorePort = nb.kvClientPort
101 cfg.InCompetingMode = inCompeteMode
102 grpcPort, err := freeport.GetFreePort()
103 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000104 logger.Fatal("Cannot get a freeport for grpc")
khenaidoob64fc8a2019-11-27 15:08:19 -0500105 }
106 cfg.GrpcPort = grpcPort
107 cfg.GrpcHost = "127.0.0.1"
108 setCoreCompeteMode(inCompeteMode)
109 client := setupKVClient(cfg, nb.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400110 backend := &db.Backend{
111 Client: client,
112 StoreType: cfg.KVStoreType,
113 Host: cfg.KVStoreHost,
114 Port: cfg.KVStorePort,
115 Timeout: cfg.KVStoreTimeout,
116 LivenessChannelInterval: cfg.LiveProbeInterval / 2,
117 PathPrefix: cfg.KVStoreDataPrefix}
118 nb.kmp = kafka.NewInterContainerProxy(
119 kafka.InterContainerHost(cfg.KafkaAdapterHost),
120 kafka.InterContainerPort(cfg.KafkaAdapterPort),
121 kafka.MsgClient(nb.kClient),
122 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}),
123 kafka.DeviceDiscoveryTopic(&kafka.Topic{Name: cfg.AffinityRouterTopic}))
124
125 endpointMgr := kafka.NewEndpointManager(backend)
126 proxy := model.NewProxy(backend, "/")
127 nb.adapterMgr = adapter.NewAdapterManager(proxy, nb.coreInstanceID, nb.kClient)
128 nb.deviceMgr, nb.logicalDeviceMgr = device.NewDeviceManagers(proxy, nb.adapterMgr, nb.kmp, endpointMgr, cfg.CorePairTopic, nb.coreInstanceID, cfg.DefaultCoreTimeout)
129 if err = nb.adapterMgr.Start(ctx); err != nil {
130 logger.Fatalf("Cannot start adapterMgr: %s", err)
131 }
132 nb.deviceMgr.Start(ctx)
133 nb.logicalDeviceMgr.Start(ctx)
134
135 if err = nb.kmp.Start(); err != nil {
136 logger.Fatalf("Cannot start InterContainerProxy: %s", err)
137 }
138 requestProxy := NewAdapterRequestHandlerProxy(nb.coreInstanceID, nb.deviceMgr, nb.adapterMgr, proxy, proxy, cfg.LongRunningRequestTimeout, cfg.DefaultRequestTimeout)
139 if err := nb.kmp.SubscribeWithRequestHandlerInterface(kafka.Topic{Name: cfg.CoreTopic}, requestProxy); err != nil {
140 logger.Fatalf("Cannot add request handler: %s", err)
141 }
142 if err := nb.kmp.SubscribeWithDefaultRequestHandler(kafka.Topic{Name: cfg.CorePairTopic}, kafka.OffsetNewest); err != nil {
143 logger.Fatalf("Cannot add default request handler: %s", err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530144 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500145}
146
Thomas Lee Se5a44012019-11-07 20:32:24 +0530147func (nb *NBTest) createAndregisterAdapters(t *testing.T) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500148 // Setup the mock OLT adapter
149 oltAdapter, err := createMockAdapter(OltAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.oltAdapterName)
150 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000151 logger.Fatalw("setting-mock-olt-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500152 }
khenaidoo67b22152020-03-02 16:01:25 -0500153 nb.oltAdapter = (oltAdapter).(*cm.OLTAdapter)
154 nb.numONUPerOLT = nb.oltAdapter.GetNumONUPerOLT()
155 nb.startingUNIPortNo = nb.oltAdapter.GetStartingUNIPortNo()
156
khenaidoob64fc8a2019-11-27 15:08:19 -0500157 // Register the adapter
158 registrationData := &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700159 Id: nb.oltAdapterName,
160 Vendor: "Voltha-olt",
161 Version: version.VersionInfo.Version,
162 Type: nb.oltAdapterName,
163 CurrentReplica: 1,
164 TotalReplicas: 1,
165 Endpoint: nb.oltAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500166 }
167 types := []*voltha.DeviceType{{Id: nb.oltAdapterName, Adapter: nb.oltAdapterName, AcceptsAddRemoveFlowUpdates: true}}
168 deviceTypes := &voltha.DeviceTypes{Items: types}
Kent Hagerman2b216042020-04-03 18:28:56 -0400169 if _, err := nb.adapterMgr.RegisterAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000170 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530171 assert.NotNil(t, err)
172 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500173
174 // Setup the mock ONU adapter
khenaidoo67b22152020-03-02 16:01:25 -0500175 onuAdapter, err := createMockAdapter(OnuAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.onuAdapterName)
176 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000177 logger.Fatalw("setting-mock-onu-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500178 }
khenaidoo67b22152020-03-02 16:01:25 -0500179 nb.onuAdapter = (onuAdapter).(*cm.ONUAdapter)
180
khenaidoob64fc8a2019-11-27 15:08:19 -0500181 // Register the adapter
182 registrationData = &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700183 Id: nb.onuAdapterName,
184 Vendor: "Voltha-onu",
185 Version: version.VersionInfo.Version,
186 Type: nb.onuAdapterName,
187 CurrentReplica: 1,
188 TotalReplicas: 1,
189 Endpoint: nb.onuAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500190 }
191 types = []*voltha.DeviceType{{Id: nb.onuAdapterName, Adapter: nb.onuAdapterName, AcceptsAddRemoveFlowUpdates: true}}
192 deviceTypes = &voltha.DeviceTypes{Items: types}
Kent Hagerman2b216042020-04-03 18:28:56 -0400193 if _, err := nb.adapterMgr.RegisterAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000194 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530195 assert.NotNil(t, err)
196 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500197}
198
199func (nb *NBTest) stopAll() {
200 if nb.kClient != nil {
201 nb.kClient.Stop()
202 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400203 if nb.logicalDeviceMgr != nil {
204 nb.logicalDeviceMgr.Stop(context.Background())
205 }
206 if nb.deviceMgr != nil {
207 nb.deviceMgr.Stop(context.Background())
208 }
209 if nb.kmp != nil {
210 nb.kmp.Stop()
khenaidoob64fc8a2019-11-27 15:08:19 -0500211 }
212 if nb.etcdServer != nil {
213 stopEmbeddedEtcdServer(nb.etcdServer)
214 }
215}
216
Kent Hagerman2b216042020-04-03 18:28:56 -0400217func (nb *NBTest) verifyLogicalDevices(t *testing.T, oltDevice *voltha.Device, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500218 // Get the latest set of logical devices
219 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
220 assert.Nil(t, err)
221 assert.NotNil(t, logicalDevices)
222 assert.Equal(t, 1, len(logicalDevices.Items))
223
224 ld := logicalDevices.Items[0]
225 assert.NotEqual(t, "", ld.Id)
226 assert.NotEqual(t, uint64(0), ld.DatapathId)
227 assert.Equal(t, "olt_adapter_mock", ld.Desc.HwDesc)
228 assert.Equal(t, "olt_adapter_mock", ld.Desc.SwDesc)
229 assert.NotEqual(t, "", ld.RootDeviceId)
230 assert.NotEqual(t, "", ld.Desc.SerialNum)
231 assert.Equal(t, uint32(256), ld.SwitchFeatures.NBuffers)
232 assert.Equal(t, uint32(2), ld.SwitchFeatures.NTables)
233 assert.Equal(t, uint32(15), ld.SwitchFeatures.Capabilities)
234 assert.Equal(t, 1+nb.numONUPerOLT, len(ld.Ports))
235 assert.Equal(t, oltDevice.ParentId, ld.Id)
236 //Expected port no
237 expectedPortNo := make(map[uint32]bool)
238 expectedPortNo[uint32(2)] = false
239 for i := 0; i < nb.numONUPerOLT; i++ {
240 expectedPortNo[uint32(i+100)] = false
241 }
242 for _, p := range ld.Ports {
243 assert.Equal(t, p.OfpPort.PortNo, p.DevicePortNo)
244 assert.Equal(t, uint32(4), p.OfpPort.State)
245 expectedPortNo[p.OfpPort.PortNo] = true
246 if strings.HasPrefix(p.Id, "nni") {
247 assert.Equal(t, true, p.RootPort)
248 //assert.Equal(t, uint32(2), p.OfpPort.PortNo)
249 assert.Equal(t, p.Id, fmt.Sprintf("nni-%d", p.DevicePortNo))
250 } else {
251 assert.Equal(t, p.Id, fmt.Sprintf("uni-%d", p.DevicePortNo))
252 assert.Equal(t, false, p.RootPort)
253 }
254 }
255}
256
Kent Hagerman2b216042020-04-03 18:28:56 -0400257func (nb *NBTest) verifyDevices(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500258 // Get the latest set of devices
259 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
260 assert.Nil(t, err)
261 assert.NotNil(t, devices)
262
khenaidoo67b22152020-03-02 16:01:25 -0500263 // A device is ready to be examined when its ADMIN state is ENABLED and OPERATIONAL state is ACTIVE
khenaidoob64fc8a2019-11-27 15:08:19 -0500264 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
265 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
266 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500267
khenaidoo67b22152020-03-02 16:01:25 -0500268 var wg sync.WaitGroup
269 for _, device := range devices.Items {
270 wg.Add(1)
271 go func(wg *sync.WaitGroup, device *voltha.Device) {
272 // Wait until the device is in the right state
273 err := waitUntilDeviceReadiness(device.Id, nb.maxTimeout, vFunction, nbi)
274 assert.Nil(t, err)
275
276 // Now, verify the details of the device. First get the latest update
277 d, err := nbi.GetDevice(getContext(), &voltha.ID{Id: device.Id})
278 assert.Nil(t, err)
279 assert.Equal(t, voltha.AdminState_ENABLED, d.AdminState)
280 assert.Equal(t, voltha.ConnectStatus_REACHABLE, d.ConnectStatus)
281 assert.Equal(t, voltha.OperStatus_ACTIVE, d.OperStatus)
282 assert.Equal(t, d.Type, d.Adapter)
283 assert.NotEqual(t, "", d.MacAddress)
284 assert.NotEqual(t, "", d.SerialNumber)
285
286 if d.Type == "olt_adapter_mock" {
287 assert.Equal(t, true, d.Root)
288 assert.NotEqual(t, "", d.Id)
289 assert.NotEqual(t, "", d.ParentId)
290 assert.Nil(t, d.ProxyAddress)
291 } else if d.Type == "onu_adapter_mock" {
292 assert.Equal(t, false, d.Root)
293 assert.NotEqual(t, uint32(0), d.Vlan)
294 assert.NotEqual(t, "", d.Id)
295 assert.NotEqual(t, "", d.ParentId)
296 assert.NotEqual(t, "", d.ProxyAddress.DeviceId)
297 assert.Equal(t, "olt_adapter_mock", d.ProxyAddress.DeviceType)
khenaidoob64fc8a2019-11-27 15:08:19 -0500298 } else {
khenaidoo67b22152020-03-02 16:01:25 -0500299 assert.Error(t, errors.New("invalid-device-type"))
khenaidoob64fc8a2019-11-27 15:08:19 -0500300 }
khenaidoo67b22152020-03-02 16:01:25 -0500301 assert.Equal(t, 2, len(d.Ports))
302 for _, p := range d.Ports {
303 assert.Equal(t, voltha.AdminState_ENABLED, p.AdminState)
304 assert.Equal(t, voltha.OperStatus_ACTIVE, p.OperStatus)
305 if p.Type == voltha.Port_ETHERNET_NNI || p.Type == voltha.Port_ETHERNET_UNI {
306 assert.Equal(t, 0, len(p.Peers))
307 } else if p.Type == voltha.Port_PON_OLT {
308 assert.Equal(t, nb.numONUPerOLT, len(p.Peers))
309 assert.Equal(t, uint32(1), p.PortNo)
310 } else if p.Type == voltha.Port_PON_ONU {
311 assert.Equal(t, 1, len(p.Peers))
312 assert.Equal(t, uint32(1), p.PortNo)
313 } else {
314 assert.Error(t, errors.New("invalid-port"))
315 }
316 }
317 wg.Done()
318 }(&wg, device)
khenaidoob64fc8a2019-11-27 15:08:19 -0500319 }
khenaidoo67b22152020-03-02 16:01:25 -0500320 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500321}
322
Kent Hagerman2b216042020-04-03 18:28:56 -0400323func (nb *NBTest) getADevice(rootDevice bool, nbi *NBIHandler) (*voltha.Device, error) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500324 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
325 if err != nil {
326 return nil, err
327 }
328 for _, d := range devices.Items {
329 if d.Root == rootDevice {
330 return d, nil
331 }
332 }
333 return nil, status.Errorf(codes.NotFound, "%v device not found", rootDevice)
334}
335
Kent Hagerman2b216042020-04-03 18:28:56 -0400336func (nb *NBTest) testCoreWithoutData(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500337 lds, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
338 assert.Nil(t, err)
339 assert.NotNil(t, lds)
340 assert.Equal(t, 0, len(lds.Items))
341 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
342 assert.Nil(t, err)
343 assert.NotNil(t, devices)
344 assert.Equal(t, 0, len(devices.Items))
345 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
khenaidoo442e7c72020-03-10 16:13:48 -0400346 assert.Equal(t, 0, len(adapters.Items))
khenaidoob64fc8a2019-11-27 15:08:19 -0500347 assert.Nil(t, err)
348 assert.NotNil(t, adapters)
khenaidoob64fc8a2019-11-27 15:08:19 -0500349}
350
Kent Hagerman2b216042020-04-03 18:28:56 -0400351func (nb *NBTest) testAdapterRegistration(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500352 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
353 assert.Nil(t, err)
354 assert.NotNil(t, adapters)
355 assert.Equal(t, 2, len(adapters.Items))
356 for _, a := range adapters.Items {
357 switch a.Id {
358 case nb.oltAdapterName:
359 assert.Equal(t, "Voltha-olt", a.Vendor)
360 case nb.onuAdapterName:
361 assert.Equal(t, "Voltha-onu", a.Vendor)
362 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000363 logger.Fatal("unregistered-adapter", a.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500364 }
365 }
366 deviceTypes, err := nbi.ListDeviceTypes(getContext(), &empty.Empty{})
367 assert.Nil(t, err)
368 assert.NotNil(t, deviceTypes)
369 assert.Equal(t, 2, len(deviceTypes.Items))
370 for _, dt := range deviceTypes.Items {
371 switch dt.Id {
372 case nb.oltAdapterName:
373 assert.Equal(t, nb.oltAdapterName, dt.Adapter)
374 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
375 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
376 case nb.onuAdapterName:
377 assert.Equal(t, nb.onuAdapterName, dt.Adapter)
378 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
379 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
380 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000381 logger.Fatal("invalid-device-type", dt.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500382 }
383 }
384}
385
Kent Hagerman2b216042020-04-03 18:28:56 -0400386func (nb *NBTest) testCreateDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500387 // Create a valid device
388 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
389 assert.Nil(t, err)
390 assert.NotNil(t, oltDevice)
391 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
392 assert.Nil(t, err)
393 assert.NotNil(t, device)
394 assert.Equal(t, oltDevice.String(), device.String())
395
396 // Try to create the same device
397 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
398 assert.NotNil(t, err)
399 assert.Equal(t, "Device is already pre-provisioned", err.Error())
400
401 // Try to create a device with invalid data
402 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName})
403 assert.NotNil(t, err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530404 assert.Equal(t, "no-device-info-present; MAC or HOSTIP&PORT", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500405
406 // Ensure we only have 1 device in the Core
407 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
408 assert.Nil(t, err)
409 assert.NotNil(t, devices)
410 assert.Equal(t, 1, len(devices.Items))
411 assert.Equal(t, oltDevice.String(), devices.Items[0].String())
412
413 //Remove the device
414 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
415 assert.Nil(t, err)
416
417 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
418 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
419 return devices != nil && len(devices.Items) == 0
420 }
khenaidoo442e7c72020-03-10 16:13:48 -0400421 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500422 assert.Nil(t, err)
423}
424
Kent Hagerman2b216042020-04-03 18:28:56 -0400425func (nb *NBTest) testEnableDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500426 // Create a device that has no adapter registered
427 oltDeviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegistered", MacAddress: "aa:bb:cc:cc:ee:ff"})
428 assert.Nil(t, err)
429 assert.NotNil(t, oltDeviceNoAdapter)
430
431 // Try to enable the oltDevice and check the error message
432 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
433 assert.NotNil(t, err)
434 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegistered", err.Error())
435
436 //Remove the device
437 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
438 assert.Nil(t, err)
439
440 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
441 var vdFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
442 return devices != nil && len(devices.Items) == 0
443 }
khenaidoo442e7c72020-03-10 16:13:48 -0400444 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vdFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500445 assert.Nil(t, err)
446
khenaidoo67b22152020-03-02 16:01:25 -0500447 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
448 var wg sync.WaitGroup
449 wg.Add(1)
450 go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg)
451
khenaidoob64fc8a2019-11-27 15:08:19 -0500452 // Create the device with valid data
453 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
454 assert.Nil(t, err)
455 assert.NotNil(t, oltDevice)
456
457 // Verify oltDevice exist in the core
458 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
459 assert.Nil(t, err)
460 assert.Equal(t, 1, len(devices.Items))
461 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
462
463 // Enable the oltDevice
464 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
465 assert.Nil(t, err)
466
467 // Wait for the logical device to be in the ready state
468 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
469 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
470 }
471 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
472 assert.Nil(t, err)
473
474 // Verify that the devices have been setup correctly
475 nb.verifyDevices(t, nbi)
476
477 // Get latest oltDevice data
478 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
479 assert.Nil(t, err)
480
481 // Verify that the logical device has been setup correctly
482 nb.verifyLogicalDevices(t, oltDevice, nbi)
khenaidoo67b22152020-03-02 16:01:25 -0500483
484 // Wait until all flows has been sent to the devices successfully
485 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500486}
487
Kent Hagerman2b216042020-04-03 18:28:56 -0400488func (nb *NBTest) testDisableAndReEnableRootDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500489 //Get an OLT device
490 oltDevice, err := nb.getADevice(true, nbi)
491 assert.Nil(t, err)
492 assert.NotNil(t, oltDevice)
493
494 // Disable the oltDevice
495 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
496 assert.Nil(t, err)
497
498 // Wait for the old device to be disabled
499 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
500 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
501 }
502 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
503 assert.Nil(t, err)
504
505 // Verify that all onu devices are disabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400506 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500507 assert.Nil(t, err)
508 for _, onu := range onuDevices.Items {
509 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
510 assert.Nil(t, err)
511 }
512
513 // Wait for the logical device to satisfy the expected condition
514 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500515 if ld == nil {
516 return false
517 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500518 for _, lp := range ld.Ports {
519 if (lp.OfpPort.Config&uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
520 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LINK_DOWN) {
521 return false
522 }
523 }
524 return true
525 }
526 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
527 assert.Nil(t, err)
528
529 // Reenable the oltDevice
530 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
531 assert.Nil(t, err)
532
533 // Wait for the old device to be enabled
534 vdFunction = func(device *voltha.Device) bool {
535 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
536 }
537 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
538 assert.Nil(t, err)
539
540 // Verify that all onu devices are enabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400541 onuDevices, err = nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500542 assert.Nil(t, err)
543 for _, onu := range onuDevices.Items {
544 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
545 assert.Nil(t, err)
546 }
547
548 // Wait for the logical device to satisfy the expected condition
549 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500550 if ld == nil {
551 return false
552 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500553 for _, lp := range ld.Ports {
554 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
555 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
556 return false
557 }
558 }
559 return true
560 }
561 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
562 assert.Nil(t, err)
563}
564
Kent Hagerman2b216042020-04-03 18:28:56 -0400565func (nb *NBTest) testDisableAndDeleteAllDevice(t *testing.T, nbi *NBIHandler) {
khenaidoo93d5a3d2020-01-15 12:37:05 -0500566 //Get an OLT device
567 oltDevice, err := nb.getADevice(true, nbi)
568 assert.Nil(t, err)
569 assert.NotNil(t, oltDevice)
570
571 // Disable the oltDevice
572 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
573 assert.Nil(t, err)
574
575 // Wait for the olt device to be disabled
576 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
577 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
578 }
579 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
580 assert.Nil(t, err)
581
582 // Verify that all onu devices are disabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400583 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoo93d5a3d2020-01-15 12:37:05 -0500584 assert.Nil(t, err)
585 for _, onu := range onuDevices.Items {
586 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
587 assert.Nil(t, err)
588 }
589
590 // Delete the oltDevice
591 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
592 assert.Nil(t, err)
593
594 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
595 return devices != nil && len(devices.Items) == 0
596 }
597 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
598 assert.Nil(t, err)
599
600 // Wait for absence of logical device
601 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
602 return lds != nil && len(lds.Items) == 0
603 }
604
605 err = waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
606 assert.Nil(t, err)
607}
Kent Hagerman2b216042020-04-03 18:28:56 -0400608func (nb *NBTest) testEnableAndDeleteAllDevice(t *testing.T, nbi *NBIHandler) {
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500609 //Create the device with valid data
610 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
611 assert.Nil(t, err)
612 assert.NotNil(t, oltDevice)
613
614 //Get an OLT device
615 oltDevice, err = nb.getADevice(true, nbi)
616 assert.Nil(t, err)
617 assert.NotNil(t, oltDevice)
618
619 // Enable the oltDevice
620 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
621 assert.Nil(t, err)
622
623 // Wait for the logical device to be in the ready state
624 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
625 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
626 }
627 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
628 assert.Nil(t, err)
629
630 //Get all child devices
Kent Hagerman2b216042020-04-03 18:28:56 -0400631 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500632 assert.Nil(t, err)
633
634 // Wait for the all onu devices to be enabled
635 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
636 return device.AdminState == voltha.AdminState_ENABLED
637 }
638 for _, onu := range onuDevices.Items {
639 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
640 assert.Nil(t, err)
641 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500642 // Wait for each onu device to get deleted
643 var vdFunc isDeviceConditionSatisfied = func(device *voltha.Device) bool {
644 return device == nil
645 }
646
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500647 // Delete the onuDevice
648 for _, onu := range onuDevices.Items {
649 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: onu.Id})
650 assert.Nil(t, err)
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500651 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunc, nbi)
652 assert.Nil(t, err)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500653 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500654
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500655 // Disable the oltDevice
656 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
657 assert.Nil(t, err)
658
659 // Wait for the olt device to be disabled
660 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
661 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
662 }
663 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vFunction, nbi)
664 assert.Nil(t, err)
665
666 // Delete the oltDevice
667 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
668 assert.Nil(t, err)
669
670 var vFunc isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
671 return devices != nil && len(devices.Items) == 0
672 }
673 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunc)
674 assert.Nil(t, err)
675}
Kent Hagerman2b216042020-04-03 18:28:56 -0400676func (nb *NBTest) testDisableAndEnablePort(t *testing.T, nbi *NBIHandler) {
kesavandbc2d1622020-01-21 00:42:01 -0500677 //Get an OLT device
678 var cp *voltha.Port
679 oltDevice, err := nb.getADevice(true, nbi)
680 assert.Nil(t, err)
681 assert.NotNil(t, oltDevice)
682
683 for _, cp = range oltDevice.Ports {
684 if cp.Type == voltha.Port_PON_OLT {
685 break
686 }
687
688 }
689 assert.NotNil(t, cp)
690 cp.DeviceId = oltDevice.Id
691
692 // Disable the NW Port of oltDevice
693 _, err = nbi.DisablePort(getContext(), cp)
694 assert.Nil(t, err)
695 // Wait for the olt device Port to be disabled
696 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
697 for _, port := range device.Ports {
698 if port.PortNo == cp.PortNo {
699 return port.AdminState == voltha.AdminState_DISABLED
700 }
701 }
702 return false
703 }
704 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
705 assert.Nil(t, err)
706 // Wait for the logical device to satisfy the expected condition
707 var vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500708 if ld == nil {
709 return false
710 }
kesavandbc2d1622020-01-21 00:42:01 -0500711 for _, lp := range ld.Ports {
712 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
713 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
714 return false
715 }
716 }
717 return true
718 }
719 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
720 assert.Nil(t, err)
721
722 // Enable the NW Port of oltDevice
723 _, err = nbi.EnablePort(getContext(), cp)
724 assert.Nil(t, err)
725
726 // Wait for the olt device Port to be enabled
727 vdFunction = func(device *voltha.Device) bool {
728 for _, port := range device.Ports {
729 if port.PortNo == cp.PortNo {
730 return port.AdminState == voltha.AdminState_ENABLED
731 }
732 }
733 return false
734 }
735 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
736 assert.Nil(t, err)
737 // Wait for the logical device to satisfy the expected condition
738 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500739 if ld == nil {
740 return false
741 }
kesavandbc2d1622020-01-21 00:42:01 -0500742 for _, lp := range ld.Ports {
743 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
744 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
745 return false
746 }
747 }
748 return true
749 }
750 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
751 assert.Nil(t, err)
752
753 // Disable a non-PON port
754 for _, cp = range oltDevice.Ports {
755 if cp.Type != voltha.Port_PON_OLT {
756 break
757 }
758
759 }
760 assert.NotNil(t, cp)
761 cp.DeviceId = oltDevice.Id
762
763 // Disable the NW Port of oltDevice
764 _, err = nbi.DisablePort(getContext(), cp)
765 assert.NotNil(t, err)
766
767}
khenaidoo93d5a3d2020-01-15 12:37:05 -0500768
Kent Hagerman2b216042020-04-03 18:28:56 -0400769func (nb *NBTest) testDeviceRebootWhenOltIsEnabled(t *testing.T, nbi *NBIHandler) {
Girish Gowdra408cd962020-03-11 14:31:31 -0700770 //Get an OLT device
771 oltDevice, err := nb.getADevice(true, nbi)
772 assert.Nil(t, err)
773 assert.NotNil(t, oltDevice)
774 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
775 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
776
777 // Verify that we have one or more ONUs to start with
Kent Hagerman2b216042020-04-03 18:28:56 -0400778 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Girish Gowdra408cd962020-03-11 14:31:31 -0700779 assert.Nil(t, err)
780 assert.NotNil(t, onuDevices)
781 assert.Greater(t, len(onuDevices.Items), 0)
782
783 // Reboot the OLT and very that Connection Status goes to UNREACHABLE and operation status to UNKNOWN
784 _, err = nbi.RebootDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
785 assert.Nil(t, err)
786
787 var vlFunction0 = func(d *voltha.Device) bool {
788 return d.ConnectStatus == voltha.ConnectStatus_UNREACHABLE && d.OperStatus == voltha.OperStatus_UNKNOWN
789 }
790
791 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction0, nbi)
792 assert.Nil(t, err)
793
794 // Wait for the logical device to satisfy the expected condition
795 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
796 return ld == nil
797 }
798
799 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
800 assert.Nil(t, err)
801
802 // Wait for the device to satisfy the expected condition (device does not have flows)
803 var vlFunction2 = func(d *voltha.Device) bool {
804 var deviceFlows *ofp.Flows
805 var err error
806 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
807 return false
808 }
809 return len(deviceFlows.Items) == 0
810 }
811
812 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
813 assert.Nil(t, err)
814
815 // Wait for the device to satisfy the expected condition (there are no child devices)
816 var vlFunction3 = func(d *voltha.Device) bool {
817 var devices *voltha.Devices
818 var err error
819 if devices, err = nbi.ListDevices(getContext(), nil); err != nil {
820 return false
821 }
822 for _, device := range devices.Items {
823 if device.ParentId == d.Id {
824 // We have a child device still left
825 return false
826 }
827 }
828 return true
829 }
830
831 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction3, nbi)
832 assert.Nil(t, err)
833
834 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
835 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
Kent Hagerman2b216042020-04-03 18:28:56 -0400836 err = nbi.deviceMgr.UpdateDeviceStatus(getContext(), oltDevice.Id, voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
Girish Gowdra408cd962020-03-11 14:31:31 -0700837 assert.Nil(t, err)
838
839 // Verify the device connection and operation states
840 oltDevice, err = nb.getADevice(true, nbi)
841 assert.Nil(t, err)
842 assert.NotNil(t, oltDevice)
843 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
844 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
845
846 // Wait for the logical device to satisfy the expected condition
847 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
848 return ld != nil
849 }
850 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
851 assert.Nil(t, err)
852
853 // Verify that logical device is created again
854 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
855 assert.Nil(t, err)
856 assert.NotNil(t, logicalDevices)
857 assert.Equal(t, 1, len(logicalDevices.Items))
858
859 // Verify that we have no ONUs left
Kent Hagerman2b216042020-04-03 18:28:56 -0400860 onuDevices, err = nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Girish Gowdra408cd962020-03-11 14:31:31 -0700861 assert.Nil(t, err)
862 assert.NotNil(t, onuDevices)
863 assert.Equal(t, 0, len(onuDevices.Items))
864}
865
Kent Hagerman2b216042020-04-03 18:28:56 -0400866func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi *NBIHandler) {
Scott Baker432f9be2020-03-26 11:56:30 -0700867 // -----------------------------------------------------------------------
868 // SubTest 1: Omci test action should fail due to nonexistent device id
869
870 request := &voltha.OmciTestRequest{Id: "123", Uuid: "456"}
871 _, err := nbi.StartOmciTestAction(getContext(), request)
872 assert.NotNil(t, err)
873 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
874
875 // -----------------------------------------------------------------------
876 // SubTest 2: Error should be returned for device with no adapter registered
877
878 // Create a device that has no adapter registered
879 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: "aa:bb:cc:cc:ee:01"})
880 assert.Nil(t, err)
881 assert.NotNil(t, deviceNoAdapter)
882
883 // Omci test action should fail due to nonexistent adapter
884 request = &voltha.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
885 _, err = nbi.StartOmciTestAction(getContext(), request)
886 assert.NotNil(t, err)
887 assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegisteredOmciTest", err.Error())
888
889 //Remove the device
890 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
891 assert.Nil(t, err)
892
893 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
894 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
895 return devices != nil && len(devices.Items) == 0
896 }
897 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
898 assert.Nil(t, err)
899
900 // -----------------------------------------------------------------------
901 // SubTest 3: Omci test action should succeed on valid ONU
902
903 // Create the device with valid data
904 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
905 assert.Nil(t, err)
906 assert.NotNil(t, oltDevice)
907
908 // Verify oltDevice exist in the core
909 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
910 assert.Nil(t, err)
911 assert.Equal(t, 1, len(devices.Items))
912 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
913
914 // Enable the oltDevice
915 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
916 assert.Nil(t, err)
917
918 // Wait for the logical device to be in the ready state
919 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
920 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
921 }
922 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
923 assert.Nil(t, err)
924
925 // Wait for the olt device to be enabled
926 vdFunction := func(device *voltha.Device) bool {
927 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
928 }
929 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
930 assert.Nil(t, err)
931
Kent Hagerman2b216042020-04-03 18:28:56 -0400932 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Scott Baker432f9be2020-03-26 11:56:30 -0700933 assert.Nil(t, err)
934 assert.Greater(t, len(onuDevices.Items), 0)
935
936 onuDevice := onuDevices.Items[0]
937
938 // Omci test action should succeed
939 request = &voltha.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
940 resp, err := nbi.StartOmciTestAction(getContext(), request)
941 assert.Nil(t, err)
942 assert.Equal(t, resp.Result, voltha.TestResponse_SUCCESS)
943
944 //Remove the device
945 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
946 assert.Nil(t, err)
947 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
948 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
949 assert.Nil(t, err)
950}
951
khenaidoo67b22152020-03-02 16:01:25 -0500952func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
953 matchFields := make([]*ofp.OfpOxmField, 0)
954 for _, val := range fa.MatchFields {
955 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
956 }
957 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
958}
959
960func createMetadata(cTag int, techProfile int, port int) uint64 {
961 md := 0
962 md = (md | (cTag & 0xFFFF)) << 16
963 md = (md | (techProfile & 0xFFFF)) << 32
964 return uint64(md | (port & 0xFFFFFFFF))
965}
966
Kent Hagerman2b216042020-04-03 18:28:56 -0400967func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi *NBIHandler, numNNIPorts int, numUNIPorts int) {
khenaidoo67b22152020-03-02 16:01:25 -0500968 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
969 // Wait for logical device to have all the flows
970 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
971 return lds != nil && len(lds.Items) == 1 && len(lds.Items[0].Flows.Items) == expectedNumFlows
972 }
973 // No timeout implies a success
974 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
975 assert.Nil(t, err)
976}
977
Kent Hagerman2b216042020-04-03 18:28:56 -0400978func (nb *NBTest) sendTrapFlows(t *testing.T, nbi *NBIHandler, logicalDevice *voltha.LogicalDevice, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
khenaidoo67b22152020-03-02 16:01:25 -0500979 // Send flows for the parent device
980 var nniPorts []*voltha.LogicalPort
981 var uniPorts []*voltha.LogicalPort
982 for _, p := range logicalDevice.Ports {
983 if p.RootPort {
984 nniPorts = append(nniPorts, p)
985 } else {
986 uniPorts = append(uniPorts, p)
987 }
988 }
989 assert.Equal(t, 1, len(nniPorts))
990 //assert.Greater(t, len(uniPorts), 1 )
991 nniPort := nniPorts[0].OfpPort.PortNo
992 maxInt32 := uint64(0xFFFFFFFF)
993 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
994 var fa *flows.FlowArgs
995 fa = &flows.FlowArgs{
996 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
997 MatchFields: []*ofp.OfpOxmOfbField{
998 flows.InPort(nniPort),
999 flows.EthType(35020),
1000 },
1001 Actions: []*ofp.OfpAction{
1002 flows.Output(controllerPortMask),
1003 },
1004 }
1005 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1006 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
1007 assert.Nil(t, err)
1008
1009 fa = &flows.FlowArgs{
1010 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1011 MatchFields: []*ofp.OfpOxmOfbField{
1012 flows.InPort(nniPort),
1013 flows.EthType(2048),
1014 flows.IpProto(17),
1015 flows.UdpSrc(67),
1016 flows.UdpDst(68),
1017 },
1018 Actions: []*ofp.OfpAction{
1019 flows.Output(controllerPortMask),
1020 },
1021 }
1022 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1023 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
1024 assert.Nil(t, err)
1025
1026 fa = &flows.FlowArgs{
1027 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1028 MatchFields: []*ofp.OfpOxmOfbField{
1029 flows.InPort(nniPort),
1030 flows.EthType(34525),
1031 flows.IpProto(17),
1032 flows.UdpSrc(546),
1033 flows.UdpDst(547),
1034 },
1035 Actions: []*ofp.OfpAction{
1036 flows.Output(controllerPortMask),
1037 },
1038 }
1039 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1040 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
1041 assert.Nil(t, err)
1042
1043 return len(nniPorts), len(uniPorts)
1044}
1045
Kent Hagerman2b216042020-04-03 18:28:56 -04001046func (nb *NBTest) sendEAPFlows(t *testing.T, nbi *NBIHandler, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
khenaidoo67b22152020-03-02 16:01:25 -05001047 maxInt32 := uint64(0xFFFFFFFF)
1048 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1049 fa := &flows.FlowArgs{
1050 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},
1051 MatchFields: []*ofp.OfpOxmOfbField{
1052 flows.InPort(port.PortNo),
1053 flows.EthType(34958),
1054 flows.VlanVid(8187),
1055 },
1056 Actions: []*ofp.OfpAction{
1057 flows.Output(controllerPortMask),
1058 },
1059 }
1060 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1061 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP)
1062 assert.Nil(t, err)
1063}
1064
Kent Hagerman2b216042020-04-03 18:28:56 -04001065func (nb *NBTest) monitorLogicalDevice(t *testing.T, nbi *NBIHandler, numNNIPorts int, numUNIPorts int, wg *sync.WaitGroup) {
khenaidoo67b22152020-03-02 16:01:25 -05001066 defer wg.Done()
Kent Hagerman2b216042020-04-03 18:28:56 -04001067 nb.logicalDeviceMgr.SetEventCallbacks(nbi)
khenaidoo67b22152020-03-02 16:01:25 -05001068
1069 // Clear any existing flows on the adapters
1070 nb.oltAdapter.ClearFlows()
1071 nb.onuAdapter.ClearFlows()
1072
1073 // Wait until a logical device is ready
1074 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
1075 if lds == nil || len(lds.Items) != 1 {
1076 return false
1077 }
1078 // Ensure there are both NNI ports and at least one UNI port on the logical device
1079 ld := lds.Items[0]
1080 nniPort := false
1081 uniPort := false
1082 for _, p := range ld.Ports {
1083 nniPort = nniPort || p.RootPort == true
1084 uniPort = uniPort || p.RootPort == false
1085 if nniPort && uniPort {
1086 return true
1087 }
1088 }
1089 return false
1090 }
1091 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
1092 assert.Nil(t, err)
1093
1094 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
1095 assert.Nil(t, err)
1096 assert.NotNil(t, logicalDevices)
1097 assert.Equal(t, 1, len(logicalDevices.Items))
1098
1099 logicalDevice := logicalDevices.Items[0]
1100 meterID := rand.Uint32()
1101
1102 // Add a meter to the logical device
1103 meterMod := &ofp.OfpMeterMod{
1104 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
1105 Flags: rand.Uint32(),
1106 MeterId: meterID,
1107 Bands: []*ofp.OfpMeterBandHeader{
1108 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
1109 Rate: rand.Uint32(),
1110 BurstSize: rand.Uint32(),
1111 Data: nil,
1112 },
1113 },
1114 }
1115 _, err = nbi.UpdateLogicalDeviceMeterTable(getContext(), &ofp.MeterModUpdate{Id: logicalDevice.Id, MeterMod: meterMod})
1116 assert.Nil(t, err)
1117
1118 // Send initial set of Trap flows
1119 startingVlan := 4091
1120 nb.sendTrapFlows(t, nbi, logicalDevice, uint64(meterID), startingVlan)
1121
1122 // Listen for port events
khenaidoo442e7c72020-03-10 16:13:48 -04001123 start := time.Now()
Girish Gowdra408cd962020-03-11 14:31:31 -07001124 processedNniLogicalPorts := 0
1125 processedUniLogicalPorts := 0
1126
khenaidoo67b22152020-03-02 16:01:25 -05001127 for event := range nbi.changeEventQueue {
1128 startingVlan++
1129 if portStatus, ok := (event.Event).(*ofp.ChangeEvent_PortStatus); ok {
1130 ps := portStatus.PortStatus
1131 if ps.Reason == ofp.OfpPortReason_OFPPR_ADD {
khenaidoo67b22152020-03-02 16:01:25 -05001132 if ps.Desc.PortNo >= uint32(nb.startingUNIPortNo) {
Girish Gowdra408cd962020-03-11 14:31:31 -07001133 processedUniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001134 nb.sendEAPFlows(t, nbi, logicalDevice.Id, ps.Desc, startingVlan, uint64(meterID))
Girish Gowdra408cd962020-03-11 14:31:31 -07001135 } else {
1136 processedNniLogicalPorts++
khenaidoo67b22152020-03-02 16:01:25 -05001137 }
1138 }
1139 }
Girish Gowdra408cd962020-03-11 14:31:31 -07001140
1141 if processedNniLogicalPorts >= numNNIPorts && processedUniLogicalPorts >= numUNIPorts {
khenaidoo442e7c72020-03-10 16:13:48 -04001142 fmt.Println("Total time to send all flows:", time.Since(start))
khenaidoo67b22152020-03-02 16:01:25 -05001143 break
1144 }
1145 }
1146 //Verify the flow count on the logical device
1147 nb.verifyLogicalDeviceFlowCount(t, nbi, numNNIPorts, numUNIPorts)
1148
1149 // Wait until all flows have been sent to the OLT adapters
1150 var oltVFunc isConditionSatisfied = func() bool {
1151 return nb.oltAdapter.GetFlowCount() >= (numNNIPorts*3)+numNNIPorts*numUNIPorts
1152 }
1153 err = waitUntilCondition(nb.maxTimeout, nbi, oltVFunc)
1154 assert.Nil(t, err)
1155
1156 // Wait until all flows have been sent to the ONU adapters
1157 var onuVFunc isConditionSatisfied = func() bool {
1158 return nb.onuAdapter.GetFlowCount() == numUNIPorts
1159 }
1160 err = waitUntilCondition(nb.maxTimeout, nbi, onuVFunc)
1161 assert.Nil(t, err)
1162}
1163
Matteo Scandolod525ae32020-04-02 17:27:29 -07001164func TestSuiteNbiApiHandler(t *testing.T) {
Kent Hagerman2b216042020-04-03 18:28:56 -04001165 f, err := os.Create("../../../tests/results/profile.cpu")
khenaidoo67b22152020-03-02 16:01:25 -05001166 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001167 logger.Fatalf("could not create CPU profile: %v\n ", err)
khenaidoo67b22152020-03-02 16:01:25 -05001168 }
1169 defer f.Close()
1170 runtime.SetBlockProfileRate(1)
1171 runtime.SetMutexProfileFraction(-1)
1172 if err := pprof.StartCPUProfile(f); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +00001173 logger.Fatalf("could not start CPU profile: %v\n", err)
khenaidoo67b22152020-03-02 16:01:25 -05001174 }
1175 defer pprof.StopCPUProfile()
1176
khenaidoo442e7c72020-03-10 16:13:48 -04001177 //log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
1178
khenaidoob64fc8a2019-11-27 15:08:19 -05001179 nb := newNBTest()
1180 assert.NotNil(t, nb)
1181
1182 defer nb.stopAll()
1183
1184 // Start the Core
1185 nb.startCore(false)
1186
1187 // Set the grpc API interface - no grpc server is running in unit test
Kent Hagerman2b216042020-04-03 18:28:56 -04001188 nbi := NewAPIHandler(nb.deviceMgr, nb.logicalDeviceMgr, nb.adapterMgr)
khenaidoob64fc8a2019-11-27 15:08:19 -05001189
1190 // 1. Basic test with no data in Core
1191 nb.testCoreWithoutData(t, nbi)
1192
1193 // Create/register the adapters
Thomas Lee Se5a44012019-11-07 20:32:24 +05301194 nb.createAndregisterAdapters(t)
khenaidoob64fc8a2019-11-27 15:08:19 -05001195
1196 // 2. Test adapter registration
1197 nb.testAdapterRegistration(t, nbi)
1198
Scott Baker8cb47bb2020-04-01 09:57:20 -07001199 numberOfDeviceTestRuns := 2
khenaidoo93d5a3d2020-01-15 12:37:05 -05001200 for i := 1; i <= numberOfDeviceTestRuns; i++ {
khenaidoo67b22152020-03-02 16:01:25 -05001201 //3. Test create device
khenaidoo93d5a3d2020-01-15 12:37:05 -05001202 nb.testCreateDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001203
khenaidoo93d5a3d2020-01-15 12:37:05 -05001204 // 4. Test Enable a device
1205 nb.testEnableDevice(t, nbi)
khenaidoob64fc8a2019-11-27 15:08:19 -05001206
khenaidoo93d5a3d2020-01-15 12:37:05 -05001207 // 5. Test disable and ReEnable a root device
1208 nb.testDisableAndReEnableRootDevice(t, nbi)
khenaidoo67b22152020-03-02 16:01:25 -05001209
kesavandbc2d1622020-01-21 00:42:01 -05001210 // 6. Test disable and Enable pon port of OLT device
1211 nb.testDisableAndEnablePort(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001212
Girish Gowdra408cd962020-03-11 14:31:31 -07001213 // 7.Test Device unreachable when OLT is enabled
1214 nb.testDeviceRebootWhenOltIsEnabled(t, nbi)
1215
1216 // 8. Test disable and delete all devices
khenaidoo93d5a3d2020-01-15 12:37:05 -05001217 nb.testDisableAndDeleteAllDevice(t, nbi)
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001218
Girish Gowdra408cd962020-03-11 14:31:31 -07001219 // 9. Test enable and delete all devices
Chaitrashree G S543df3e2020-02-24 22:36:54 -05001220 nb.testEnableAndDeleteAllDevice(t, nbi)
Scott Baker432f9be2020-03-26 11:56:30 -07001221
1222 // 10. Test omci test
1223 nb.testStartOmciTestAction(t, nbi)
khenaidoo93d5a3d2020-01-15 12:37:05 -05001224 }
khenaidoob64fc8a2019-11-27 15:08:19 -05001225
1226 //x. TODO - More tests to come
1227}