From 41de6d64d89b8caeddb88389cf49fb2fb9e368d4 Mon Sep 17 00:00:00 2001 From: kissand Date: Thu, 21 Jul 2022 14:53:37 +0200 Subject: Distributed datastore solution for Data Sync Watchdog - update lombok config to handle Qualifier annotation - update Semaphore config to use ConcurrentMap - update SyncUtils to return a list of cm handles - update DataSyncWatchdog and ModuleSyncWatchdog with Qualifier - update DataSyncWatchdog to handle a list of cm handles - Use get with xpath to check cm handle state Issue-ID: CPS-1015 Change-Id: Icb39bd29f89e0020d49a1f8960476ffe81b12362 Signed-off-by: kissand --- .../NetworkCmProxyCmHandlerQueryServiceSpec.groovy | 7 +- .../SynchronizationSemaphoresConfigSpec.groovy | 14 +-- .../ncmp/api/inventory/CmHandleQueriesSpec.groovy | 18 ++-- .../ncmp/api/inventory/sync/DataSyncSpec.groovy | 109 --------------------- .../api/inventory/sync/DataSyncWatchdogSpec.groovy | 105 ++++++++++++++++++++ .../ncmp/api/inventory/sync/SyncUtilsSpec.groovy | 29 +++--- 6 files changed, 139 insertions(+), 143 deletions(-) delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy (limited to 'cps-ncmp-service/src/test') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy index 19c5049021..f1294ced7a 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy @@ -21,7 +21,6 @@ package org.onap.cps.ncmp.api.impl import org.onap.cps.cpspath.parser.PathParsingException -import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService import org.onap.cps.ncmp.api.inventory.InventoryPersistence import org.onap.cps.ncmp.api.inventory.CmHandleQueries import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle @@ -52,7 +51,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification { def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']]) cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties]) and: 'cmHandleQueries returns a non null query result' - cmHandleQueries.getCmHandleDataNodesByCpsPath('/some/cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [new DataNode(leaves: ['id':'some-cmhandle-id'])] + cmHandleQueries.queryCmHandleDataNodesByCpsPath('/some/cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [new DataNode(leaves: ['id':'some-cmhandle-id'])] and: 'CmHandleQueries returns cmHandles with the relevant query result' cmHandleQueries.combineCmHandleQueries(*_) >> ['PNFDemo1': new NcmpServiceCmHandle(cmHandleId: 'PNFDemo1'), 'PNFDemo3': new NcmpServiceCmHandle(cmHandleId: 'PNFDemo3')] when: 'the query is executed for both cm handle ids and details' @@ -70,7 +69,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification { def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']]) cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties]) and: 'cmHandleQueries throws a path parsing exception' - cmHandleQueries.getCmHandleDataNodesByCpsPath('/some/cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> { throw thrownException } + cmHandleQueries.queryCmHandleDataNodesByCpsPath('/some/cps/path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> { throw thrownException } when: 'the query is executed for both cm handle ids and details' objectUnderTest.queryCmHandleIds(cmHandleQueryParameters) objectUnderTest.queryCmHandles(cmHandleQueryParameters) @@ -134,7 +133,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification { and: 'cmHandles are returned from the module names query' inventoryPersistence.queryAnchors(['some-module-name']) >> anchorsForModuleQuery and: 'cmHandleQueries returns a datanode result' - 2 * cmHandleQueries.getCmHandleDataNodesByCpsPath(*_) >> [someCmHandleDataNode] + 2 * cmHandleQueries.queryCmHandleDataNodesByCpsPath(*_) >> [someCmHandleDataNode] when: 'the query is executed for both cm handle ids and details' def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters) def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationSemaphoresConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationSemaphoresConfigSpec.groovy index fe7ed9eeb3..ea84b440f3 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationSemaphoresConfigSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationSemaphoresConfigSpec.groovy @@ -31,19 +31,19 @@ import spock.lang.Specification class SynchronizationSemaphoresConfigSpec extends Specification { @Autowired - private Map moduleSyncSemaphore; + private Map moduleSyncSemaphores; @Autowired - private Map dataSyncSemaphore; + private Map dataSyncSemaphores; def 'Embedded Sync Semaphores'() { - expect: 'system is able to create an instance of ModuleSyncSemaphore' - assert null != moduleSyncSemaphore - and: 'system is able to create an instance of DataSyncSemaphore' - assert null != dataSyncSemaphore + expect: 'system is able to create an instance of ModuleSyncSemaphores' + assert null != moduleSyncSemaphores + and: 'system is able to create an instance of DataSyncSemaphores' + assert null != dataSyncSemaphores and: 'we have 2 instances' assert Hazelcast.allHazelcastInstances.size() == 2 and: 'the names match' - assert Hazelcast.allHazelcastInstances.name == ['moduleSyncSemaphore', 'dataSyncSemaphore'] + assert Hazelcast.allHazelcastInstances.name == ['moduleSyncSemaphores', 'dataSyncSemaphores'] } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy index 10a5d62461..ff173300a6 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy @@ -92,31 +92,31 @@ class CmHandleQueriesSpec extends Specification { cpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry', '//state[@cm-handle-state="ADVISED"]/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS) >> sampleDataNodes when: 'cm handles are fetched by state' - def result = objectUnderTest.getCmHandlesByState(cmHandleState) + def result = objectUnderTest.queryCmHandlesByState(cmHandleState) then: 'the returned result matches the result from the persistence service' assert result == sampleDataNodes } - def 'Get Cm Handles By State and Cm-Handle Id'() { + def 'Get Cm Handles state by Cm-Handle Id'() { given: 'a cm handle state to query' def cmHandleState = CmHandleState.READY and: 'cps data service returns a list of data nodes' - cpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry', - '//cm-handles[@id=\'some-cm-handle\']/state[@cm-handle-state="'+ 'READY'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes + cpsDataPersistenceService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + '/dmi-registry/cm-handles[@id=\'some-cm-handle\']/state', OMIT_DESCENDANTS) >> new DataNode(leaves: ['cm-handle-state': 'READY']) when: 'cm handles are fetched by state and id' - def result = objectUnderTest.getCmHandlesByIdAndState('some-cm-handle', cmHandleState) + def result = objectUnderTest.getCmHandleState('some-cm-handle') then: 'the returned result is a list of data nodes returned by cps data service' - assert result == sampleDataNodes + assert result == new DataNode(leaves: ['cm-handle-state': 'READY']) } - def 'Get Cm Handles By Operational Sync State : UNSYNCHRONIZED'() { + def 'Retrieve Cm Handles By Operational Sync State : UNSYNCHRONIZED'() { given: 'a cm handle state to query' def cmHandleState = CmHandleState.READY and: 'cps data service returns a list of data nodes' cpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry', '//state/datastores/operational[@sync-state="'+'UNSYNCHRONIZED'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes when: 'cm handles are fetched by the UNSYNCHRONIZED operational sync state' - def result = objectUnderTest.getCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) + def result = objectUnderTest.queryCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) then: 'the returned result is a list of data nodes returned by cps data service' assert result == sampleDataNodes } @@ -130,7 +130,7 @@ class CmHandleQueriesSpec extends Specification { cpsPath + '/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS) >> Arrays.asList(cmHandleDataNode) when: 'get cm handles by cps path is invoked' - def result = objectUnderTest.getCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) + def result = objectUnderTest.queryCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) then: 'the returned result is a list of data nodes returned by cps data service' assert result.contains(cmHandleDataNode) } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy deleted file mode 100644 index 650a779a42..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.cps.ncmp.api.inventory.sync - -import org.onap.cps.api.CpsDataService -import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle -import org.onap.cps.ncmp.api.inventory.CmHandleState -import org.onap.cps.ncmp.api.inventory.CompositeState -import org.onap.cps.ncmp.api.inventory.InventoryPersistence -import org.onap.cps.ncmp.api.inventory.DataStoreSyncState -import spock.lang.Shared -import spock.lang.Specification - -class DataSyncSpec extends Specification { - - def mockInventoryPersistence = Mock(InventoryPersistence) - - def mockCpsDataService = Mock(CpsDataService) - - def mockSyncUtils = Mock(SyncUtils) - - @Shared - def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}' - - def objectUnderTest = new DataSyncWatchdog(mockInventoryPersistence, mockCpsDataService, mockSyncUtils) - - def compositeState = getCompositeState() - - def yangModelCmHandle1 = createSampleYangModelCmHandle('some-cm-handle-1') - - def yangModelCmHandle2 = createSampleYangModelCmHandle('some-cm-handle-2') - - def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED'() { - given: 'sample resource data' - def resourceData = jsonString - and: 'sync utilities return a cm handle twice' - mockSyncUtils.getAnUnSynchronizedReadyCmHandle() >>> [yangModelCmHandle1, yangModelCmHandle2, null] - when: 'data sync poll is executed' - objectUnderTest.executeUnSynchronizedReadyCmHandlePoll() - then: 'the inventory persistence cm handle returns a composite state for the first cm handle' - 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-1') >> compositeState - and: 'the sync util returns first resource data' - 1 * mockSyncUtils.getResourceData('some-cm-handle-1') >> resourceData - and: 'the cm-handle data is saved' - 1 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-1', jsonString, _) - and: 'the first cm handle operational sync state is updated' - 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-1', compositeState) - then: 'the inventory persistence cm handle returns a composite state for the second cm handle' - 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-2') >> compositeState - and: 'the sync util returns first resource data' - 1 * mockSyncUtils.getResourceData('some-cm-handle-2') >> resourceData - and: 'the cm-handle data is saved' - 1 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-2', jsonString, _) - and: 'the second cm handle operational sync state is updated from "UNSYNCHRONIZED" to "SYNCHRONIZED"' - 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-2', compositeState) - } - - def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED which return empty data from Node because #scenario'() { - given: 'a yang model cm handle' - def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', compositeState: new CompositeState(dataSyncEnabled: dataSyncEnabled)) - and: 'sync utilities returns a single cm handle' - mockSyncUtils.getAnUnSynchronizedReadyCmHandle() >>> [yangModelCmHandle, null] - when: 'data sync poll is executed' - objectUnderTest.executeUnSynchronizedReadyCmHandlePoll() - then: 'the inventory persistence cm handle returns a composite state for the first cm handle' - 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle') >> compositeState - and: 'the sync util returns first resource data' - 1 * mockSyncUtils.getResourceData('some-cm-handle') >> resourceData - and: 'the cm-handle data is not saved' - 0 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-1', jsonString, _) - where: - scenario | dataSyncEnabled | resourceData - 'data sync is not enabled' | false | jsonString - 'resource data is null' | true | null - 'data sync is not enabled and resource data is null' | false | null - } - - def createSampleYangModelCmHandle(cmHandleId) { - def compositeState = getCompositeState() - return new YangModelCmHandle(id: cmHandleId, compositeState: compositeState) - } - - def getCompositeState() { - def cmHandleState = CmHandleState.READY - def compositeState = new CompositeState(cmHandleState: cmHandleState, dataSyncEnabled: true) - compositeState.setDataStores(CompositeState.DataStores.builder() - .operationalDataStore(CompositeState.Operational.builder().dataStoreSyncState(DataStoreSyncState.SYNCHRONIZED) - .build()).build()) - return compositeState - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy new file mode 100644 index 0000000000..605381970d --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy @@ -0,0 +1,105 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.api.inventory.sync + +import org.onap.cps.api.CpsDataService +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.inventory.CmHandleState +import org.onap.cps.ncmp.api.inventory.CompositeState +import org.onap.cps.ncmp.api.inventory.InventoryPersistence +import org.onap.cps.ncmp.api.inventory.DataStoreSyncState +import spock.lang.Specification +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentMap + +class DataSyncWatchdogSpec extends Specification { + + def mockInventoryPersistence = Mock(InventoryPersistence) + + def mockCpsDataService = Mock(CpsDataService) + + def mockSyncUtils = Mock(SyncUtils) + + def stubbedMap = Stub(ConcurrentMap) + + def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}' + + def objectUnderTest = new DataSyncWatchdog(mockInventoryPersistence, mockCpsDataService, mockSyncUtils, stubbedMap as ConcurrentHashMap) + + def compositeState = getCompositeState() + + def yangModelCmHandle1 = createSampleYangModelCmHandle('some-cm-handle-1') + + def yangModelCmHandle2 = createSampleYangModelCmHandle('some-cm-handle-2') + + def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED'() { + given: 'sample resource data' + def resourceData = jsonString + and: 'sync utilities return a cm handle twice' + mockSyncUtils.getUnsynchronizedReadyCmHandles() >> [yangModelCmHandle1, yangModelCmHandle2] + when: 'data sync poll is executed' + objectUnderTest.executeUnSynchronizedReadyCmHandlePoll() + then: 'the inventory persistence cm handle returns a composite state for the first cm handle' + 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-1') >> compositeState + and: 'the sync util returns first resource data' + 1 * mockSyncUtils.getResourceData('some-cm-handle-1') >> resourceData + and: 'the cm-handle data is saved' + 1 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-1', jsonString, _) + and: 'the first cm handle operational sync state is updated' + 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-1', compositeState) + then: 'the inventory persistence cm handle returns a composite state for the second cm handle' + 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-2') >> compositeState + and: 'the sync util returns first resource data' + 1 * mockSyncUtils.getResourceData('some-cm-handle-2') >> resourceData + and: 'the cm-handle data is saved' + 1 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-2', jsonString, _) + and: 'the second cm handle operational sync state is updated from "UNSYNCHRONIZED" to "SYNCHRONIZED"' + 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-2', compositeState) + } + + def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED which return empty data from Node'() { + given: 'cm handles in an ready state and operational sync state in unsynchronized' + and: 'sync utilities return a cm handle twice' + mockSyncUtils.getUnsynchronizedReadyCmHandles() >> [yangModelCmHandle1] + when: 'data sync poll is executed' + objectUnderTest.executeUnSynchronizedReadyCmHandlePoll() + then: 'the inventory persistence cm handle returns a composite state for the first cm handle' + 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-1') >> compositeState + and: 'the sync util returns first resource data' + 1 * mockSyncUtils.getResourceData('some-cm-handle-1') >> null + and: 'the cm-handle data is not saved' + 0 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-1', jsonString, _) + } + + def createSampleYangModelCmHandle(cmHandleId) { + def compositeState = getCompositeState() + return new YangModelCmHandle(id: cmHandleId, compositeState: compositeState) + } + + def getCompositeState() { + def cmHandleState = CmHandleState.READY + def compositeState = new CompositeState(cmHandleState: cmHandleState) + compositeState.setDataStores(CompositeState.DataStores.builder() + .operationalDataStore(CompositeState.Operational.builder().dataStoreSyncState(DataStoreSyncState.SYNCHRONIZED) + .build()).build()) + return compositeState + } +} 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 fb4ca3933d..52fb110b33 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 @@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper 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.CmHandleQueries +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder @@ -54,7 +55,7 @@ class SyncUtilsSpec extends Specification{ def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) - def objectUnderTest = new SyncUtils(mockInventoryPersistence, mockCmHandleQueries, mockDmiDataOperations, jsonObjectMapper) + def objectUnderTest = new SyncUtils(mockCmHandleQueries, mockDmiDataOperations, jsonObjectMapper) @Shared def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(OffsetDateTime.now()) @@ -68,7 +69,7 @@ class SyncUtilsSpec extends Specification{ def 'Get an advised Cm-Handle where ADVISED cm handle #scenario'() { given: 'the inventory persistence service returns a collection of data nodes' - mockCmHandleQueries.getCmHandlesByState(CmHandleState.ADVISED) >> dataNodeCollection + mockCmHandleQueries.queryCmHandlesByState(CmHandleState.ADVISED) >> dataNodeCollection and: 'we have some additional (dmi, private) properties' dataNodeAdditionalProperties.xpath = dataNode.xpath + '/additional-properties[@name="dmiProp1"]' dataNode.childDataNodes = [dataNodeAdditionalProperties] @@ -106,7 +107,7 @@ class SyncUtilsSpec extends Specification{ def 'Get all locked Cm-Handle where Lock Reason is LOCKED_MODULE_SYNC_FAILED cm handle #scenario'() { given: 'the cps (persistence service) returns a collection of data nodes' - mockCmHandleQueries.getCmHandleDataNodesByCpsPath( + mockCmHandleQueries.queryCmHandleDataNodesByCpsPath( '//lock-reason[@reason="LOCKED_MODULE_SYNC_FAILED"]', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode] when: 'get locked Misbehaving cm handle is called' @@ -132,21 +133,21 @@ class SyncUtilsSpec extends Specification{ } - def 'Get a Cm-Handle where Operational Sync state is UnSynchronized and Cm-handle state is READY and #scenario'() { + def 'Get a Cm-Handle where #scenario'() { given: 'the inventory persistence service returns a collection of data nodes' - mockCmHandleQueries.getCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) >> unSynchronizedDataNodes - mockCmHandleQueries.getCmHandlesByIdAndState("cm-handle-123", CmHandleState.READY) >> readyDataNodes + mockCmHandleQueries.queryCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) >> unSynchronizedDataNodes + mockCmHandleQueries.cmHandleHasState('cm-handle-123', CmHandleState.READY) >> cmHandleHasState when: 'get advised cm handles are fetched' - objectUnderTest.getAnUnSynchronizedReadyCmHandle() + def yangModelCollection = objectUnderTest.getUnsynchronizedReadyCmHandles() then: 'the returned data node collection is the correct size' - readyDataNodes.size() == expectedDataNodeSize - and: 'get yang model cm handles is invoked the correct number of times' - expectedCallsToGetYangModelCmHandle * mockInventoryPersistence.getYangModelCmHandle('cm-handle-123') + yangModelCollection.size() == expectedDataNodeSize + and: 'the result contains the correct data' + yangModelCollection.stream().map(yangModel -> yangModel.id).collect(Collectors.toSet()) == expectedYangModelCollectionIds where: 'the following scenarios are used' - scenario | unSynchronizedDataNodes | readyDataNodes || expectedCallsToGetYangModelCmHandle | expectedDataNodeSize - 'exists' | [dataNode] | [dataNode] || 1 | 1 - 'unsynchronized exist but not ready' | [dataNode] | [] || 0 | 0 - 'does not exist' | [] | [] || 0 | 0 + scenario | unSynchronizedDataNodes | cmHandleHasState || expectedDataNodeSize | expectedYangModelCollectionIds + 'a Cm-Handle unsynchronized and ready' | [dataNode] | true || 1 | ['cm-handle-123'] as Set + 'a Cm-Handle unsynchronized but not ready' | [dataNode] | false || 0 | [] as Set + 'all Cm-Handle synchronized' | [] | false || 0 | [] as Set } def 'Get resource data through DMI Operations #scenario'() { -- cgit 1.2.3-korg