blob: e8b651d9db1e9be92d3c3ec27b88e43bfbbd6f82 [file] [log] [blame]
khenaidoob64fc8a2019-11-27 15:08:19 -05001/*
Kent Hagerman45a13e42020-04-13 12:23:50 -04002 * 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.
khenaidoob64fc8a2019-11-27 15:08:19 -050015 */
Kent Hagerman45a13e42020-04-13 12:23:50 -040016
Kent Hagerman2b216042020-04-03 18:28:56 -040017package api
khenaidoob64fc8a2019-11-27 15:08:19 -050018
19import (
20 "context"
21 "errors"
22 "fmt"
khenaidoo67b22152020-03-02 16:01:25 -050023 "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"
Kent Hagerman2b216042020-04-03 18:28:56 -040033 "github.com/opencord/voltha-go/db/model"
khenaidoob64fc8a2019-11-27 15:08:19 -050034 "github.com/opencord/voltha-go/rw_core/config"
Kent Hagerman2b216042020-04-03 18:28:56 -040035 "github.com/opencord/voltha-go/rw_core/core/adapter"
36 "github.com/opencord/voltha-go/rw_core/core/device"
khenaidoob64fc8a2019-11-27 15:08:19 -050037 cm "github.com/opencord/voltha-go/rw_core/mocks"
Kent Hagerman2b216042020-04-03 18:28:56 -040038 "github.com/opencord/voltha-lib-go/v3/pkg/db"
39 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080040 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
41 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Matteo Scandolod525ae32020-04-02 17:27:29 -070042 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
43 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080044 "github.com/opencord/voltha-lib-go/v3/pkg/version"
45 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
46 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob64fc8a2019-11-27 15:08:19 -050047 "github.com/phayes/freeport"
48 "github.com/stretchr/testify/assert"
49 "google.golang.org/grpc/codes"
50 "google.golang.org/grpc/status"
khenaidoob64fc8a2019-11-27 15:08:19 -050051)
52
Kent Hagerman2b216042020-04-03 18:28:56 -040053const (
54 coreName = "rw_core"
55)
56
khenaidoob64fc8a2019-11-27 15:08:19 -050057type NBTest struct {
Matteo Scandolod525ae32020-04-02 17:27:29 -070058 etcdServer *mock_etcd.EtcdServer
Kent Hagerman2b216042020-04-03 18:28:56 -040059 deviceMgr *device.Manager
60 logicalDeviceMgr *device.LogicalManager
61 adapterMgr *adapter.Manager
62 kmp kafka.InterContainerProxy
khenaidoo67b22152020-03-02 16:01:25 -050063 kClient kafka.Client
64 kvClientPort int
65 numONUPerOLT int
66 startingUNIPortNo int
67 oltAdapter *cm.OLTAdapter
68 onuAdapter *cm.ONUAdapter
69 oltAdapterName string
70 onuAdapterName string
71 coreInstanceID string
72 defaultTimeout time.Duration
73 maxTimeout time.Duration
khenaidoob64fc8a2019-11-27 15:08:19 -050074}
75
76func newNBTest() *NBTest {
77 test := &NBTest{}
78 // Start the embedded etcd server
79 var err error
80 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.nb.test", "voltha.rwcore.nb.etcd", "error")
81 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000082 logger.Fatal(err)
khenaidoob64fc8a2019-11-27 15:08:19 -050083 }
84 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -070085 test.kClient = mock_kafka.NewKafkaClient()
khenaidoob64fc8a2019-11-27 15:08:19 -050086 test.oltAdapterName = "olt_adapter_mock"
87 test.onuAdapterName = "onu_adapter_mock"
88 test.coreInstanceID = "rw-nbi-test"
khenaidoo32836732020-03-05 16:10:44 -050089 test.defaultTimeout = 10 * time.Second
90 test.maxTimeout = 20 * time.Second
khenaidoob64fc8a2019-11-27 15:08:19 -050091 return test
92}
93
94func (nb *NBTest) startCore(inCompeteMode bool) {
Thomas Lee Se5a44012019-11-07 20:32:24 +053095 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
96 defer cancel()
khenaidoob64fc8a2019-11-27 15:08:19 -050097 cfg := config.NewRWCoreFlags()
98 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -040099 cfg.DefaultRequestTimeout = nb.defaultTimeout
100 cfg.DefaultCoreTimeout = nb.defaultTimeout
khenaidoob64fc8a2019-11-27 15:08:19 -0500101 cfg.KVStorePort = nb.kvClientPort
102 cfg.InCompetingMode = inCompeteMode
103 grpcPort, err := freeport.GetFreePort()
104 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000105 logger.Fatal("Cannot get a freeport for grpc")
khenaidoob64fc8a2019-11-27 15:08:19 -0500106 }
107 cfg.GrpcPort = grpcPort
108 cfg.GrpcHost = "127.0.0.1"
109 setCoreCompeteMode(inCompeteMode)
110 client := setupKVClient(cfg, nb.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400111 backend := &db.Backend{
112 Client: client,
113 StoreType: cfg.KVStoreType,
114 Host: cfg.KVStoreHost,
115 Port: cfg.KVStorePort,
116 Timeout: cfg.KVStoreTimeout,
117 LivenessChannelInterval: cfg.LiveProbeInterval / 2,
118 PathPrefix: cfg.KVStoreDataPrefix}
119 nb.kmp = kafka.NewInterContainerProxy(
120 kafka.InterContainerHost(cfg.KafkaAdapterHost),
121 kafka.InterContainerPort(cfg.KafkaAdapterPort),
122 kafka.MsgClient(nb.kClient),
123 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}),
124 kafka.DeviceDiscoveryTopic(&kafka.Topic{Name: cfg.AffinityRouterTopic}))
125
126 endpointMgr := kafka.NewEndpointManager(backend)
127 proxy := model.NewProxy(backend, "/")
128 nb.adapterMgr = adapter.NewAdapterManager(proxy, nb.coreInstanceID, nb.kClient)
Kent Hagerman45a13e42020-04-13 12:23:50 -0400129 nb.deviceMgr, nb.logicalDeviceMgr = device.NewManagers(proxy, nb.adapterMgr, nb.kmp, endpointMgr, cfg.CorePairTopic, nb.coreInstanceID, cfg.DefaultCoreTimeout)
Kent Hagerman2b216042020-04-03 18:28:56 -0400130 if err = nb.adapterMgr.Start(ctx); err != nil {
131 logger.Fatalf("Cannot start adapterMgr: %s", err)
132 }
133 nb.deviceMgr.Start(ctx)
134 nb.logicalDeviceMgr.Start(ctx)
135
136 if err = nb.kmp.Start(); err != nil {
137 logger.Fatalf("Cannot start InterContainerProxy: %s", err)
138 }
139 requestProxy := NewAdapterRequestHandlerProxy(nb.coreInstanceID, nb.deviceMgr, nb.adapterMgr, proxy, proxy, cfg.LongRunningRequestTimeout, cfg.DefaultRequestTimeout)
140 if err := nb.kmp.SubscribeWithRequestHandlerInterface(kafka.Topic{Name: cfg.CoreTopic}, requestProxy); err != nil {
141 logger.Fatalf("Cannot add request handler: %s", err)
142 }
143 if err := nb.kmp.SubscribeWithDefaultRequestHandler(kafka.Topic{Name: cfg.CorePairTopic}, kafka.OffsetNewest); err != nil {
144 logger.Fatalf("Cannot add default request handler: %s", err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530145 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500146}
147
Thomas Lee Se5a44012019-11-07 20:32:24 +0530148func (nb *NBTest) createAndregisterAdapters(t *testing.T) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500149 // Setup the mock OLT adapter
150 oltAdapter, err := createMockAdapter(OltAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.oltAdapterName)
151 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000152 logger.Fatalw("setting-mock-olt-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500153 }
khenaidoo67b22152020-03-02 16:01:25 -0500154 nb.oltAdapter = (oltAdapter).(*cm.OLTAdapter)
155 nb.numONUPerOLT = nb.oltAdapter.GetNumONUPerOLT()
156 nb.startingUNIPortNo = nb.oltAdapter.GetStartingUNIPortNo()
157
khenaidoob64fc8a2019-11-27 15:08:19 -0500158 // Register the adapter
159 registrationData := &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700160 Id: nb.oltAdapterName,
161 Vendor: "Voltha-olt",
162 Version: version.VersionInfo.Version,
163 Type: nb.oltAdapterName,
164 CurrentReplica: 1,
165 TotalReplicas: 1,
166 Endpoint: nb.oltAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500167 }
168 types := []*voltha.DeviceType{{Id: nb.oltAdapterName, Adapter: nb.oltAdapterName, AcceptsAddRemoveFlowUpdates: true}}
169 deviceTypes := &voltha.DeviceTypes{Items: types}
Kent Hagerman2b216042020-04-03 18:28:56 -0400170 if _, err := nb.adapterMgr.RegisterAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000171 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530172 assert.NotNil(t, err)
173 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500174
175 // Setup the mock ONU adapter
khenaidoo67b22152020-03-02 16:01:25 -0500176 onuAdapter, err := createMockAdapter(OnuAdapter, nb.kClient, nb.coreInstanceID, coreName, nb.onuAdapterName)
177 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000178 logger.Fatalw("setting-mock-onu-adapter-failed", log.Fields{"error": err})
khenaidoob64fc8a2019-11-27 15:08:19 -0500179 }
khenaidoo67b22152020-03-02 16:01:25 -0500180 nb.onuAdapter = (onuAdapter).(*cm.ONUAdapter)
181
khenaidoob64fc8a2019-11-27 15:08:19 -0500182 // Register the adapter
183 registrationData = &voltha.Adapter{
Matteo Scandolod525ae32020-04-02 17:27:29 -0700184 Id: nb.onuAdapterName,
185 Vendor: "Voltha-onu",
186 Version: version.VersionInfo.Version,
187 Type: nb.onuAdapterName,
188 CurrentReplica: 1,
189 TotalReplicas: 1,
190 Endpoint: nb.onuAdapterName,
khenaidoob64fc8a2019-11-27 15:08:19 -0500191 }
192 types = []*voltha.DeviceType{{Id: nb.onuAdapterName, Adapter: nb.onuAdapterName, AcceptsAddRemoveFlowUpdates: true}}
193 deviceTypes = &voltha.DeviceTypes{Items: types}
Kent Hagerman2b216042020-04-03 18:28:56 -0400194 if _, err := nb.adapterMgr.RegisterAdapter(registrationData, deviceTypes); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000195 logger.Errorw("failed-to-register-adapter", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530196 assert.NotNil(t, err)
197 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500198}
199
200func (nb *NBTest) stopAll() {
201 if nb.kClient != nil {
202 nb.kClient.Stop()
203 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400204 if nb.logicalDeviceMgr != nil {
205 nb.logicalDeviceMgr.Stop(context.Background())
206 }
207 if nb.deviceMgr != nil {
208 nb.deviceMgr.Stop(context.Background())
209 }
210 if nb.kmp != nil {
211 nb.kmp.Stop()
khenaidoob64fc8a2019-11-27 15:08:19 -0500212 }
213 if nb.etcdServer != nil {
214 stopEmbeddedEtcdServer(nb.etcdServer)
215 }
216}
217
Kent Hagerman2b216042020-04-03 18:28:56 -0400218func (nb *NBTest) verifyLogicalDevices(t *testing.T, oltDevice *voltha.Device, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500219 // Get the latest set of logical devices
220 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
221 assert.Nil(t, err)
222 assert.NotNil(t, logicalDevices)
223 assert.Equal(t, 1, len(logicalDevices.Items))
224
225 ld := logicalDevices.Items[0]
226 assert.NotEqual(t, "", ld.Id)
227 assert.NotEqual(t, uint64(0), ld.DatapathId)
228 assert.Equal(t, "olt_adapter_mock", ld.Desc.HwDesc)
229 assert.Equal(t, "olt_adapter_mock", ld.Desc.SwDesc)
230 assert.NotEqual(t, "", ld.RootDeviceId)
231 assert.NotEqual(t, "", ld.Desc.SerialNum)
232 assert.Equal(t, uint32(256), ld.SwitchFeatures.NBuffers)
233 assert.Equal(t, uint32(2), ld.SwitchFeatures.NTables)
234 assert.Equal(t, uint32(15), ld.SwitchFeatures.Capabilities)
235 assert.Equal(t, 1+nb.numONUPerOLT, len(ld.Ports))
236 assert.Equal(t, oltDevice.ParentId, ld.Id)
237 //Expected port no
238 expectedPortNo := make(map[uint32]bool)
239 expectedPortNo[uint32(2)] = false
240 for i := 0; i < nb.numONUPerOLT; i++ {
241 expectedPortNo[uint32(i+100)] = false
242 }
243 for _, p := range ld.Ports {
244 assert.Equal(t, p.OfpPort.PortNo, p.DevicePortNo)
245 assert.Equal(t, uint32(4), p.OfpPort.State)
246 expectedPortNo[p.OfpPort.PortNo] = true
247 if strings.HasPrefix(p.Id, "nni") {
248 assert.Equal(t, true, p.RootPort)
249 //assert.Equal(t, uint32(2), p.OfpPort.PortNo)
250 assert.Equal(t, p.Id, fmt.Sprintf("nni-%d", p.DevicePortNo))
251 } else {
252 assert.Equal(t, p.Id, fmt.Sprintf("uni-%d", p.DevicePortNo))
253 assert.Equal(t, false, p.RootPort)
254 }
255 }
256}
257
Kent Hagerman2b216042020-04-03 18:28:56 -0400258func (nb *NBTest) verifyDevices(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500259 // Get the latest set of devices
260 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
261 assert.Nil(t, err)
262 assert.NotNil(t, devices)
263
khenaidoo67b22152020-03-02 16:01:25 -0500264 // A device is ready to be examined when its ADMIN state is ENABLED and OPERATIONAL state is ACTIVE
khenaidoob64fc8a2019-11-27 15:08:19 -0500265 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
266 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
267 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500268
khenaidoo67b22152020-03-02 16:01:25 -0500269 var wg sync.WaitGroup
270 for _, device := range devices.Items {
271 wg.Add(1)
272 go func(wg *sync.WaitGroup, device *voltha.Device) {
273 // Wait until the device is in the right state
274 err := waitUntilDeviceReadiness(device.Id, nb.maxTimeout, vFunction, nbi)
275 assert.Nil(t, err)
276
277 // Now, verify the details of the device. First get the latest update
278 d, err := nbi.GetDevice(getContext(), &voltha.ID{Id: device.Id})
279 assert.Nil(t, err)
280 assert.Equal(t, voltha.AdminState_ENABLED, d.AdminState)
281 assert.Equal(t, voltha.ConnectStatus_REACHABLE, d.ConnectStatus)
282 assert.Equal(t, voltha.OperStatus_ACTIVE, d.OperStatus)
283 assert.Equal(t, d.Type, d.Adapter)
284 assert.NotEqual(t, "", d.MacAddress)
285 assert.NotEqual(t, "", d.SerialNumber)
286
287 if d.Type == "olt_adapter_mock" {
288 assert.Equal(t, true, d.Root)
289 assert.NotEqual(t, "", d.Id)
290 assert.NotEqual(t, "", d.ParentId)
291 assert.Nil(t, d.ProxyAddress)
292 } else if d.Type == "onu_adapter_mock" {
293 assert.Equal(t, false, d.Root)
294 assert.NotEqual(t, uint32(0), d.Vlan)
295 assert.NotEqual(t, "", d.Id)
296 assert.NotEqual(t, "", d.ParentId)
297 assert.NotEqual(t, "", d.ProxyAddress.DeviceId)
298 assert.Equal(t, "olt_adapter_mock", d.ProxyAddress.DeviceType)
khenaidoob64fc8a2019-11-27 15:08:19 -0500299 } else {
khenaidoo67b22152020-03-02 16:01:25 -0500300 assert.Error(t, errors.New("invalid-device-type"))
khenaidoob64fc8a2019-11-27 15:08:19 -0500301 }
khenaidoo67b22152020-03-02 16:01:25 -0500302 assert.Equal(t, 2, len(d.Ports))
303 for _, p := range d.Ports {
304 assert.Equal(t, voltha.AdminState_ENABLED, p.AdminState)
305 assert.Equal(t, voltha.OperStatus_ACTIVE, p.OperStatus)
306 if p.Type == voltha.Port_ETHERNET_NNI || p.Type == voltha.Port_ETHERNET_UNI {
307 assert.Equal(t, 0, len(p.Peers))
308 } else if p.Type == voltha.Port_PON_OLT {
309 assert.Equal(t, nb.numONUPerOLT, len(p.Peers))
310 assert.Equal(t, uint32(1), p.PortNo)
311 } else if p.Type == voltha.Port_PON_ONU {
312 assert.Equal(t, 1, len(p.Peers))
313 assert.Equal(t, uint32(1), p.PortNo)
314 } else {
315 assert.Error(t, errors.New("invalid-port"))
316 }
317 }
318 wg.Done()
319 }(&wg, device)
khenaidoob64fc8a2019-11-27 15:08:19 -0500320 }
khenaidoo67b22152020-03-02 16:01:25 -0500321 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500322}
323
Kent Hagerman2b216042020-04-03 18:28:56 -0400324func (nb *NBTest) getADevice(rootDevice bool, nbi *NBIHandler) (*voltha.Device, error) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500325 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
326 if err != nil {
327 return nil, err
328 }
329 for _, d := range devices.Items {
330 if d.Root == rootDevice {
331 return d, nil
332 }
333 }
334 return nil, status.Errorf(codes.NotFound, "%v device not found", rootDevice)
335}
336
Kent Hagerman2b216042020-04-03 18:28:56 -0400337func (nb *NBTest) testCoreWithoutData(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500338 lds, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
339 assert.Nil(t, err)
340 assert.NotNil(t, lds)
341 assert.Equal(t, 0, len(lds.Items))
342 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
343 assert.Nil(t, err)
344 assert.NotNil(t, devices)
345 assert.Equal(t, 0, len(devices.Items))
346 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
khenaidoo442e7c72020-03-10 16:13:48 -0400347 assert.Equal(t, 0, len(adapters.Items))
khenaidoob64fc8a2019-11-27 15:08:19 -0500348 assert.Nil(t, err)
349 assert.NotNil(t, adapters)
khenaidoob64fc8a2019-11-27 15:08:19 -0500350}
351
Kent Hagerman2b216042020-04-03 18:28:56 -0400352func (nb *NBTest) testAdapterRegistration(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500353 adapters, err := nbi.ListAdapters(getContext(), &empty.Empty{})
354 assert.Nil(t, err)
355 assert.NotNil(t, adapters)
356 assert.Equal(t, 2, len(adapters.Items))
357 for _, a := range adapters.Items {
358 switch a.Id {
359 case nb.oltAdapterName:
360 assert.Equal(t, "Voltha-olt", a.Vendor)
361 case nb.onuAdapterName:
362 assert.Equal(t, "Voltha-onu", a.Vendor)
363 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000364 logger.Fatal("unregistered-adapter", a.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500365 }
366 }
367 deviceTypes, err := nbi.ListDeviceTypes(getContext(), &empty.Empty{})
368 assert.Nil(t, err)
369 assert.NotNil(t, deviceTypes)
370 assert.Equal(t, 2, len(deviceTypes.Items))
371 for _, dt := range deviceTypes.Items {
372 switch dt.Id {
373 case nb.oltAdapterName:
374 assert.Equal(t, nb.oltAdapterName, dt.Adapter)
375 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
376 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
377 case nb.onuAdapterName:
378 assert.Equal(t, nb.onuAdapterName, dt.Adapter)
379 assert.Equal(t, false, dt.AcceptsBulkFlowUpdate)
380 assert.Equal(t, true, dt.AcceptsAddRemoveFlowUpdates)
381 default:
Girish Kumarf56a4682020-03-20 20:07:46 +0000382 logger.Fatal("invalid-device-type", dt.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500383 }
384 }
385}
386
Kent Hagerman2b216042020-04-03 18:28:56 -0400387func (nb *NBTest) testCreateDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500388 // Create a valid device
389 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
390 assert.Nil(t, err)
391 assert.NotNil(t, oltDevice)
392 device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
393 assert.Nil(t, err)
394 assert.NotNil(t, device)
395 assert.Equal(t, oltDevice.String(), device.String())
396
397 // Try to create the same device
398 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
399 assert.NotNil(t, err)
Kent Hagerman45a13e42020-04-13 12:23:50 -0400400 assert.Equal(t, "device is already pre-provisioned", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500401
402 // Try to create a device with invalid data
403 _, err = nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName})
404 assert.NotNil(t, err)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530405 assert.Equal(t, "no-device-info-present; MAC or HOSTIP&PORT", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500406
407 // Ensure we only have 1 device in the Core
408 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
409 assert.Nil(t, err)
410 assert.NotNil(t, devices)
411 assert.Equal(t, 1, len(devices.Items))
412 assert.Equal(t, oltDevice.String(), devices.Items[0].String())
413
414 //Remove the device
415 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
416 assert.Nil(t, err)
417
418 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
419 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
420 return devices != nil && len(devices.Items) == 0
421 }
khenaidoo442e7c72020-03-10 16:13:48 -0400422 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500423 assert.Nil(t, err)
424}
425
Kent Hagerman2b216042020-04-03 18:28:56 -0400426func (nb *NBTest) testEnableDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500427 // Create a device that has no adapter registered
428 oltDeviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegistered", MacAddress: "aa:bb:cc:cc:ee:ff"})
429 assert.Nil(t, err)
430 assert.NotNil(t, oltDeviceNoAdapter)
431
432 // Try to enable the oltDevice and check the error message
433 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
434 assert.NotNil(t, err)
Kent Hagerman45a13e42020-04-13 12:23:50 -0400435 assert.Equal(t, "adapter-not-registered-for-device-type noAdapterRegistered", err.Error())
khenaidoob64fc8a2019-11-27 15:08:19 -0500436
437 //Remove the device
438 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDeviceNoAdapter.Id})
439 assert.Nil(t, err)
440
441 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
442 var vdFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
443 return devices != nil && len(devices.Items) == 0
444 }
khenaidoo442e7c72020-03-10 16:13:48 -0400445 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vdFunction)
khenaidoob64fc8a2019-11-27 15:08:19 -0500446 assert.Nil(t, err)
447
khenaidoo67b22152020-03-02 16:01:25 -0500448 // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
449 var wg sync.WaitGroup
450 wg.Add(1)
451 go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg)
452
khenaidoob64fc8a2019-11-27 15:08:19 -0500453 // Create the device with valid data
454 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
455 assert.Nil(t, err)
456 assert.NotNil(t, oltDevice)
457
458 // Verify oltDevice exist in the core
459 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
460 assert.Nil(t, err)
461 assert.Equal(t, 1, len(devices.Items))
462 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
463
464 // Enable the oltDevice
465 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
466 assert.Nil(t, err)
467
468 // Wait for the logical device to be in the ready state
469 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
470 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
471 }
472 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
473 assert.Nil(t, err)
474
475 // Verify that the devices have been setup correctly
476 nb.verifyDevices(t, nbi)
477
478 // Get latest oltDevice data
479 oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
480 assert.Nil(t, err)
481
482 // Verify that the logical device has been setup correctly
483 nb.verifyLogicalDevices(t, oltDevice, nbi)
khenaidoo67b22152020-03-02 16:01:25 -0500484
485 // Wait until all flows has been sent to the devices successfully
486 wg.Wait()
khenaidoob64fc8a2019-11-27 15:08:19 -0500487}
488
Kent Hagerman2b216042020-04-03 18:28:56 -0400489func (nb *NBTest) testDisableAndReEnableRootDevice(t *testing.T, nbi *NBIHandler) {
khenaidoob64fc8a2019-11-27 15:08:19 -0500490 //Get an OLT device
491 oltDevice, err := nb.getADevice(true, nbi)
492 assert.Nil(t, err)
493 assert.NotNil(t, oltDevice)
494
495 // Disable the oltDevice
496 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
497 assert.Nil(t, err)
498
499 // Wait for the old device to be disabled
500 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
501 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
502 }
503 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
504 assert.Nil(t, err)
505
506 // Verify that all onu devices are disabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400507 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500508 assert.Nil(t, err)
509 for _, onu := range onuDevices.Items {
510 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
511 assert.Nil(t, err)
512 }
513
514 // Wait for the logical device to satisfy the expected condition
515 var vlFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500516 if ld == nil {
517 return false
518 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500519 for _, lp := range ld.Ports {
520 if (lp.OfpPort.Config&uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
521 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LINK_DOWN) {
522 return false
523 }
524 }
525 return true
526 }
527 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
528 assert.Nil(t, err)
529
530 // Reenable the oltDevice
531 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
532 assert.Nil(t, err)
533
534 // Wait for the old device to be enabled
535 vdFunction = func(device *voltha.Device) bool {
536 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
537 }
538 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
539 assert.Nil(t, err)
540
541 // Verify that all onu devices are enabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400542 onuDevices, err = nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoob64fc8a2019-11-27 15:08:19 -0500543 assert.Nil(t, err)
544 for _, onu := range onuDevices.Items {
545 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
546 assert.Nil(t, err)
547 }
548
549 // Wait for the logical device to satisfy the expected condition
550 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500551 if ld == nil {
552 return false
553 }
khenaidoob64fc8a2019-11-27 15:08:19 -0500554 for _, lp := range ld.Ports {
555 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
556 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
557 return false
558 }
559 }
560 return true
561 }
562 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
563 assert.Nil(t, err)
564}
565
Kent Hagerman2b216042020-04-03 18:28:56 -0400566func (nb *NBTest) testDisableAndDeleteAllDevice(t *testing.T, nbi *NBIHandler) {
khenaidoo93d5a3d2020-01-15 12:37:05 -0500567 //Get an OLT device
568 oltDevice, err := nb.getADevice(true, nbi)
569 assert.Nil(t, err)
570 assert.NotNil(t, oltDevice)
571
572 // Disable the oltDevice
573 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
574 assert.Nil(t, err)
575
576 // Wait for the olt device to be disabled
577 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
578 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
579 }
580 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
581 assert.Nil(t, err)
582
583 // Verify that all onu devices are disabled as well
Kent Hagerman2b216042020-04-03 18:28:56 -0400584 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
khenaidoo93d5a3d2020-01-15 12:37:05 -0500585 assert.Nil(t, err)
586 for _, onu := range onuDevices.Items {
587 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
588 assert.Nil(t, err)
589 }
590
591 // Delete the oltDevice
592 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
593 assert.Nil(t, err)
594
595 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
596 return devices != nil && len(devices.Items) == 0
597 }
598 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
599 assert.Nil(t, err)
600
601 // Wait for absence of logical device
602 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
603 return lds != nil && len(lds.Items) == 0
604 }
605
606 err = waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
607 assert.Nil(t, err)
608}
Kent Hagerman2b216042020-04-03 18:28:56 -0400609func (nb *NBTest) testEnableAndDeleteAllDevice(t *testing.T, nbi *NBIHandler) {
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500610 //Create the device with valid data
611 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
612 assert.Nil(t, err)
613 assert.NotNil(t, oltDevice)
614
615 //Get an OLT device
616 oltDevice, err = nb.getADevice(true, nbi)
617 assert.Nil(t, err)
618 assert.NotNil(t, oltDevice)
619
620 // Enable the oltDevice
621 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
622 assert.Nil(t, err)
623
624 // Wait for the logical device to be in the ready state
625 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
626 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
627 }
628 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
629 assert.Nil(t, err)
630
631 //Get all child devices
Kent Hagerman2b216042020-04-03 18:28:56 -0400632 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500633 assert.Nil(t, err)
634
635 // Wait for the all onu devices to be enabled
636 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
637 return device.AdminState == voltha.AdminState_ENABLED
638 }
639 for _, onu := range onuDevices.Items {
640 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunction, nbi)
641 assert.Nil(t, err)
642 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500643 // Wait for each onu device to get deleted
644 var vdFunc isDeviceConditionSatisfied = func(device *voltha.Device) bool {
645 return device == nil
646 }
647
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500648 // Delete the onuDevice
649 for _, onu := range onuDevices.Items {
650 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: onu.Id})
651 assert.Nil(t, err)
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500652 err = waitUntilDeviceReadiness(onu.Id, nb.maxTimeout, vdFunc, nbi)
653 assert.Nil(t, err)
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500654 }
Chaitrashree G Se8ad0202020-02-27 18:48:00 -0500655
Chaitrashree G S543df3e2020-02-24 22:36:54 -0500656 // Disable the oltDevice
657 _, err = nbi.DisableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
658 assert.Nil(t, err)
659
660 // Wait for the olt device to be disabled
661 var vFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
662 return device.AdminState == voltha.AdminState_DISABLED && device.OperStatus == voltha.OperStatus_UNKNOWN
663 }
664 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vFunction, nbi)
665 assert.Nil(t, err)
666
667 // Delete the oltDevice
668 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
669 assert.Nil(t, err)
670
671 var vFunc isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
672 return devices != nil && len(devices.Items) == 0
673 }
674 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunc)
675 assert.Nil(t, err)
676}
Kent Hagerman2b216042020-04-03 18:28:56 -0400677func (nb *NBTest) testDisableAndEnablePort(t *testing.T, nbi *NBIHandler) {
kesavandbc2d1622020-01-21 00:42:01 -0500678 //Get an OLT device
679 var cp *voltha.Port
680 oltDevice, err := nb.getADevice(true, nbi)
681 assert.Nil(t, err)
682 assert.NotNil(t, oltDevice)
683
684 for _, cp = range oltDevice.Ports {
685 if cp.Type == voltha.Port_PON_OLT {
686 break
687 }
688
689 }
690 assert.NotNil(t, cp)
691 cp.DeviceId = oltDevice.Id
692
693 // Disable the NW Port of oltDevice
694 _, err = nbi.DisablePort(getContext(), cp)
695 assert.Nil(t, err)
696 // Wait for the olt device Port to be disabled
697 var vdFunction isDeviceConditionSatisfied = func(device *voltha.Device) bool {
698 for _, port := range device.Ports {
699 if port.PortNo == cp.PortNo {
700 return port.AdminState == voltha.AdminState_DISABLED
701 }
702 }
703 return false
704 }
705 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
706 assert.Nil(t, err)
707 // Wait for the logical device to satisfy the expected condition
708 var vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500709 if ld == nil {
710 return false
711 }
kesavandbc2d1622020-01-21 00:42:01 -0500712 for _, lp := range ld.Ports {
713 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
714 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
715 return false
716 }
717 }
718 return true
719 }
720 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
721 assert.Nil(t, err)
722
723 // Enable the NW Port of oltDevice
724 _, err = nbi.EnablePort(getContext(), cp)
725 assert.Nil(t, err)
726
727 // Wait for the olt device Port to be enabled
728 vdFunction = func(device *voltha.Device) bool {
729 for _, port := range device.Ports {
730 if port.PortNo == cp.PortNo {
731 return port.AdminState == voltha.AdminState_ENABLED
732 }
733 }
734 return false
735 }
736 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
737 assert.Nil(t, err)
738 // Wait for the logical device to satisfy the expected condition
739 vlFunction = func(ld *voltha.LogicalDevice) bool {
khenaidoo67b22152020-03-02 16:01:25 -0500740 if ld == nil {
741 return false
742 }
kesavandbc2d1622020-01-21 00:42:01 -0500743 for _, lp := range ld.Ports {
744 if (lp.OfpPort.Config&^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN) != lp.OfpPort.Config) ||
745 lp.OfpPort.State != uint32(ofp.OfpPortState_OFPPS_LIVE) {
746 return false
747 }
748 }
749 return true
750 }
751 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction)
752 assert.Nil(t, err)
753
754 // Disable a non-PON port
755 for _, cp = range oltDevice.Ports {
756 if cp.Type != voltha.Port_PON_OLT {
757 break
758 }
759
760 }
761 assert.NotNil(t, cp)
762 cp.DeviceId = oltDevice.Id
763
764 // Disable the NW Port of oltDevice
765 _, err = nbi.DisablePort(getContext(), cp)
766 assert.NotNil(t, err)
767
768}
khenaidoo93d5a3d2020-01-15 12:37:05 -0500769
Kent Hagerman2b216042020-04-03 18:28:56 -0400770func (nb *NBTest) testDeviceRebootWhenOltIsEnabled(t *testing.T, nbi *NBIHandler) {
Girish Gowdra408cd962020-03-11 14:31:31 -0700771 //Get an OLT device
772 oltDevice, err := nb.getADevice(true, nbi)
773 assert.Nil(t, err)
774 assert.NotNil(t, oltDevice)
775 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
776 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
777
778 // Verify that we have one or more ONUs to start with
Kent Hagerman2b216042020-04-03 18:28:56 -0400779 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Girish Gowdra408cd962020-03-11 14:31:31 -0700780 assert.Nil(t, err)
781 assert.NotNil(t, onuDevices)
782 assert.Greater(t, len(onuDevices.Items), 0)
783
784 // Reboot the OLT and very that Connection Status goes to UNREACHABLE and operation status to UNKNOWN
785 _, err = nbi.RebootDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
786 assert.Nil(t, err)
787
788 var vlFunction0 = func(d *voltha.Device) bool {
789 return d.ConnectStatus == voltha.ConnectStatus_UNREACHABLE && d.OperStatus == voltha.OperStatus_UNKNOWN
790 }
791
792 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction0, nbi)
793 assert.Nil(t, err)
794
795 // Wait for the logical device to satisfy the expected condition
796 var vlFunction1 = func(ld *voltha.LogicalDevice) bool {
797 return ld == nil
798 }
799
800 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction1)
801 assert.Nil(t, err)
802
803 // Wait for the device to satisfy the expected condition (device does not have flows)
804 var vlFunction2 = func(d *voltha.Device) bool {
805 var deviceFlows *ofp.Flows
806 var err error
807 if deviceFlows, err = nbi.ListDeviceFlows(getContext(), &voltha.ID{Id: d.Id}); err != nil {
808 return false
809 }
810 return len(deviceFlows.Items) == 0
811 }
812
813 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction2, nbi)
814 assert.Nil(t, err)
815
816 // Wait for the device to satisfy the expected condition (there are no child devices)
817 var vlFunction3 = func(d *voltha.Device) bool {
818 var devices *voltha.Devices
819 var err error
820 if devices, err = nbi.ListDevices(getContext(), nil); err != nil {
821 return false
822 }
823 for _, device := range devices.Items {
824 if device.ParentId == d.Id {
825 // We have a child device still left
826 return false
827 }
828 }
829 return true
830 }
831
832 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vlFunction3, nbi)
833 assert.Nil(t, err)
834
835 // Update the OLT Connection Status to REACHABLE and operation status to ACTIVE
836 // Normally, in a real adapter this happens after connection regain via a heartbeat mechanism with real hardware
Kent Hagerman45a13e42020-04-13 12:23:50 -0400837 err = nbi.UpdateDeviceStatus(getContext(), oltDevice.Id, voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
Girish Gowdra408cd962020-03-11 14:31:31 -0700838 assert.Nil(t, err)
839
840 // Verify the device connection and operation states
841 oltDevice, err = nb.getADevice(true, nbi)
842 assert.Nil(t, err)
843 assert.NotNil(t, oltDevice)
844 assert.Equal(t, oltDevice.ConnectStatus, voltha.ConnectStatus_REACHABLE)
845 assert.Equal(t, oltDevice.AdminState, voltha.AdminState_ENABLED)
846
847 // Wait for the logical device to satisfy the expected condition
848 var vlFunction4 = func(ld *voltha.LogicalDevice) bool {
849 return ld != nil
850 }
851 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vlFunction4)
852 assert.Nil(t, err)
853
854 // Verify that logical device is created again
855 logicalDevices, err := nbi.ListLogicalDevices(getContext(), &empty.Empty{})
856 assert.Nil(t, err)
857 assert.NotNil(t, logicalDevices)
858 assert.Equal(t, 1, len(logicalDevices.Items))
859
860 // Verify that we have no ONUs left
Kent Hagerman2b216042020-04-03 18:28:56 -0400861 onuDevices, err = nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Girish Gowdra408cd962020-03-11 14:31:31 -0700862 assert.Nil(t, err)
863 assert.NotNil(t, onuDevices)
864 assert.Equal(t, 0, len(onuDevices.Items))
865}
866
Kent Hagerman2b216042020-04-03 18:28:56 -0400867func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi *NBIHandler) {
Scott Baker432f9be2020-03-26 11:56:30 -0700868 // -----------------------------------------------------------------------
869 // SubTest 1: Omci test action should fail due to nonexistent device id
870
871 request := &voltha.OmciTestRequest{Id: "123", Uuid: "456"}
872 _, err := nbi.StartOmciTestAction(getContext(), request)
873 assert.NotNil(t, err)
874 assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
875
876 // -----------------------------------------------------------------------
877 // SubTest 2: Error should be returned for device with no adapter registered
878
879 // Create a device that has no adapter registered
880 deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: "aa:bb:cc:cc:ee:01"})
881 assert.Nil(t, err)
882 assert.NotNil(t, deviceNoAdapter)
883
884 // Omci test action should fail due to nonexistent adapter
885 request = &voltha.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
886 _, err = nbi.StartOmciTestAction(getContext(), request)
887 assert.NotNil(t, err)
Kent Hagerman45a13e42020-04-13 12:23:50 -0400888 assert.Equal(t, "adapter-not-registered-for-device-type noAdapterRegisteredOmciTest", err.Error())
Scott Baker432f9be2020-03-26 11:56:30 -0700889
890 //Remove the device
891 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
892 assert.Nil(t, err)
893
894 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
895 var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
896 return devices != nil && len(devices.Items) == 0
897 }
898 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
899 assert.Nil(t, err)
900
901 // -----------------------------------------------------------------------
902 // SubTest 3: Omci test action should succeed on valid ONU
903
904 // Create the device with valid data
905 oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
906 assert.Nil(t, err)
907 assert.NotNil(t, oltDevice)
908
909 // Verify oltDevice exist in the core
910 devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
911 assert.Nil(t, err)
912 assert.Equal(t, 1, len(devices.Items))
913 assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
914
915 // Enable the oltDevice
916 _, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
917 assert.Nil(t, err)
918
919 // Wait for the logical device to be in the ready state
920 var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
921 return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
922 }
923 err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
924 assert.Nil(t, err)
925
926 // Wait for the olt device to be enabled
927 vdFunction := func(device *voltha.Device) bool {
928 return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
929 }
930 err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
931 assert.Nil(t, err)
932
Kent Hagerman2b216042020-04-03 18:28:56 -0400933 onuDevices, err := nb.deviceMgr.GetAllChildDevices(getContext(), oltDevice.Id)
Scott Baker432f9be2020-03-26 11:56:30 -0700934 assert.Nil(t, err)
935 assert.Greater(t, len(onuDevices.Items), 0)
936
937 onuDevice := onuDevices.Items[0]
938
939 // Omci test action should succeed
940 request = &voltha.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
941 resp, err := nbi.StartOmciTestAction(getContext(), request)
942 assert.Nil(t, err)
943 assert.Equal(t, resp.Result, voltha.TestResponse_SUCCESS)
944
945 //Remove the device
946 _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
947 assert.Nil(t, err)
948 //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
949 err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
950 assert.Nil(t, err)
951}
952
khenaidoo67b22152020-03-02 16:01:25 -0500953func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
954 matchFields := make([]*ofp.OfpOxmField, 0)
955 for _, val := range fa.MatchFields {
956 matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
957 }
958 return flows.MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV)
959}
960
961func createMetadata(cTag int, techProfile int, port int) uint64 {
962 md := 0
963 md = (md | (cTag & 0xFFFF)) << 16
964 md = (md | (techProfile & 0xFFFF)) << 32
965 return uint64(md | (port & 0xFFFFFFFF))
966}
967
Kent Hagerman2b216042020-04-03 18:28:56 -0400968func (nb *NBTest) verifyLogicalDeviceFlowCount(t *testing.T, nbi *NBIHandler, numNNIPorts int, numUNIPorts int) {
khenaidoo67b22152020-03-02 16:01:25 -0500969 expectedNumFlows := numNNIPorts*3 + numNNIPorts*numUNIPorts
970 // Wait for logical device to have all the flows
971 var vlFunction isLogicalDevicesConditionSatisfied = func(lds *voltha.LogicalDevices) bool {
972 return lds != nil && len(lds.Items) == 1 && len(lds.Items[0].Flows.Items) == expectedNumFlows
973 }
974 // No timeout implies a success
975 err := waitUntilConditionForLogicalDevices(nb.maxTimeout, nbi, vlFunction)
976 assert.Nil(t, err)
977}
978
Kent Hagerman2b216042020-04-03 18:28:56 -0400979func (nb *NBTest) sendTrapFlows(t *testing.T, nbi *NBIHandler, logicalDevice *voltha.LogicalDevice, meterID uint64, startingVlan int) (numNNIPorts, numUNIPorts int) {
khenaidoo67b22152020-03-02 16:01:25 -0500980 // Send flows for the parent device
981 var nniPorts []*voltha.LogicalPort
982 var uniPorts []*voltha.LogicalPort
983 for _, p := range logicalDevice.Ports {
984 if p.RootPort {
985 nniPorts = append(nniPorts, p)
986 } else {
987 uniPorts = append(uniPorts, p)
988 }
989 }
990 assert.Equal(t, 1, len(nniPorts))
991 //assert.Greater(t, len(uniPorts), 1 )
992 nniPort := nniPorts[0].OfpPort.PortNo
993 maxInt32 := uint64(0xFFFFFFFF)
994 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
995 var fa *flows.FlowArgs
996 fa = &flows.FlowArgs{
997 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
998 MatchFields: []*ofp.OfpOxmOfbField{
999 flows.InPort(nniPort),
1000 flows.EthType(35020),
1001 },
1002 Actions: []*ofp.OfpAction{
1003 flows.Output(controllerPortMask),
1004 },
1005 }
1006 flowLLDP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1007 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowLLDP)
1008 assert.Nil(t, err)
1009
1010 fa = &flows.FlowArgs{
1011 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1012 MatchFields: []*ofp.OfpOxmOfbField{
1013 flows.InPort(nniPort),
1014 flows.EthType(2048),
1015 flows.IpProto(17),
1016 flows.UdpSrc(67),
1017 flows.UdpDst(68),
1018 },
1019 Actions: []*ofp.OfpAction{
1020 flows.Output(controllerPortMask),
1021 },
1022 }
1023 flowIPV4 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1024 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV4)
1025 assert.Nil(t, err)
1026
1027 fa = &flows.FlowArgs{
1028 KV: flows.OfpFlowModArgs{"priority": 10000, "buffer_id": maxInt32, "out_port": maxInt32, "out_group": maxInt32, "flags": 1},
1029 MatchFields: []*ofp.OfpOxmOfbField{
1030 flows.InPort(nniPort),
1031 flows.EthType(34525),
1032 flows.IpProto(17),
1033 flows.UdpSrc(546),
1034 flows.UdpDst(547),
1035 },
1036 Actions: []*ofp.OfpAction{
1037 flows.Output(controllerPortMask),
1038 },
1039 }
1040 flowIPV6 := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDevice.Id}
1041 _, err = nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowIPV6)
1042 assert.Nil(t, err)
1043
1044 return len(nniPorts), len(uniPorts)
1045}
1046
Kent Hagerman2b216042020-04-03 18:28:56 -04001047func (nb *NBTest) sendEAPFlows(t *testing.T, nbi *NBIHandler, logicalDeviceID string, port *ofp.OfpPort, vlan int, meterID uint64) {
khenaidoo67b22152020-03-02 16:01:25 -05001048 maxInt32 := uint64(0xFFFFFFFF)
1049 controllerPortMask := uint32(4294967293) // will result in 4294967293&0x7fffffff => 2147483645 which is the actual controller port
1050 fa := &flows.FlowArgs{
1051 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},
1052 MatchFields: []*ofp.OfpOxmOfbField{
1053 flows.InPort(port.PortNo),
1054 flows.EthType(34958),
1055 flows.VlanVid(8187),
1056 },
1057 Actions: []*ofp.OfpAction{
1058 flows.Output(controllerPortMask),
1059 },
1060 }
1061 flowEAP := ofp.FlowTableUpdate{FlowMod: makeSimpleFlowMod(fa), Id: logicalDeviceID}
1062 _, err := nbi.UpdateLogicalDeviceFlowTable(getContext(), &flowEAP)
1063 assert.Nil(t, err)
1064}
1065
Kent Hagerman2b216042020-04-03 18:28:56 -04001066func (nb *NBTest) monitorLogicalDevice(t *testing.T, nbi *NBIHandler, numNNIPorts int, numUNIPorts int, wg *sync.WaitGroup) {
khenaidoo67b22152020-03-02 16:01:25 -05001067 defer wg.Done()
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
Kent Hagerman45a13e42020-04-13 12:23:50 -04001127 for event := range nbi.GetChangeEventsQueueForTest() {
khenaidoo67b22152020-03-02 16:01:25 -05001128 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 Hagerman45a13e42020-04-13 12:23:50 -04001188 nbi := NewNBIHandler(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}