blob: 3c3b2b03c0b17f173517b5956ccda6aaa308aba9 [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"
Kent Hagerman2b216042020-04-03 18:28:56 -040020 "github.com/opencord/voltha-go/db/model"
21 "github.com/opencord/voltha-go/rw_core/core/adapter"
22 "github.com/opencord/voltha-lib-go/v3/pkg/db"
David Bainbridged1afd662020-03-26 18:27:41 -070023 "math/rand"
24 "sync"
25 "testing"
26 "time"
27
khenaidoo6e55d9e2019-12-12 18:26:26 -050028 "github.com/gogo/protobuf/proto"
29 "github.com/opencord/voltha-go/rw_core/config"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080030 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
31 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
32 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
Matteo Scandolod525ae32020-04-02 17:27:29 -070033 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
34 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080035 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
36 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo6e55d9e2019-12-12 18:26:26 -050037 "github.com/phayes/freeport"
khenaidoo2bc48282019-07-16 18:13:46 -040038 "github.com/stretchr/testify/assert"
khenaidoo2bc48282019-07-16 18:13:46 -040039)
40
41func TestLogicalDeviceAgent_diff_nochange_1(t *testing.T) {
42 currentLogicalPorts := []*voltha.LogicalPort{}
43 updatedLogicalPorts := []*voltha.LogicalPort{}
44 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
45 assert.Equal(t, 0, len(newPorts))
46 assert.Equal(t, 0, len(changedPorts))
47 assert.Equal(t, 0, len(deletedPorts))
48}
49
50func TestLogicalDeviceAgent_diff_nochange_2(t *testing.T) {
51 currentLogicalPorts := []*voltha.LogicalPort{
52 {
53 Id: "1231",
54 DeviceId: "d1234",
55 DevicePortNo: 1,
56 RootPort: true,
57 OfpPort: &ofp.OfpPort{
58 PortNo: 1,
59 Name: "port1",
60 Config: 1,
61 State: 1,
62 },
63 },
64 {
65 Id: "1232",
66 DeviceId: "d1234",
67 DevicePortNo: 2,
68 RootPort: false,
69 OfpPort: &ofp.OfpPort{
70 PortNo: 2,
71 Name: "port2",
72 Config: 1,
73 State: 1,
74 },
75 },
76 {
77 Id: "1233",
78 DeviceId: "d1234",
79 DevicePortNo: 3,
80 RootPort: false,
81 OfpPort: &ofp.OfpPort{
82 PortNo: 3,
83 Name: "port3",
84 Config: 1,
85 State: 1,
86 },
87 },
88 }
89 updatedLogicalPorts := []*voltha.LogicalPort{
90 {
91 Id: "1231",
92 DeviceId: "d1234",
93 DevicePortNo: 1,
94 RootPort: true,
95 OfpPort: &ofp.OfpPort{
96 PortNo: 1,
97 Name: "port1",
98 Config: 1,
99 State: 1,
100 },
101 },
102 {
103 Id: "1232",
104 DeviceId: "d1234",
105 DevicePortNo: 2,
106 RootPort: false,
107 OfpPort: &ofp.OfpPort{
108 PortNo: 2,
109 Name: "port2",
110 Config: 1,
111 State: 1,
112 },
113 },
114 {
115 Id: "1233",
116 DeviceId: "d1234",
117 DevicePortNo: 3,
118 RootPort: false,
119 OfpPort: &ofp.OfpPort{
120 PortNo: 3,
121 Name: "port3",
122 Config: 1,
123 State: 1,
124 },
125 },
126 }
127 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
128 assert.Equal(t, 0, len(newPorts))
129 assert.Equal(t, 0, len(changedPorts))
130 assert.Equal(t, 0, len(deletedPorts))
131}
132
133func TestLogicalDeviceAgent_diff_add(t *testing.T) {
134 currentLogicalPorts := []*voltha.LogicalPort{}
135 updatedLogicalPorts := []*voltha.LogicalPort{
136 {
137 Id: "1231",
138 DeviceId: "d1234",
139 DevicePortNo: 1,
140 RootPort: true,
141 OfpPort: &ofp.OfpPort{
142 PortNo: 1,
143 Name: "port1",
144 Config: 1,
145 State: 1,
146 },
147 },
148 {
149 Id: "1232",
150 DeviceId: "d1234",
151 DevicePortNo: 2,
152 RootPort: true,
153 OfpPort: &ofp.OfpPort{
154 PortNo: 2,
155 Name: "port2",
156 Config: 1,
157 State: 1,
158 },
159 },
160 }
161 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
162 assert.Equal(t, 2, len(newPorts))
163 assert.Equal(t, 0, len(changedPorts))
164 assert.Equal(t, 0, len(deletedPorts))
165 assert.Equal(t, updatedLogicalPorts[0], newPorts[0])
166 assert.Equal(t, updatedLogicalPorts[1], newPorts[1])
167}
168
169func TestLogicalDeviceAgent_diff_delete(t *testing.T) {
170 currentLogicalPorts := []*voltha.LogicalPort{
171 {
172 Id: "1231",
173 DeviceId: "d1234",
174 DevicePortNo: 1,
175 RootPort: true,
176 OfpPort: &ofp.OfpPort{
177 PortNo: 1,
178 Name: "port1",
179 Config: 1,
180 State: 1,
181 },
182 },
183 }
184 updatedLogicalPorts := []*voltha.LogicalPort{}
185 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
186 assert.Equal(t, 0, len(newPorts))
187 assert.Equal(t, 0, len(changedPorts))
188 assert.Equal(t, 1, len(deletedPorts))
189 assert.Equal(t, currentLogicalPorts[0], deletedPorts[0])
190}
191
192func TestLogicalDeviceAgent_diff_changed(t *testing.T) {
193 currentLogicalPorts := []*voltha.LogicalPort{
194 {
195 Id: "1231",
196 DeviceId: "d1234",
197 DevicePortNo: 1,
198 RootPort: true,
199 OfpPort: &ofp.OfpPort{
200 PortNo: 1,
201 Name: "port1",
202 Config: 1,
203 State: 1,
204 },
205 },
206 {
207 Id: "1232",
208 DeviceId: "d1234",
209 DevicePortNo: 2,
210 RootPort: false,
211 OfpPort: &ofp.OfpPort{
212 PortNo: 2,
213 Name: "port2",
214 Config: 1,
215 State: 1,
216 },
217 },
218 {
219 Id: "1233",
220 DeviceId: "d1234",
221 DevicePortNo: 3,
222 RootPort: false,
223 OfpPort: &ofp.OfpPort{
224 PortNo: 3,
225 Name: "port3",
226 Config: 1,
227 State: 1,
228 },
229 },
230 }
231 updatedLogicalPorts := []*voltha.LogicalPort{
232 {
233 Id: "1231",
234 DeviceId: "d1234",
235 DevicePortNo: 1,
236 RootPort: true,
237 OfpPort: &ofp.OfpPort{
238 PortNo: 1,
239 Name: "port1",
240 Config: 4,
241 State: 4,
242 },
243 },
244 {
245 Id: "1232",
246 DeviceId: "d1234",
247 DevicePortNo: 2,
248 RootPort: false,
249 OfpPort: &ofp.OfpPort{
250 PortNo: 2,
251 Name: "port2",
252 Config: 4,
253 State: 4,
254 },
255 },
256 {
257 Id: "1233",
258 DeviceId: "d1234",
259 DevicePortNo: 3,
260 RootPort: false,
261 OfpPort: &ofp.OfpPort{
262 PortNo: 3,
263 Name: "port3",
264 Config: 1,
265 State: 1,
266 },
267 },
268 }
269 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
270 assert.Equal(t, 0, len(newPorts))
271 assert.Equal(t, 2, len(changedPorts))
272 assert.Equal(t, 0, len(deletedPorts))
273 assert.Equal(t, updatedLogicalPorts[0], changedPorts[0])
274 assert.Equal(t, updatedLogicalPorts[1], changedPorts[1])
275}
276
277func TestLogicalDeviceAgent_diff_mix(t *testing.T) {
278 currentLogicalPorts := []*voltha.LogicalPort{
279 {
280 Id: "1231",
281 DeviceId: "d1234",
282 DevicePortNo: 1,
283 RootPort: true,
284 OfpPort: &ofp.OfpPort{
285 PortNo: 1,
286 Name: "port1",
287 Config: 1,
288 State: 1,
289 },
290 },
291 {
292 Id: "1232",
293 DeviceId: "d1234",
294 DevicePortNo: 2,
295 RootPort: false,
296 OfpPort: &ofp.OfpPort{
297 PortNo: 2,
298 Name: "port2",
299 Config: 1,
300 State: 1,
301 },
302 },
303 {
304 Id: "1233",
305 DeviceId: "d1234",
306 DevicePortNo: 3,
307 RootPort: false,
308 OfpPort: &ofp.OfpPort{
309 PortNo: 3,
310 Name: "port3",
311 Config: 1,
312 State: 1,
313 },
314 },
315 }
316 updatedLogicalPorts := []*voltha.LogicalPort{
317 {
318 Id: "1231",
319 DeviceId: "d1234",
320 DevicePortNo: 1,
321 RootPort: true,
322 OfpPort: &ofp.OfpPort{
323 PortNo: 1,
324 Name: "port1",
325 Config: 4,
326 State: 4,
327 },
328 },
329 {
330 Id: "1232",
331 DeviceId: "d1234",
332 DevicePortNo: 2,
333 RootPort: false,
334 OfpPort: &ofp.OfpPort{
335 PortNo: 2,
336 Name: "port2",
337 Config: 4,
338 State: 4,
339 },
340 },
341 {
342 Id: "1234",
343 DeviceId: "d1234",
344 DevicePortNo: 4,
345 RootPort: false,
346 OfpPort: &ofp.OfpPort{
347 PortNo: 4,
348 Name: "port4",
349 Config: 4,
350 State: 4,
351 },
352 },
353 }
354 newPorts, changedPorts, deletedPorts := diff(currentLogicalPorts, updatedLogicalPorts)
355 assert.Equal(t, 1, len(newPorts))
356 assert.Equal(t, 2, len(changedPorts))
357 assert.Equal(t, 1, len(deletedPorts))
358 assert.Equal(t, updatedLogicalPorts[0], changedPorts[0])
359 assert.Equal(t, updatedLogicalPorts[1], changedPorts[1])
360 assert.Equal(t, currentLogicalPorts[2], deletedPorts[0])
361}
khenaidoo6e55d9e2019-12-12 18:26:26 -0500362
363type LDATest struct {
Kent Hagerman2b216042020-04-03 18:28:56 -0400364 etcdServer *mock_etcd.EtcdServer
365 deviceMgr *Manager
366 kmp kafka.InterContainerProxy
367 logicalDeviceMgr *LogicalManager
368 kClient kafka.Client
369 kvClientPort int
370 oltAdapterName string
371 onuAdapterName string
372 coreInstanceID string
373 defaultTimeout time.Duration
374 maxTimeout time.Duration
375 logicalDevice *voltha.LogicalDevice
376 deviceIds []string
377 done chan int
khenaidoo6e55d9e2019-12-12 18:26:26 -0500378}
379
380func newLDATest() *LDATest {
381 test := &LDATest{}
382 // Start the embedded etcd server
383 var err error
384 test.etcdServer, test.kvClientPort, err = startEmbeddedEtcdServer("voltha.rwcore.lda.test", "voltha.rwcore.lda.etcd", "error")
385 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000386 logger.Fatal(err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500387 }
388 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -0700389 test.kClient = mock_kafka.NewKafkaClient()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500390 test.oltAdapterName = "olt_adapter_mock"
391 test.onuAdapterName = "onu_adapter_mock"
392 test.coreInstanceID = "rw-da-test"
393 test.defaultTimeout = 5 * time.Second
394 test.maxTimeout = 20 * time.Second
395 test.done = make(chan int)
396 test.deviceIds = []string{com.GetRandomString(10), com.GetRandomString(10), com.GetRandomString(10)}
397 test.logicalDevice = &voltha.LogicalDevice{
398 Desc: &ofp.OfpDesc{
399 HwDesc: "olt_adapter_mock",
400 SwDesc: "olt_adapter_mock",
401 SerialNum: com.GetRandomSerialNumber(),
402 },
403 SwitchFeatures: &ofp.OfpSwitchFeatures{
404 NBuffers: 256,
405 NTables: 2,
406 Capabilities: uint32(ofp.OfpCapabilities_OFPC_FLOW_STATS |
407 ofp.OfpCapabilities_OFPC_TABLE_STATS |
408 ofp.OfpCapabilities_OFPC_PORT_STATS |
409 ofp.OfpCapabilities_OFPC_GROUP_STATS),
410 },
411 RootDeviceId: test.deviceIds[0],
412 Ports: []*voltha.LogicalPort{
413 {
414 Id: "1001",
415 DeviceId: test.deviceIds[0],
416 DevicePortNo: 1,
417 RootPort: true,
418 OfpPort: &ofp.OfpPort{
419 PortNo: 1,
420 Name: "port1",
421 Config: 4,
422 State: 4,
423 },
424 },
425 {
426 Id: "1002",
427 DeviceId: test.deviceIds[1],
428 DevicePortNo: 2,
429 RootPort: false,
430 OfpPort: &ofp.OfpPort{
431 PortNo: 2,
432 Name: "port2",
433 Config: 4,
434 State: 4,
435 },
436 },
437 {
438 Id: "1003",
439 DeviceId: test.deviceIds[2],
440 DevicePortNo: 3,
441 RootPort: false,
442 OfpPort: &ofp.OfpPort{
443 PortNo: 4,
444 Name: "port3",
445 Config: 4,
446 State: 4,
447 },
448 },
449 },
450 }
451 return test
452}
453
454func (lda *LDATest) startCore(inCompeteMode bool) {
455 cfg := config.NewRWCoreFlags()
456 cfg.CorePairTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -0400457 cfg.DefaultRequestTimeout = lda.defaultTimeout
khenaidoo6e55d9e2019-12-12 18:26:26 -0500458 cfg.KVStorePort = lda.kvClientPort
459 cfg.InCompetingMode = inCompeteMode
460 grpcPort, err := freeport.GetFreePort()
461 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000462 logger.Fatal("Cannot get a freeport for grpc")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500463 }
464 cfg.GrpcPort = grpcPort
465 cfg.GrpcHost = "127.0.0.1"
khenaidoo6e55d9e2019-12-12 18:26:26 -0500466 client := setupKVClient(cfg, lda.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400467 backend := &db.Backend{
468 Client: client,
469 StoreType: cfg.KVStoreType,
470 Host: cfg.KVStoreHost,
471 Port: cfg.KVStorePort,
472 Timeout: cfg.KVStoreTimeout,
473 LivenessChannelInterval: cfg.LiveProbeInterval / 2,
474 PathPrefix: cfg.KVStoreDataPrefix}
475 lda.kmp = kafka.NewInterContainerProxy(
476 kafka.InterContainerHost(cfg.KafkaAdapterHost),
477 kafka.InterContainerPort(cfg.KafkaAdapterPort),
478 kafka.MsgClient(lda.kClient),
479 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}),
480 kafka.DeviceDiscoveryTopic(&kafka.Topic{Name: cfg.AffinityRouterTopic}))
481
482 endpointMgr := kafka.NewEndpointManager(backend)
483 proxy := model.NewProxy(backend, "/")
484 adapterMgr := adapter.NewAdapterManager(proxy, lda.coreInstanceID, lda.kClient)
485
486 lda.deviceMgr, lda.logicalDeviceMgr = NewDeviceManagers(proxy, adapterMgr, lda.kmp, endpointMgr, cfg.CorePairTopic, lda.coreInstanceID, cfg.DefaultCoreTimeout)
487 lda.logicalDeviceMgr.SetEventCallbacks(fakeEventCallbacks{})
488 if err = lda.kmp.Start(); err != nil {
489 logger.Fatal("Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530490 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400491 if err = adapterMgr.Start(context.Background()); err != nil {
492 logger.Fatal("Cannot start adapterMgr")
493 }
494 lda.deviceMgr.Start(context.Background())
495 lda.logicalDeviceMgr.Start(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500496}
497
498func (lda *LDATest) stopAll() {
499 if lda.kClient != nil {
500 lda.kClient.Stop()
501 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400502 if lda.logicalDeviceMgr != nil {
503 lda.logicalDeviceMgr.Stop(context.Background())
504 }
505 if lda.deviceMgr != nil {
506 lda.deviceMgr.Stop(context.Background())
507 }
508 if lda.kmp != nil {
509 lda.kmp.Stop()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500510 }
511 if lda.etcdServer != nil {
512 stopEmbeddedEtcdServer(lda.etcdServer)
513 }
514}
515
Kent Hagerman2b216042020-04-03 18:28:56 -0400516func (lda *LDATest) createLogicalDeviceAgent(t *testing.T) *LogicalAgent {
517 lDeviceMgr := lda.logicalDeviceMgr
518 deviceMgr := lda.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500519 clonedLD := proto.Clone(lda.logicalDevice).(*voltha.LogicalDevice)
520 clonedLD.Id = com.GetRandomString(10)
521 clonedLD.DatapathId = rand.Uint64()
David Bainbridged1afd662020-03-26 18:27:41 -0700522 lDeviceAgent := newLogicalDeviceAgent(clonedLD.Id, clonedLD.Id, clonedLD.RootDeviceId, lDeviceMgr, deviceMgr, lDeviceMgr.clusterDataProxy, lDeviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500523 lDeviceAgent.logicalDevice = clonedLD
Kent Hagerman4f355f52020-03-30 16:01:33 -0400524 err := lDeviceAgent.clusterDataProxy.AddWithID(context.Background(), "logical_devices", clonedLD.Id, clonedLD)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530525 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500526 lDeviceMgr.addLogicalDeviceAgentToMap(lDeviceAgent)
527 return lDeviceAgent
528}
529
Kent Hagerman2b216042020-04-03 18:28:56 -0400530func (lda *LDATest) updateLogicalDeviceConcurrently(t *testing.T, ldAgent *LogicalAgent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400531 originalLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500532 assert.NotNil(t, originalLogicalDevice)
533 var localWG sync.WaitGroup
534
535 // Change the state of the first port to FAILED
536 localWG.Add(1)
537 go func() {
npujar467fe752020-01-16 20:17:45 +0530538 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[0].DeviceId, lda.logicalDevice.Ports[0].DevicePortNo, voltha.OperStatus_FAILED)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500539 assert.Nil(t, err)
540 localWG.Done()
541 }()
542
543 // Change the state of the second port to TESTING
544 localWG.Add(1)
545 go func() {
npujar467fe752020-01-16 20:17:45 +0530546 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[1].DeviceId, lda.logicalDevice.Ports[1].DevicePortNo, voltha.OperStatus_TESTING)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500547 assert.Nil(t, err)
548 localWG.Done()
549 }()
550
551 // Change the state of the third port to UNKNOWN and then back to ACTIVE
552 localWG.Add(1)
553 go func() {
npujar467fe752020-01-16 20:17:45 +0530554 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_UNKNOWN)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500555 assert.Nil(t, err)
npujar467fe752020-01-16 20:17:45 +0530556 err = ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_ACTIVE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500557 assert.Nil(t, err)
558 localWG.Done()
559 }()
560
561 // Add a meter to the logical device
562 meterMod := &ofp.OfpMeterMod{
563 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
564 Flags: rand.Uint32(),
565 MeterId: rand.Uint32(),
566 Bands: []*ofp.OfpMeterBandHeader{
567 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
568 Rate: rand.Uint32(),
569 BurstSize: rand.Uint32(),
570 Data: nil,
571 },
572 },
573 }
574 localWG.Add(1)
575 go func() {
npujar467fe752020-01-16 20:17:45 +0530576 err := ldAgent.meterAdd(context.Background(), meterMod)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500577 assert.Nil(t, err)
578 localWG.Done()
579 }()
580
581 // wait for go routines to be done
582 localWG.Wait()
583
584 expectedChange := proto.Clone(originalLogicalDevice).(*voltha.LogicalDevice)
585 expectedChange.Ports[0].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
586 expectedChange.Ports[0].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
587 expectedChange.Ports[1].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
588 expectedChange.Ports[1].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
589 expectedChange.Ports[2].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
590 expectedChange.Ports[2].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
591 expectedChange.Meters = &voltha.Meters{Items: nil}
592 expectedChange.Meters.Items = append(expectedChange.Meters.Items, fu.MeterEntryFromMeterMod(meterMod))
khenaidoo442e7c72020-03-10 16:13:48 -0400593 updatedLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500594 assert.NotNil(t, updatedLogicalDevice)
595 assert.True(t, proto.Equal(expectedChange, updatedLogicalDevice))
596 globalWG.Done()
597}
598
599func TestConcurrentLogicalDeviceUpdate(t *testing.T) {
600 lda := newLDATest()
601 assert.NotNil(t, lda)
602 defer lda.stopAll()
603
604 // Start the Core
605 lda.startCore(false)
606
607 var wg sync.WaitGroup
khenaidoo442e7c72020-03-10 16:13:48 -0400608 numConCurrentLogicalDeviceAgents := 3
khenaidoo6e55d9e2019-12-12 18:26:26 -0500609 for i := 0; i < numConCurrentLogicalDeviceAgents; i++ {
610 wg.Add(1)
611 a := lda.createLogicalDeviceAgent(t)
612 go lda.updateLogicalDeviceConcurrently(t, a, &wg)
613 }
614
615 wg.Wait()
616}