blob: 2e1b1d319be71b444416cb0003c9ef0fea0d7d46 [file] [log] [blame]
khenaidoo2bc48282019-07-16 18:13:46 -04001/*
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 device
khenaidoo2bc48282019-07-16 18:13:46 -040017
18import (
khenaidoo6e55d9e2019-12-12 18:26:26 -050019 "context"
David Bainbridged1afd662020-03-26 18:27:41 -070020 "math/rand"
Neha Sharmad1387da2020-05-07 20:07:28 +000021 "strconv"
David Bainbridged1afd662020-03-26 18:27:41 -070022 "sync"
23 "testing"
24 "time"
25
Kent Hagermanf5a67352020-04-30 15:15:26 -040026 "github.com/gogo/protobuf/proto"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070027 "github.com/opencord/voltha-go/db/model"
Kent Hagermanf5a67352020-04-30 15:15:26 -040028 "github.com/opencord/voltha-go/rw_core/config"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070029 "github.com/opencord/voltha-go/rw_core/core/adapter"
Mahir Gunyel03de0d32020-06-03 01:36:59 -070030 tst "github.com/opencord/voltha-go/rw_core/test"
Kent Hagermanf5a67352020-04-30 15:15:26 -040031 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070032 "github.com/opencord/voltha-lib-go/v3/pkg/db"
33 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080034 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
Matteo Scandolod525ae32020-04-02 17:27:29 -070035 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
36 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080037 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
38 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo6e55d9e2019-12-12 18:26:26 -050039 "github.com/phayes/freeport"
khenaidoo2bc48282019-07-16 18:13:46 -040040 "github.com/stretchr/testify/assert"
khenaidoo2bc48282019-07-16 18:13:46 -040041)
42
43func TestLogicalDeviceAgent_diff_nochange_1(t *testing.T) {
44 currentLogicalPorts := []*voltha.LogicalPort{}
45 updatedLogicalPorts := []*voltha.LogicalPort{}
46 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
47 assert.Equal(t, 0, len(newPorts))
48 assert.Equal(t, 0, len(changedPorts))
49 assert.Equal(t, 0, len(deletedPorts))
50}
51
52func TestLogicalDeviceAgent_diff_nochange_2(t *testing.T) {
53 currentLogicalPorts := []*voltha.LogicalPort{
54 {
55 Id: "1231",
56 DeviceId: "d1234",
57 DevicePortNo: 1,
58 RootPort: true,
59 OfpPort: &ofp.OfpPort{
60 PortNo: 1,
61 Name: "port1",
62 Config: 1,
63 State: 1,
64 },
65 },
66 {
67 Id: "1232",
68 DeviceId: "d1234",
69 DevicePortNo: 2,
70 RootPort: false,
71 OfpPort: &ofp.OfpPort{
72 PortNo: 2,
73 Name: "port2",
74 Config: 1,
75 State: 1,
76 },
77 },
78 {
79 Id: "1233",
80 DeviceId: "d1234",
81 DevicePortNo: 3,
82 RootPort: false,
83 OfpPort: &ofp.OfpPort{
84 PortNo: 3,
85 Name: "port3",
86 Config: 1,
87 State: 1,
88 },
89 },
90 }
91 updatedLogicalPorts := []*voltha.LogicalPort{
92 {
93 Id: "1231",
94 DeviceId: "d1234",
95 DevicePortNo: 1,
96 RootPort: true,
97 OfpPort: &ofp.OfpPort{
98 PortNo: 1,
99 Name: "port1",
100 Config: 1,
101 State: 1,
102 },
103 },
104 {
105 Id: "1232",
106 DeviceId: "d1234",
107 DevicePortNo: 2,
108 RootPort: false,
109 OfpPort: &ofp.OfpPort{
110 PortNo: 2,
111 Name: "port2",
112 Config: 1,
113 State: 1,
114 },
115 },
116 {
117 Id: "1233",
118 DeviceId: "d1234",
119 DevicePortNo: 3,
120 RootPort: false,
121 OfpPort: &ofp.OfpPort{
122 PortNo: 3,
123 Name: "port3",
124 Config: 1,
125 State: 1,
126 },
127 },
128 }
129 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
130 assert.Equal(t, 0, len(newPorts))
131 assert.Equal(t, 0, len(changedPorts))
132 assert.Equal(t, 0, len(deletedPorts))
133}
134
135func TestLogicalDeviceAgent_diff_add(t *testing.T) {
136 currentLogicalPorts := []*voltha.LogicalPort{}
137 updatedLogicalPorts := []*voltha.LogicalPort{
138 {
139 Id: "1231",
140 DeviceId: "d1234",
141 DevicePortNo: 1,
142 RootPort: true,
143 OfpPort: &ofp.OfpPort{
144 PortNo: 1,
145 Name: "port1",
146 Config: 1,
147 State: 1,
148 },
149 },
150 {
151 Id: "1232",
152 DeviceId: "d1234",
153 DevicePortNo: 2,
154 RootPort: true,
155 OfpPort: &ofp.OfpPort{
156 PortNo: 2,
157 Name: "port2",
158 Config: 1,
159 State: 1,
160 },
161 },
162 }
163 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
164 assert.Equal(t, 2, len(newPorts))
165 assert.Equal(t, 0, len(changedPorts))
166 assert.Equal(t, 0, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400167 assert.Equal(t, updatedLogicalPorts[0], newPorts[updatedLogicalPorts[0].Id])
168 assert.Equal(t, updatedLogicalPorts[1], newPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400169}
170
171func TestLogicalDeviceAgent_diff_delete(t *testing.T) {
172 currentLogicalPorts := []*voltha.LogicalPort{
173 {
174 Id: "1231",
175 DeviceId: "d1234",
176 DevicePortNo: 1,
177 RootPort: true,
178 OfpPort: &ofp.OfpPort{
179 PortNo: 1,
180 Name: "port1",
181 Config: 1,
182 State: 1,
183 },
184 },
185 }
186 updatedLogicalPorts := []*voltha.LogicalPort{}
187 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
188 assert.Equal(t, 0, len(newPorts))
189 assert.Equal(t, 0, len(changedPorts))
190 assert.Equal(t, 1, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400191 assert.Equal(t, currentLogicalPorts[0], deletedPorts[currentLogicalPorts[0].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400192}
193
194func TestLogicalDeviceAgent_diff_changed(t *testing.T) {
195 currentLogicalPorts := []*voltha.LogicalPort{
196 {
197 Id: "1231",
198 DeviceId: "d1234",
199 DevicePortNo: 1,
200 RootPort: true,
201 OfpPort: &ofp.OfpPort{
202 PortNo: 1,
203 Name: "port1",
204 Config: 1,
205 State: 1,
206 },
207 },
208 {
209 Id: "1232",
210 DeviceId: "d1234",
211 DevicePortNo: 2,
212 RootPort: false,
213 OfpPort: &ofp.OfpPort{
214 PortNo: 2,
215 Name: "port2",
216 Config: 1,
217 State: 1,
218 },
219 },
220 {
221 Id: "1233",
222 DeviceId: "d1234",
223 DevicePortNo: 3,
224 RootPort: false,
225 OfpPort: &ofp.OfpPort{
226 PortNo: 3,
227 Name: "port3",
228 Config: 1,
229 State: 1,
230 },
231 },
232 }
233 updatedLogicalPorts := []*voltha.LogicalPort{
234 {
235 Id: "1231",
236 DeviceId: "d1234",
237 DevicePortNo: 1,
238 RootPort: true,
239 OfpPort: &ofp.OfpPort{
240 PortNo: 1,
241 Name: "port1",
242 Config: 4,
243 State: 4,
244 },
245 },
246 {
247 Id: "1232",
248 DeviceId: "d1234",
249 DevicePortNo: 2,
250 RootPort: false,
251 OfpPort: &ofp.OfpPort{
252 PortNo: 2,
253 Name: "port2",
254 Config: 4,
255 State: 4,
256 },
257 },
258 {
259 Id: "1233",
260 DeviceId: "d1234",
261 DevicePortNo: 3,
262 RootPort: false,
263 OfpPort: &ofp.OfpPort{
264 PortNo: 3,
265 Name: "port3",
266 Config: 1,
267 State: 1,
268 },
269 },
270 }
271 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
272 assert.Equal(t, 0, len(newPorts))
273 assert.Equal(t, 2, len(changedPorts))
274 assert.Equal(t, 0, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400275 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
276 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400277}
278
279func TestLogicalDeviceAgent_diff_mix(t *testing.T) {
280 currentLogicalPorts := []*voltha.LogicalPort{
281 {
282 Id: "1231",
283 DeviceId: "d1234",
284 DevicePortNo: 1,
285 RootPort: true,
286 OfpPort: &ofp.OfpPort{
287 PortNo: 1,
288 Name: "port1",
289 Config: 1,
290 State: 1,
291 },
292 },
293 {
294 Id: "1232",
295 DeviceId: "d1234",
296 DevicePortNo: 2,
297 RootPort: false,
298 OfpPort: &ofp.OfpPort{
299 PortNo: 2,
300 Name: "port2",
301 Config: 1,
302 State: 1,
303 },
304 },
305 {
306 Id: "1233",
307 DeviceId: "d1234",
308 DevicePortNo: 3,
309 RootPort: false,
310 OfpPort: &ofp.OfpPort{
311 PortNo: 3,
312 Name: "port3",
313 Config: 1,
314 State: 1,
315 },
316 },
317 }
318 updatedLogicalPorts := []*voltha.LogicalPort{
319 {
320 Id: "1231",
321 DeviceId: "d1234",
322 DevicePortNo: 1,
323 RootPort: true,
324 OfpPort: &ofp.OfpPort{
325 PortNo: 1,
326 Name: "port1",
327 Config: 4,
328 State: 4,
329 },
330 },
331 {
332 Id: "1232",
333 DeviceId: "d1234",
334 DevicePortNo: 2,
335 RootPort: false,
336 OfpPort: &ofp.OfpPort{
337 PortNo: 2,
338 Name: "port2",
339 Config: 4,
340 State: 4,
341 },
342 },
343 {
344 Id: "1234",
345 DeviceId: "d1234",
346 DevicePortNo: 4,
347 RootPort: false,
348 OfpPort: &ofp.OfpPort{
349 PortNo: 4,
350 Name: "port4",
351 Config: 4,
352 State: 4,
353 },
354 },
355 }
356 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
357 assert.Equal(t, 1, len(newPorts))
358 assert.Equal(t, 2, len(changedPorts))
359 assert.Equal(t, 1, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400360 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
361 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
362 assert.Equal(t, currentLogicalPorts[2], deletedPorts[currentLogicalPorts[2].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400363}
khenaidoo6e55d9e2019-12-12 18:26:26 -0500364
365type LDATest struct {
Kent Hagerman2b216042020-04-03 18:28:56 -0400366 etcdServer *mock_etcd.EtcdServer
367 deviceMgr *Manager
368 kmp kafka.InterContainerProxy
369 logicalDeviceMgr *LogicalManager
370 kClient kafka.Client
371 kvClientPort int
372 oltAdapterName string
373 onuAdapterName string
374 coreInstanceID string
375 defaultTimeout time.Duration
376 maxTimeout time.Duration
377 logicalDevice *voltha.LogicalDevice
378 deviceIds []string
379 done chan int
khenaidoo6e55d9e2019-12-12 18:26:26 -0500380}
381
382func newLDATest() *LDATest {
383 test := &LDATest{}
384 // Start the embedded etcd server
385 var err error
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700386 test.etcdServer, test.kvClientPort, err = tst.StartEmbeddedEtcdServer("voltha.rwcore.lda.test", "voltha.rwcore.lda.etcd", "error")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500387 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000388 logger.Fatal(err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500389 }
390 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -0700391 test.kClient = mock_kafka.NewKafkaClient()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500392 test.oltAdapterName = "olt_adapter_mock"
393 test.onuAdapterName = "onu_adapter_mock"
394 test.coreInstanceID = "rw-da-test"
395 test.defaultTimeout = 5 * time.Second
396 test.maxTimeout = 20 * time.Second
397 test.done = make(chan int)
398 test.deviceIds = []string{com.GetRandomString(10), com.GetRandomString(10), com.GetRandomString(10)}
399 test.logicalDevice = &voltha.LogicalDevice{
400 Desc: &ofp.OfpDesc{
401 HwDesc: "olt_adapter_mock",
402 SwDesc: "olt_adapter_mock",
403 SerialNum: com.GetRandomSerialNumber(),
404 },
405 SwitchFeatures: &ofp.OfpSwitchFeatures{
406 NBuffers: 256,
407 NTables: 2,
408 Capabilities: uint32(ofp.OfpCapabilities_OFPC_FLOW_STATS |
409 ofp.OfpCapabilities_OFPC_TABLE_STATS |
410 ofp.OfpCapabilities_OFPC_PORT_STATS |
411 ofp.OfpCapabilities_OFPC_GROUP_STATS),
412 },
413 RootDeviceId: test.deviceIds[0],
414 Ports: []*voltha.LogicalPort{
415 {
416 Id: "1001",
417 DeviceId: test.deviceIds[0],
418 DevicePortNo: 1,
419 RootPort: true,
420 OfpPort: &ofp.OfpPort{
421 PortNo: 1,
422 Name: "port1",
423 Config: 4,
424 State: 4,
425 },
426 },
427 {
428 Id: "1002",
429 DeviceId: test.deviceIds[1],
430 DevicePortNo: 2,
431 RootPort: false,
432 OfpPort: &ofp.OfpPort{
433 PortNo: 2,
434 Name: "port2",
435 Config: 4,
436 State: 4,
437 },
438 },
439 {
440 Id: "1003",
441 DeviceId: test.deviceIds[2],
442 DevicePortNo: 3,
443 RootPort: false,
444 OfpPort: &ofp.OfpPort{
445 PortNo: 4,
446 Name: "port3",
447 Config: 4,
448 State: 4,
449 },
450 },
451 },
452 }
453 return test
454}
455
456func (lda *LDATest) startCore(inCompeteMode bool) {
457 cfg := config.NewRWCoreFlags()
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700458 cfg.CoreTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -0400459 cfg.DefaultRequestTimeout = lda.defaultTimeout
Neha Sharmad1387da2020-05-07 20:07:28 +0000460 cfg.KVStoreAddress = "127.0.0.1" + ":" + strconv.Itoa(lda.kvClientPort)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500461 cfg.InCompetingMode = inCompeteMode
462 grpcPort, err := freeport.GetFreePort()
463 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000464 logger.Fatal("Cannot get a freeport for grpc")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500465 }
Neha Sharmad1387da2020-05-07 20:07:28 +0000466 cfg.GrpcAddress = "127.0.0.1" + ":" + strconv.Itoa(grpcPort)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700467 client := tst.SetupKVClient(cfg, lda.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400468 backend := &db.Backend{
469 Client: client,
470 StoreType: cfg.KVStoreType,
Neha Sharmad1387da2020-05-07 20:07:28 +0000471 Address: cfg.KVStoreAddress,
Kent Hagerman2b216042020-04-03 18:28:56 -0400472 Timeout: cfg.KVStoreTimeout,
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700473 LivenessChannelInterval: cfg.LiveProbeInterval / 2}
Kent Hagerman2b216042020-04-03 18:28:56 -0400474 lda.kmp = kafka.NewInterContainerProxy(
Neha Sharmad1387da2020-05-07 20:07:28 +0000475 kafka.InterContainerAddress(cfg.KafkaAdapterAddress),
Kent Hagerman2b216042020-04-03 18:28:56 -0400476 kafka.MsgClient(lda.kClient),
477 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}),
478 kafka.DeviceDiscoveryTopic(&kafka.Topic{Name: cfg.AffinityRouterTopic}))
479
480 endpointMgr := kafka.NewEndpointManager(backend)
Kent Hagermanf5a67352020-04-30 15:15:26 -0400481 proxy := model.NewDBPath(backend)
Kent Hagerman2b216042020-04-03 18:28:56 -0400482 adapterMgr := adapter.NewAdapterManager(proxy, lda.coreInstanceID, lda.kClient)
483
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700484 lda.deviceMgr, lda.logicalDeviceMgr = NewManagers(proxy, adapterMgr, lda.kmp, endpointMgr, cfg.CoreTopic, lda.coreInstanceID, cfg.DefaultCoreTimeout)
Kent Hagerman2b216042020-04-03 18:28:56 -0400485 if err = lda.kmp.Start(); err != nil {
486 logger.Fatal("Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530487 }
Kent Hagerman2f0d0552020-04-23 17:28:52 -0400488 adapterMgr.Start(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500489}
490
491func (lda *LDATest) stopAll() {
492 if lda.kClient != nil {
493 lda.kClient.Stop()
494 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400495 if lda.kmp != nil {
496 lda.kmp.Stop()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500497 }
498 if lda.etcdServer != nil {
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700499 tst.StopEmbeddedEtcdServer(lda.etcdServer)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500500 }
501}
502
Kent Hagerman2b216042020-04-03 18:28:56 -0400503func (lda *LDATest) createLogicalDeviceAgent(t *testing.T) *LogicalAgent {
504 lDeviceMgr := lda.logicalDeviceMgr
505 deviceMgr := lda.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500506 clonedLD := proto.Clone(lda.logicalDevice).(*voltha.LogicalDevice)
507 clonedLD.Id = com.GetRandomString(10)
508 clonedLD.DatapathId = rand.Uint64()
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700509 lDeviceAgent := newLogicalAgent(clonedLD.Id, clonedLD.Id, clonedLD.RootDeviceId, lDeviceMgr, deviceMgr, lDeviceMgr.dbPath, lDeviceMgr.ldProxy, lDeviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500510 lDeviceAgent.logicalDevice = clonedLD
Kent Hagermanf5a67352020-04-30 15:15:26 -0400511 err := lDeviceAgent.ldProxy.Set(context.Background(), clonedLD.Id, clonedLD)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530512 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500513 lDeviceMgr.addLogicalDeviceAgentToMap(lDeviceAgent)
514 return lDeviceAgent
515}
516
Kent Hagerman2b216042020-04-03 18:28:56 -0400517func (lda *LDATest) updateLogicalDeviceConcurrently(t *testing.T, ldAgent *LogicalAgent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400518 originalLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500519 assert.NotNil(t, originalLogicalDevice)
520 var localWG sync.WaitGroup
521
522 // Change the state of the first port to FAILED
523 localWG.Add(1)
524 go func() {
npujar467fe752020-01-16 20:17:45 +0530525 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[0].DeviceId, lda.logicalDevice.Ports[0].DevicePortNo, voltha.OperStatus_FAILED)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500526 assert.Nil(t, err)
527 localWG.Done()
528 }()
529
530 // Change the state of the second port to TESTING
531 localWG.Add(1)
532 go func() {
npujar467fe752020-01-16 20:17:45 +0530533 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[1].DeviceId, lda.logicalDevice.Ports[1].DevicePortNo, voltha.OperStatus_TESTING)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500534 assert.Nil(t, err)
535 localWG.Done()
536 }()
537
538 // Change the state of the third port to UNKNOWN and then back to ACTIVE
539 localWG.Add(1)
540 go func() {
npujar467fe752020-01-16 20:17:45 +0530541 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_UNKNOWN)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500542 assert.Nil(t, err)
npujar467fe752020-01-16 20:17:45 +0530543 err = ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_ACTIVE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500544 assert.Nil(t, err)
545 localWG.Done()
546 }()
547
548 // Add a meter to the logical device
549 meterMod := &ofp.OfpMeterMod{
550 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
551 Flags: rand.Uint32(),
552 MeterId: rand.Uint32(),
553 Bands: []*ofp.OfpMeterBandHeader{
554 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
555 Rate: rand.Uint32(),
556 BurstSize: rand.Uint32(),
557 Data: nil,
558 },
559 },
560 }
561 localWG.Add(1)
562 go func() {
npujar467fe752020-01-16 20:17:45 +0530563 err := ldAgent.meterAdd(context.Background(), meterMod)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500564 assert.Nil(t, err)
565 localWG.Done()
566 }()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500567 // wait for go routines to be done
568 localWG.Wait()
Mahir Gunyeladdb66a2020-04-29 18:08:50 -0700569 meterEntry := fu.MeterEntryFromMeterMod(meterMod)
570
Kent Hagerman433a31a2020-05-20 19:04:48 -0400571 meterHandle, have := ldAgent.meterLoader.Lock(meterMod.MeterId)
572 assert.Equal(t, have, true)
573 if have {
574 assert.True(t, proto.Equal(meterEntry, meterHandle.GetReadOnly()))
575 meterHandle.Unlock()
576 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500577
578 expectedChange := proto.Clone(originalLogicalDevice).(*voltha.LogicalDevice)
579 expectedChange.Ports[0].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
580 expectedChange.Ports[0].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
581 expectedChange.Ports[1].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
582 expectedChange.Ports[1].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
583 expectedChange.Ports[2].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
584 expectedChange.Ports[2].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
khenaidoo442e7c72020-03-10 16:13:48 -0400585 updatedLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500586 assert.NotNil(t, updatedLogicalDevice)
587 assert.True(t, proto.Equal(expectedChange, updatedLogicalDevice))
588 globalWG.Done()
589}
590
591func TestConcurrentLogicalDeviceUpdate(t *testing.T) {
592 lda := newLDATest()
593 assert.NotNil(t, lda)
594 defer lda.stopAll()
595
596 // Start the Core
597 lda.startCore(false)
598
599 var wg sync.WaitGroup
khenaidoo442e7c72020-03-10 16:13:48 -0400600 numConCurrentLogicalDeviceAgents := 3
khenaidoo6e55d9e2019-12-12 18:26:26 -0500601 for i := 0; i < numConCurrentLogicalDeviceAgents; i++ {
602 wg.Add(1)
603 a := lda.createLogicalDeviceAgent(t)
604 go lda.updateLogicalDeviceConcurrently(t, a, &wg)
605 }
606
607 wg.Wait()
608}