blob: eb65673b1ec62f6898a6040dcb5328dc1acc785f [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
Kent Hagermanf5a67352020-04-30 15:15:26 -040025 "github.com/gogo/protobuf/proto"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070026 "github.com/opencord/voltha-go/db/model"
Kent Hagermanf5a67352020-04-30 15:15:26 -040027 "github.com/opencord/voltha-go/rw_core/config"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070028 "github.com/opencord/voltha-go/rw_core/core/adapter"
Kent Hagermanf5a67352020-04-30 15:15:26 -040029 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
Mahir Gunyeladdb66a2020-04-29 18:08:50 -070030 "github.com/opencord/voltha-lib-go/v3/pkg/db"
31 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080032 "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))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400165 assert.Equal(t, updatedLogicalPorts[0], newPorts[updatedLogicalPorts[0].Id])
166 assert.Equal(t, updatedLogicalPorts[1], newPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400167}
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))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400189 assert.Equal(t, currentLogicalPorts[0], deletedPorts[currentLogicalPorts[0].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400190}
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))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400273 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
274 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400275}
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))
Kent Hagerman8ad29952020-04-21 11:48:02 -0400358 assert.Equal(t, updatedLogicalPorts[0], changedPorts[updatedLogicalPorts[0].Id])
359 assert.Equal(t, updatedLogicalPorts[1], changedPorts[updatedLogicalPorts[1].Id])
360 assert.Equal(t, currentLogicalPorts[2], deletedPorts[currentLogicalPorts[2].Id])
khenaidoo2bc48282019-07-16 18:13:46 -0400361}
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)
Kent Hagermanf5a67352020-04-30 15:15:26 -0400483 proxy := model.NewDBPath(backend)
Kent Hagerman2b216042020-04-03 18:28:56 -0400484 adapterMgr := adapter.NewAdapterManager(proxy, lda.coreInstanceID, lda.kClient)
485
Kent Hagerman45a13e42020-04-13 12:23:50 -0400486 lda.deviceMgr, lda.logicalDeviceMgr = NewManagers(proxy, adapterMgr, lda.kmp, endpointMgr, cfg.CorePairTopic, lda.coreInstanceID, cfg.DefaultCoreTimeout)
Kent Hagerman2b216042020-04-03 18:28:56 -0400487 if err = lda.kmp.Start(); err != nil {
488 logger.Fatal("Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530489 }
Kent Hagerman2f0d0552020-04-23 17:28:52 -0400490 adapterMgr.Start(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500491}
492
493func (lda *LDATest) stopAll() {
494 if lda.kClient != nil {
495 lda.kClient.Stop()
496 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400497 if lda.kmp != nil {
498 lda.kmp.Stop()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500499 }
500 if lda.etcdServer != nil {
501 stopEmbeddedEtcdServer(lda.etcdServer)
502 }
503}
504
Kent Hagerman2b216042020-04-03 18:28:56 -0400505func (lda *LDATest) createLogicalDeviceAgent(t *testing.T) *LogicalAgent {
506 lDeviceMgr := lda.logicalDeviceMgr
507 deviceMgr := lda.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500508 clonedLD := proto.Clone(lda.logicalDevice).(*voltha.LogicalDevice)
509 clonedLD.Id = com.GetRandomString(10)
510 clonedLD.DatapathId = rand.Uint64()
Kent Hagermanf5a67352020-04-30 15:15:26 -0400511 lDeviceAgent := newLogicalAgent(clonedLD.Id, clonedLD.Id, clonedLD.RootDeviceId, lDeviceMgr, deviceMgr, lDeviceMgr.dbProxy, lDeviceMgr.ldProxy, lDeviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500512 lDeviceAgent.logicalDevice = clonedLD
Kent Hagermanf5a67352020-04-30 15:15:26 -0400513 err := lDeviceAgent.ldProxy.Set(context.Background(), clonedLD.Id, clonedLD)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530514 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500515 lDeviceMgr.addLogicalDeviceAgentToMap(lDeviceAgent)
516 return lDeviceAgent
517}
518
Kent Hagerman2b216042020-04-03 18:28:56 -0400519func (lda *LDATest) updateLogicalDeviceConcurrently(t *testing.T, ldAgent *LogicalAgent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400520 originalLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500521 assert.NotNil(t, originalLogicalDevice)
522 var localWG sync.WaitGroup
523
524 // Change the state of the first port to FAILED
525 localWG.Add(1)
526 go func() {
npujar467fe752020-01-16 20:17:45 +0530527 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[0].DeviceId, lda.logicalDevice.Ports[0].DevicePortNo, voltha.OperStatus_FAILED)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500528 assert.Nil(t, err)
529 localWG.Done()
530 }()
531
532 // Change the state of the second port to TESTING
533 localWG.Add(1)
534 go func() {
npujar467fe752020-01-16 20:17:45 +0530535 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[1].DeviceId, lda.logicalDevice.Ports[1].DevicePortNo, voltha.OperStatus_TESTING)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500536 assert.Nil(t, err)
537 localWG.Done()
538 }()
539
540 // Change the state of the third port to UNKNOWN and then back to ACTIVE
541 localWG.Add(1)
542 go func() {
npujar467fe752020-01-16 20:17:45 +0530543 err := ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_UNKNOWN)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500544 assert.Nil(t, err)
npujar467fe752020-01-16 20:17:45 +0530545 err = ldAgent.updatePortState(context.Background(), lda.logicalDevice.Ports[2].DeviceId, lda.logicalDevice.Ports[2].DevicePortNo, voltha.OperStatus_ACTIVE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500546 assert.Nil(t, err)
547 localWG.Done()
548 }()
549
550 // Add a meter to the logical device
551 meterMod := &ofp.OfpMeterMod{
552 Command: ofp.OfpMeterModCommand_OFPMC_ADD,
553 Flags: rand.Uint32(),
554 MeterId: rand.Uint32(),
555 Bands: []*ofp.OfpMeterBandHeader{
556 {Type: ofp.OfpMeterBandType_OFPMBT_EXPERIMENTER,
557 Rate: rand.Uint32(),
558 BurstSize: rand.Uint32(),
559 Data: nil,
560 },
561 },
562 }
563 localWG.Add(1)
564 go func() {
npujar467fe752020-01-16 20:17:45 +0530565 err := ldAgent.meterAdd(context.Background(), meterMod)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500566 assert.Nil(t, err)
567 localWG.Done()
568 }()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500569 // wait for go routines to be done
570 localWG.Wait()
Mahir Gunyeladdb66a2020-04-29 18:08:50 -0700571 meterEntry := fu.MeterEntryFromMeterMod(meterMod)
572
Kent Hagerman433a31a2020-05-20 19:04:48 -0400573 meterHandle, have := ldAgent.meterLoader.Lock(meterMod.MeterId)
574 assert.Equal(t, have, true)
575 if have {
576 assert.True(t, proto.Equal(meterEntry, meterHandle.GetReadOnly()))
577 meterHandle.Unlock()
578 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500579
580 expectedChange := proto.Clone(originalLogicalDevice).(*voltha.LogicalDevice)
581 expectedChange.Ports[0].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
582 expectedChange.Ports[0].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
583 expectedChange.Ports[1].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
584 expectedChange.Ports[1].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
585 expectedChange.Ports[2].OfpPort.Config = originalLogicalDevice.Ports[0].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
586 expectedChange.Ports[2].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
khenaidoo442e7c72020-03-10 16:13:48 -0400587 updatedLogicalDevice, _ := ldAgent.GetLogicalDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500588 assert.NotNil(t, updatedLogicalDevice)
589 assert.True(t, proto.Equal(expectedChange, updatedLogicalDevice))
590 globalWG.Done()
591}
592
593func TestConcurrentLogicalDeviceUpdate(t *testing.T) {
594 lda := newLDATest()
595 assert.NotNil(t, lda)
596 defer lda.stopAll()
597
598 // Start the Core
599 lda.startCore(false)
600
601 var wg sync.WaitGroup
khenaidoo442e7c72020-03-10 16:13:48 -0400602 numConCurrentLogicalDeviceAgents := 3
khenaidoo6e55d9e2019-12-12 18:26:26 -0500603 for i := 0; i < numConCurrentLogicalDeviceAgents; i++ {
604 wg.Add(1)
605 a := lda.createLogicalDeviceAgent(t)
606 go lda.updateLogicalDeviceConcurrently(t, a, &wg)
607 }
608
609 wg.Wait()
610}