aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/test/groovy/org
diff options
context:
space:
mode:
authormpriyank <priyank.maheshwari@est.tech>2024-11-27 14:43:28 +0000
committermpriyank <priyank.maheshwari@est.tech>2024-12-19 15:38:36 +0000
commita7206655a004659bd1251c70db0acfd0f58e40d4 (patch)
tree852a2331753c722e46c03ac6b508a14b646f24e1 /cps-ncmp-service/src/test/groovy/org
parent40578d56733247540a09b6bbf000181b46b5c1fc (diff)
Cps and Ncmp distributed lock for various use cases
- introduced cpsAndNcmpLock to be used for any use case needing coordination. Since it can be used for any use case hence placing the class accordingly. - currently lock is being used for populating workQueue. - Removed FencedLock as it was part of CPSubsystem which is moved to hazelcast-enterprise in 5.5.* version onwards. - added info level logging statement to verify just one thread at a time in the critical section - Note : integration test to be part of a separate patch. Issue-ID: CPS-2479 Change-Id: I0f33c7232786c517383e5093fda91fd9a1839021 Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
Diffstat (limited to 'cps-ncmp-service/src/test/groovy/org')
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdogSpec.groovy32
1 files changed, 18 insertions, 14 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdogSpec.groovy
index 4cf07e4c24..a9b88c2d3b 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdogSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdogSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -44,11 +44,11 @@ class ModuleSyncWatchdogSpec extends Specification {
def spiedAsyncTaskExecutor = Spy(AsyncTaskExecutor)
- def mockWorkQueueLock = Mock(Lock)
+ def mockCpsAndNcmpLock = Mock(IMap<String,String>)
def spiedSleeper = Spy(Sleeper)
- def objectUnderTest = new ModuleSyncWatchdog(mockModuleOperationsUtils, moduleSyncWorkQueue , mockModuleSyncStartedOnCmHandles, mockModuleSyncTasks, spiedAsyncTaskExecutor, mockWorkQueueLock, spiedSleeper)
+ def objectUnderTest = new ModuleSyncWatchdog(mockModuleOperationsUtils, moduleSyncWorkQueue , mockModuleSyncStartedOnCmHandles, mockModuleSyncTasks, spiedAsyncTaskExecutor, mockCpsAndNcmpLock, spiedSleeper)
void setup() {
spiedAsyncTaskExecutor.setupThreadPool()
@@ -59,14 +59,16 @@ class ModuleSyncWatchdogSpec extends Specification {
mockModuleOperationsUtils.getAdvisedCmHandleIds() >> createCmHandleIds(numberOfAdvisedCmHandles)
and: 'module sync utilities returns no failed (locked) cm handles'
mockModuleOperationsUtils.getCmHandlesThatFailedModelSyncOrUpgrade() >> []
- and: 'the work queue is not locked'
- mockWorkQueueLock.tryLock() >> true
+ and: 'the work queue can be locked'
+ mockCpsAndNcmpLock.tryLock('workQueueLock') >> true
and: 'the executor has enough available threads'
spiedAsyncTaskExecutor.getAsyncTaskParallelismLevel() >> 3
when: ' module sync is started'
objectUnderTest.moduleSyncAdvisedCmHandles()
then: 'it performs #expectedNumberOfTaskExecutions tasks'
expectedNumberOfTaskExecutions * spiedAsyncTaskExecutor.executeTask(*_)
+ and: 'the executing thread is unlocked'
+ 1 * mockCpsAndNcmpLock.unlock('workQueueLock')
where: 'the following parameter are used'
scenario | numberOfAdvisedCmHandles || expectedNumberOfTaskExecutions
'none at all' | 0 || 0
@@ -80,8 +82,8 @@ class ModuleSyncWatchdogSpec extends Specification {
def 'Module sync cm handles starts with no available threads.'() {
given: 'module sync utilities returns a advise cm handles'
mockModuleOperationsUtils.getAdvisedCmHandleIds() >> createCmHandleIds(1)
- and: 'the work queue is not locked'
- mockWorkQueueLock.tryLock() >> true
+ and: 'the work queue can be locked'
+ mockCpsAndNcmpLock.tryLock('workQueueLock') >> true
and: 'the executor first has no threads but has one thread on the second attempt'
spiedAsyncTaskExecutor.getAsyncTaskParallelismLevel() >>> [ 0, 1 ]
when: ' module sync is started'
@@ -93,8 +95,8 @@ class ModuleSyncWatchdogSpec extends Specification {
def 'Module sync advised cm handle already handled by other thread.'() {
given: 'module sync utilities returns an advised cm handle'
mockModuleOperationsUtils.getAdvisedCmHandleIds() >> createCmHandleIds(1)
- and: 'the work queue is not locked'
- mockWorkQueueLock.tryLock() >> true
+ and: 'the work queue can be locked'
+ mockCpsAndNcmpLock.tryLock('workQueueLock') >> true
and: 'the executor has a thread available'
spiedAsyncTaskExecutor.getAsyncTaskParallelismLevel() >> 1
and: 'the semaphore cache indicates the cm handle is already being processed'
@@ -131,16 +133,18 @@ class ModuleSyncWatchdogSpec extends Specification {
def 'Module Sync Locking.'() {
given: 'module sync utilities returns an advised cm handle'
mockModuleOperationsUtils.getAdvisedCmHandleIds() >> createCmHandleIds(1)
- and: 'can lock is : #canLock'
- mockWorkQueueLock.tryLock() >> canLock
+ and: 'can be locked is : #canLock'
+ mockCpsAndNcmpLock.tryLock('workQueueLock') >> canLock
when: 'attempt to populate the work queue'
objectUnderTest.populateWorkQueueIfNeeded()
then: 'the queue remains empty is #expectQueueRemainsEmpty'
assert moduleSyncWorkQueue.isEmpty() == expectQueueRemainsEmpty
+ and: 'unlock is called only when thread is able to enter the critical section'
+ expectedInvocationToUnlock * mockCpsAndNcmpLock.unlock('workQueueLock')
where: 'the following lock states are applied'
- canLock | expectQueueRemainsEmpty
- false | true
- true | false
+ canLock || expectQueueRemainsEmpty || expectedInvocationToUnlock
+ false || true || 0
+ true || false || 1
}
def 'Sleeper gets interrupted.'() {