blob: f5d404e0ab426b8f7db1daee04098a731d7bdd36 [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"
21 "sync"
22 "testing"
23 "time"
24
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070025 "github.com/opencord/voltha-go/db/model"
26 "github.com/opencord/voltha-go/rw_core/core/adapter"
27 "github.com/opencord/voltha-lib-go/v3/pkg/db"
28 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
29
khenaidoo6e55d9e2019-12-12 18:26:26 -050030 "github.com/gogo/protobuf/proto"
31 "github.com/opencord/voltha-go/rw_core/config"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080032 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080033 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
Matteo Scandolod525ae32020-04-02 17:27:29 -070034 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
35 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080036 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
37 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo6e55d9e2019-12-12 18:26:26 -050038 "github.com/phayes/freeport"
khenaidoo2bc48282019-07-16 18:13:46 -040039 "github.com/stretchr/testify/assert"
khenaidoo2bc48282019-07-16 18:13:46 -040040)
41
42func TestLogicalDeviceAgent_diff_nochange_1(t *testing.T) {
43 currentLogicalPorts := []*voltha.LogicalPort{}
44 updatedLogicalPorts := []*voltha.LogicalPort{}
45 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
46 assert.Equal(t, 0, len(newPorts))
47 assert.Equal(t, 0, len(changedPorts))
48 assert.Equal(t, 0, len(deletedPorts))
49}
50
51func TestLogicalDeviceAgent_diff_nochange_2(t *testing.T) {
52 currentLogicalPorts := []*voltha.LogicalPort{
53 {
54 Id: "1231",
55 DeviceId: "d1234",
56 DevicePortNo: 1,
57 RootPort: true,
58 OfpPort: &ofp.OfpPort{
59 PortNo: 1,
60 Name: "port1",
61 Config: 1,
62 State: 1,
63 },
64 },
65 {
66 Id: "1232",
67 DeviceId: "d1234",
68 DevicePortNo: 2,
69 RootPort: false,
70 OfpPort: &ofp.OfpPort{
71 PortNo: 2,
72 Name: "port2",
73 Config: 1,
74 State: 1,
75 },
76 },
77 {
78 Id: "1233",
79 DeviceId: "d1234",
80 DevicePortNo: 3,
81 RootPort: false,
82 OfpPort: &ofp.OfpPort{
83 PortNo: 3,
84 Name: "port3",
85 Config: 1,
86 State: 1,
87 },
88 },
89 }
90 updatedLogicalPorts := []*voltha.LogicalPort{
91 {
92 Id: "1231",
93 DeviceId: "d1234",
94 DevicePortNo: 1,
95 RootPort: true,
96 OfpPort: &ofp.OfpPort{
97 PortNo: 1,
98 Name: "port1",
99 Config: 1,
100 State: 1,
101 },
102 },
103 {
104 Id: "1232",
105 DeviceId: "d1234",
106 DevicePortNo: 2,
107 RootPort: false,
108 OfpPort: &ofp.OfpPort{
109 PortNo: 2,
110 Name: "port2",
111 Config: 1,
112 State: 1,
113 },
114 },
115 {
116 Id: "1233",
117 DeviceId: "d1234",
118 DevicePortNo: 3,
119 RootPort: false,
120 OfpPort: &ofp.OfpPort{
121 PortNo: 3,
122 Name: "port3",
123 Config: 1,
124 State: 1,
125 },
126 },
127 }
128 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
129 assert.Equal(t, 0, len(newPorts))
130 assert.Equal(t, 0, len(changedPorts))
131 assert.Equal(t, 0, len(deletedPorts))
132}
133
134func TestLogicalDeviceAgent_diff_add(t *testing.T) {
135 currentLogicalPorts := []*voltha.LogicalPort{}
136 updatedLogicalPorts := []*voltha.LogicalPort{
137 {
138 Id: "1231",
139 DeviceId: "d1234",
140 DevicePortNo: 1,
141 RootPort: true,
142 OfpPort: &ofp.OfpPort{
143 PortNo: 1,
144 Name: "port1",
145 Config: 1,
146 State: 1,
147 },
148 },
149 {
150 Id: "1232",
151 DeviceId: "d1234",
152 DevicePortNo: 2,
153 RootPort: true,
154 OfpPort: &ofp.OfpPort{
155 PortNo: 2,
156 Name: "port2",
157 Config: 1,
158 State: 1,
159 },
160 },
161 }
162 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
163 assert.Equal(t, 2, len(newPorts))
164 assert.Equal(t, 0, len(changedPorts))
165 assert.Equal(t, 0, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400166 assert.Equal(t, updatedLogicalPorts[0], newPorts[updatedLogicalPorts[0].Id])
167 assert.Equal(t, updatedLogicalPorts[1], newPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400168}
169
170func TestLogicalDeviceAgent_diff_delete(t *testing.T) {
171 currentLogicalPorts := []*voltha.LogicalPort{
172 {
173 Id: "1231",
174 DeviceId: "d1234",
175 DevicePortNo: 1,
176 RootPort: true,
177 OfpPort: &ofp.OfpPort{
178 PortNo: 1,
179 Name: "port1",
180 Config: 1,
181 State: 1,
182 },
183 },
184 }
185 updatedLogicalPorts := []*voltha.LogicalPort{}
186 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
187 assert.Equal(t, 0, len(newPorts))
188 assert.Equal(t, 0, len(changedPorts))
189 assert.Equal(t, 1, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400190 assert.Equal(t, currentLogicalPorts[0], deletedPorts[currentLogicalPorts[0].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400191}
192
193func TestLogicalDeviceAgent_diff_changed(t *testing.T) {
194 currentLogicalPorts := []*voltha.LogicalPort{
195 {
196 Id: "1231",
197 DeviceId: "d1234",
198 DevicePortNo: 1,
199 RootPort: true,
200 OfpPort: &ofp.OfpPort{
201 PortNo: 1,
202 Name: "port1",
203 Config: 1,
204 State: 1,
205 },
206 },
207 {
208 Id: "1232",
209 DeviceId: "d1234",
210 DevicePortNo: 2,
211 RootPort: false,
212 OfpPort: &ofp.OfpPort{
213 PortNo: 2,
214 Name: "port2",
215 Config: 1,
216 State: 1,
217 },
218 },
219 {
220 Id: "1233",
221 DeviceId: "d1234",
222 DevicePortNo: 3,
223 RootPort: false,
224 OfpPort: &ofp.OfpPort{
225 PortNo: 3,
226 Name: "port3",
227 Config: 1,
228 State: 1,
229 },
230 },
231 }
232 updatedLogicalPorts := []*voltha.LogicalPort{
233 {
234 Id: "1231",
235 DeviceId: "d1234",
236 DevicePortNo: 1,
237 RootPort: true,
238 OfpPort: &ofp.OfpPort{
239 PortNo: 1,
240 Name: "port1",
241 Config: 4,
242 State: 4,
243 },
244 },
245 {
246 Id: "1232",
247 DeviceId: "d1234",
248 DevicePortNo: 2,
249 RootPort: false,
250 OfpPort: &ofp.OfpPort{
251 PortNo: 2,
252 Name: "port2",
253 Config: 4,
254 State: 4,
255 },
256 },
257 {
258 Id: "1233",
259 DeviceId: "d1234",
260 DevicePortNo: 3,
261 RootPort: false,
262 OfpPort: &ofp.OfpPort{
263 PortNo: 3,
264 Name: "port3",
265 Config: 1,
266 State: 1,
267 },
268 },
269 }
270 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
271 assert.Equal(t, 0, len(newPorts))
272 assert.Equal(t, 2, len(changedPorts))
273 assert.Equal(t, 0, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400274 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
275 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400276}
277
278func TestLogicalDeviceAgent_diff_mix(t *testing.T) {
279 currentLogicalPorts := []*voltha.LogicalPort{
280 {
281 Id: "1231",
282 DeviceId: "d1234",
283 DevicePortNo: 1,
284 RootPort: true,
285 OfpPort: &ofp.OfpPort{
286 PortNo: 1,
287 Name: "port1",
288 Config: 1,
289 State: 1,
290 },
291 },
292 {
293 Id: "1232",
294 DeviceId: "d1234",
295 DevicePortNo: 2,
296 RootPort: false,
297 OfpPort: &ofp.OfpPort{
298 PortNo: 2,
299 Name: "port2",
300 Config: 1,
301 State: 1,
302 },
303 },
304 {
305 Id: "1233",
306 DeviceId: "d1234",
307 DevicePortNo: 3,
308 RootPort: false,
309 OfpPort: &ofp.OfpPort{
310 PortNo: 3,
311 Name: "port3",
312 Config: 1,
313 State: 1,
314 },
315 },
316 }
317 updatedLogicalPorts := []*voltha.LogicalPort{
318 {
319 Id: "1231",
320 DeviceId: "d1234",
321 DevicePortNo: 1,
322 RootPort: true,
323 OfpPort: &ofp.OfpPort{
324 PortNo: 1,
325 Name: "port1",
326 Config: 4,
327 State: 4,
328 },
329 },
330 {
331 Id: "1232",
332 DeviceId: "d1234",
333 DevicePortNo: 2,
334 RootPort: false,
335 OfpPort: &ofp.OfpPort{
336 PortNo: 2,
337 Name: "port2",
338 Config: 4,
339 State: 4,
340 },
341 },
342 {
343 Id: "1234",
344 DeviceId: "d1234",
345 DevicePortNo: 4,
346 RootPort: false,
347 OfpPort: &ofp.OfpPort{
348 PortNo: 4,
349 Name: "port4",
350 Config: 4,
351 State: 4,
352 },
353 },
354 }
355 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
356 assert.Equal(t, 1, len(newPorts))
357 assert.Equal(t, 2, len(changedPorts))
358 assert.Equal(t, 1, len(deletedPorts))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400359 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
360 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
361 assert.Equal(t, currentLogicalPorts[2], deletedPorts[currentLogicalPorts[2].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400362}
khenaidoo6e55d9e2019-12-12 18:26:26 -0500363
364type LDATest struct {
Kent Hagerman2b216042020-04-03 18:28:56 -0400365 etcdServer *mock_etcd.EtcdServer
366 deviceMgr *Manager
367 kmp kafka.InterContainerProxy
368 logicalDeviceMgr *LogicalManager
369 kClient kafka.Client
370 kvClientPort int
371 oltAdapterName string
372 onuAdapterName string
373 coreInstanceID string
374 defaultTimeout time.Duration
375 maxTimeout time.Duration
376 logicalDevice *voltha.LogicalDevice
377 deviceIds []string
378 done chan int
khenaidoo6e55d9e2019-12-12 18:26:26 -0500379}
380
381func newLDATest() *LDATest {
382 test := &LDATest{}
383 // Start the embedded etcd server
384 var err error
385 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.lda.test", "voltha.rwcore.lda.etcd", "error")
386 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000387 logger.Fatal(err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500388 }
389 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -0700390 test.kClient = mock_kafka.NewKafkaClient()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500391 test.oltAdapterName = "olt_adapter_mock"
392 test.onuAdapterName = "onu_adapter_mock"
393 test.coreInstanceID = "rw-da-test"
394 test.defaultTimeout = 5 * time.Second
395 test.maxTimeout = 20 * time.Second
396 test.done = make(chan int)
397 test.deviceIds = []string{com.GetRandomString(10), com.GetRandomString(10), com.GetRandomString(10)}
398 test.logicalDevice = &voltha.LogicalDevice{
399 Desc: &ofp.OfpDesc{
400 HwDesc: "olt_adapter_mock",
401 SwDesc: "olt_adapter_mock",
402 SerialNum: com.GetRandomSerialNumber(),
403 },
404 SwitchFeatures: &ofp.OfpSwitchFeatures{
405 NBuffers: 256,
406 NTables: 2,
407 Capabilities: uint32(ofp.OfpCapabilities_OFPC_FLOW_STATS |
408 ofp.OfpCapabilities_OFPC_TABLE_STATS |
409 ofp.OfpCapabilities_OFPC_PORT_STATS |
410 ofp.OfpCapabilities_OFPC_GROUP_STATS),
411 },
412 RootDeviceId: test.deviceIds[0],
413 Ports: []*voltha.LogicalPort{
414 {
415 Id: "1001",
416 DeviceId: test.deviceIds[0],
417 DevicePortNo: 1,
418 RootPort: true,
419 OfpPort: &ofp.OfpPort{
420 PortNo: 1,
421 Name: "port1",
422 Config: 4,
423 State: 4,
424 },
425 },
426 {
427 Id: "1002",
428 DeviceId: test.deviceIds[1],
429 DevicePortNo: 2,
430 RootPort: false,
431 OfpPort: &ofp.OfpPort{
432 PortNo: 2,
433 Name: "port2",
434 Config: 4,
435 State: 4,
436 },
437 },
438 {
439 Id: "1003",
440 DeviceId: test.deviceIds[2],
441 DevicePortNo: 3,
442 RootPort: false,
443 OfpPort: &ofp.OfpPort{
444 PortNo: 4,
445 Name: "port3",
446 Config: 4,
447 State: 4,
448 },
449 },
450 },
451 }
452 return test
453}
454
455func (lda *LDATest) startCore(inCompeteMode bool) {
456 cfg := config.NewRWCoreFlags()
457 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -0400458 cfg.DefaultRequestTimeout = lda.defaultTimeout
khenaidoo6e55d9e2019-12-12 18:26:26 -0500459 cfg.KVStorePort = lda.kvClientPort
460 cfg.InCompetingMode = inCompeteMode
461 grpcPort, err := freeport.GetFreePort()
462 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000463 logger.Fatal("Cannot get a freeport for grpc")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500464 }
465 cfg.GrpcPort = grpcPort
466 cfg.GrpcHost = "127.0.0.1"
khenaidoo6e55d9e2019-12-12 18:26:26 -0500467 client := setupKVClient(cfg, lda.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400468 backend := &db.Backend{
469 Client: client,
470 StoreType: cfg.KVStoreType,
471 Host: cfg.KVStoreHost,
472 Port: cfg.KVStorePort,
473 Timeout: cfg.KVStoreTimeout,
474 LivenessChannelInterval: cfg.LiveProbeInterval / 2,
475 PathPrefix: cfg.KVStoreDataPrefix}
476 lda.kmp = kafka.NewInterContainerProxy(
477 kafka.InterContainerHost(cfg.KafkaAdapterHost),
478 kafka.InterContainerPort(cfg.KafkaAdapterPort),
479 kafka.MsgClient(lda.kClient),
480 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}),
481 kafka.DeviceDiscoveryTopic(&kafka.Topic{Name: cfg.AffinityRouterTopic}))
482
483 endpointMgr := kafka.NewEndpointManager(backend)
484 proxy := model.NewProxy(backend, "/")
485 adapterMgr := adapter.NewAdapterManager(proxy, lda.coreInstanceID, lda.kClient)
486
Kent Hagerman45a13e42020-04-13 12:23:50 -0400487 lda.deviceMgr, lda.logicalDeviceMgr = NewManagers(proxy, adapterMgr, lda.kmp, endpointMgr, cfg.CorePairTopic, lda.coreInstanceID, cfg.DefaultCoreTimeout)
Kent Hagerman2b216042020-04-03 18:28:56 -0400488 if err = lda.kmp.Start(); err != nil {
489 logger.Fatal("Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530490 }
Kent Hagerman2f0d0552020-04-23 17:28:52 -0400491 adapterMgr.Start(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500492}
493
494func (lda *LDATest) stopAll() {
495 if lda.kClient != nil {
496 lda.kClient.Stop()
497 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400498 if lda.kmp != nil {
499 lda.kmp.Stop()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500500 }
501 if lda.etcdServer != nil {
502 stopEmbeddedEtcdServer(lda.etcdServer)
503 }
504}
505
Kent Hagerman2b216042020-04-03 18:28:56 -0400506func (lda *LDATest) createLogicalDeviceAgent(t *testing.T) *LogicalAgent {
507 lDeviceMgr := lda.logicalDeviceMgr
508 deviceMgr := lda.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500509 clonedLD := proto.Clone(lda.logicalDevice).(*voltha.LogicalDevice)
510 clonedLD.Id = com.GetRandomString(10)
511 clonedLD.DatapathId = rand.Uint64()
David Bainbridged1afd662020-03-26 18:27:41 -0700512 lDeviceAgent := newLogicalDeviceAgent(clonedLD.Id, clonedLD.Id, clonedLD.RootDeviceId, lDeviceMgr, deviceMgr, lDeviceMgr.clusterDataProxy, lDeviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500513 lDeviceAgent.logicalDevice = clonedLD
Kent Hagerman4f355f52020-03-30 16:01:33 -0400514 err := lDeviceAgent.clusterDataProxy.AddWithID(context.Background(), "logical_devices", clonedLD.Id, clonedLD)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530515 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500516 lDeviceMgr.addLogicalDeviceAgentToMap(lDeviceAgent)
517 return lDeviceAgent
518}
519
Kent Hagerman2b216042020-04-03 18:28:56 -0400520func (lda *LDATest) updateLogicalDeviceConcurrently(t *testing.T, ldAgent *LogicalAgent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400521 originalLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500522 assert.NotNil(t, originalLogicalDevice)
523 var localWG sync.WaitGroup
524
525 // Change the state of the first port to FAILED
526 localWG.Add(1)
527 go func() {
npujar467fe752020-01-16 20:17:45 +0530528 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[0].DeviceId, lda.logicalDevice.Ports[0].DevicePortNo, voltha.OperStatus_FAILED)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500529 assert.Nil(t, err)
530 localWG.Done()
531 }()
532
533 // Change the state of the second port to TESTING
534 localWG.Add(1)
535 go func() {
npujar467fe752020-01-16 20:17:45 +0530536 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[1].DeviceId, lda.logicalDevice.Ports[1].DevicePortNo, voltha.OperStatus_TESTING)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500537 assert.Nil(t, err)
538 localWG.Done()
539 }()
540
541 // Change the state of the third port to UNKNOWN and then back to ACTIVE
542 localWG.Add(1)
543 go func() {
npujar467fe752020-01-16 20:17:45 +0530544 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_UNKNOWN)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500545 assert.Nil(t, err)
npujar467fe752020-01-16 20:17:45 +0530546 err = ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_ACTIVE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500547 assert.Nil(t, err)
548 localWG.Done()
549 }()
550
551 // Add a meter to the logical device
552 meterMod := &ofp.OfpMeterMod{
553 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
554 Flags: rand.Uint32(),
555 MeterId: rand.Uint32(),
556 Bands: []*ofp.OfpMeterBandHeader{
557 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
558 Rate: rand.Uint32(),
559 BurstSize: rand.Uint32(),
560 Data: nil,
561 },
562 },
563 }
564 localWG.Add(1)
565 go func() {
npujar467fe752020-01-16 20:17:45 +0530566 err := ldAgent.meterAdd(context.Background(), meterMod)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500567 assert.Nil(t, err)
568 localWG.Done()
569 }()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500570 // wait for go routines to be done
571 localWG.Wait()
Mahir Gunyeladdb66a2020-04-29 18:08:50 -0700572 meterEntry := fu.MeterEntryFromMeterMod(meterMod)
573
Kent Hagerman433a31a2020-05-20 19:04:48 -0400574 meterHandle, have := ldAgent.meterLoader.Lock(meterMod.MeterId)
575 assert.Equal(t, have, true)
576 if have {
577 assert.True(t, proto.Equal(meterEntry, meterHandle.GetReadOnly()))
578 meterHandle.Unlock()
579 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500580
581 expectedChange := proto.Clone(originalLogicalDevice).(*voltha.LogicalDevice)
582 expectedChange.Ports[0].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
583 expectedChange.Ports[0].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
584 expectedChange.Ports[1].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
585 expectedChange.Ports[1].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
586 expectedChange.Ports[2].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
587 expectedChange.Ports[2].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
khenaidoo442e7c72020-03-10 16:13:48 -0400588 updatedLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500589 assert.NotNil(t, updatedLogicalDevice)
590 assert.True(t, proto.Equal(expectedChange, updatedLogicalDevice))
591 globalWG.Done()
592}
593
594func TestConcurrentLogicalDeviceUpdate(t *testing.T) {
595 lda := newLDATest()
596 assert.NotNil(t, lda)
597 defer lda.stopAll()
598
599 // Start the Core
600 lda.startCore(false)
601
602 var wg sync.WaitGroup
khenaidoo442e7c72020-03-10 16:13:48 -0400603 numConCurrentLogicalDeviceAgents := 3
khenaidoo6e55d9e2019-12-12 18:26:26 -0500604 for i := 0; i < numConCurrentLogicalDeviceAgents; i++ {
605 wg.Add(1)
606 a := lda.createLogicalDeviceAgent(t)
607 go lda.updateLogicalDeviceConcurrently(t, a, &wg)
608 }
609
610 wg.Wait()
611}