From 722701b8893e0f3c27aa63ab506a32b891dd64d0 Mon Sep 17 00:00:00 2001 From: DylanB95EST Date: Mon, 20 Jun 2022 13:45:19 +0100 Subject: Retry Module-Sync based on from last failure Retry algorithm for module-sync based on last failure Poll Lock Reason, check if lock has surpassed minimum time based on last update time and lock reason Issue-ID: CPS-1076 Change-Id: Ifbbabd2b403f88f1bbe3fae3f125b1e9cb2091aa Signed-off-by: DylanB95EST --- .../ncmp/api/inventory/sync/ModuleSyncSpec.groovy | 17 +++++++++++++---- .../ncmp/api/inventory/sync/SyncUtilsSpec.groovy | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'cps-ncmp-service/src/test/groovy/org') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy index 614783efd..0f89a428b 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy @@ -90,16 +90,25 @@ class ModuleSyncSpec extends Specification { } - def 'Schedule a Cm-Handle Sync for LOCKED with reason LOCKED_MISBEHAVING Cm-Handles '() { + def 'Schedule a Cm-Handle Sync for LOCKED with reason LOCKED_MISBEHAVING Cm-Handles with #scenario'() { given: 'cm handles in an locked state' def compositeState = new CompositeStateBuilder().withCmHandleState(CmHandleState.LOCKED) - .withLockReason(LockReasonCategory.LOCKED_MISBEHAVING, '').build() + .withLockReason(LockReasonCategory.LOCKED_MISBEHAVING, '').withLastUpdatedTimeNow().build() def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', compositeState: compositeState) and: 'sync utilities return a cm handle twice' mockSyncUtils.getLockedMisbehavingYangModelCmHandles() >> [yangModelCmHandle, yangModelCmHandle] + and: 'inventory persistence returns the composite state of the cm handle' + mockInventoryPersistence.getCmHandleState(yangModelCmHandle.getId()) >> compositeState + and: 'sync utils retry locked cm handle returns #isReadyForRetry' + mockSyncUtils.isReadyForRetry(compositeState) >>> isReadyForRetry when: 'module sync poll is executed' - objectUnderTest.executeLockedMisbehavingCmHandlePoll() + objectUnderTest.executeLockedCmHandlePoll() then: 'the first cm handle is updated to state "ADVISED" from "READY"' - 2 * mockInventoryPersistence.saveCmHandleState(yangModelCmHandle.id, compositeState) + expectedNumberOfInvocationsToSaveCmHandleState * mockInventoryPersistence.saveCmHandleState(yangModelCmHandle.id, compositeState) + where: + scenario | isReadyForRetry || expectedNumberOfInvocationsToSaveCmHandleState + 'retry locked cm handle once' | [true, false] || 1 + 'retry locked cm handle twice' | [true, true] || 2 + 'do not retry locked cm handle' | [false, false] || 0 } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy index 2c45ab769..dd299146f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy @@ -27,6 +27,7 @@ import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations import org.onap.cps.ncmp.api.impl.operations.DmiOperations import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState +import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder import org.onap.cps.ncmp.api.inventory.InventoryPersistence import org.onap.cps.ncmp.api.inventory.LockReasonCategory import org.onap.cps.ncmp.api.inventory.SyncState @@ -38,6 +39,9 @@ import org.springframework.http.ResponseEntity import spock.lang.Shared import spock.lang.Specification +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter + class SyncUtilsSpec extends Specification{ def mockInventoryPersistence = Mock(InventoryPersistence) @@ -48,6 +52,9 @@ class SyncUtilsSpec extends Specification{ def objectUnderTest = new SyncUtils(mockInventoryPersistence, mockDmiDataOperations, jsonObjectMapper) + @Shared + def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(OffsetDateTime.now()) + @Shared def dataNode = new DataNode(leaves: ['id': 'cm-handle-123']) @@ -94,6 +101,21 @@ class SyncUtilsSpec extends Specification{ result[0].id == 'cm-handle-123' } + def 'Retry Locked Cm-Handle where the last update time is #scenario'() { + when: 'retry locked cm handle is invoked' + def result = objectUnderTest.isReadyForRetry(new CompositeStateBuilder() + .withLockReason(LockReasonCategory.LOCKED_MISBEHAVING, details) + .withLastUpdatedTime(lastUpdateTime).build()) + then: 'result returns #expectedResult' + result == expectedResult + where: + scenario | lastUpdateTime | details || expectedResult + 'is the first attempt' | '1900-01-01T00:00:00.000+0100' | 'First Attempt' || true + 'is greater than one minute' | '1900-01-01T00:00:00.000+0100' | 'Attempt #1 failed:' || true + 'is less than eight minutes' | formattedDateAndTime | 'Attempt #3 failed:' || false + } + + def 'Get a Cm-Handle where Operational Sync state is UnSynchronized and Cm-handle state is READY and #scenario'() { given: 'the inventory persistence service returns a collection of data nodes' mockInventoryPersistence.getCmHandlesByOperationalSyncState(SyncState.UNSYNCHRONIZED) >> unSynchronizedDataNodes -- cgit 1.2.3-korg