summaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/test
diff options
context:
space:
mode:
authorJoseph Keenan <joseph.keenan@est.tech>2022-08-02 12:26:46 +0000
committerGerrit Code Review <gerrit@onap.org>2022-08-02 12:26:46 +0000
commit7a75eea4e388a04d8b67610ef53ed16db75489e6 (patch)
tree75664b32b00cb5df106ec58a15e4c3e0f337b8a3 /cps-ncmp-service/src/test
parentb3c2b74c5a90750978a051cc9c8a6933f77e7948 (diff)
parent82a550f6b080cb50912d93f7b13ba0fc97a95470 (diff)
Merge "Query CmHandles using CPS path"
Diffstat (limited to 'cps-ncmp-service/src/test')
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy192
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy150
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy60
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy21
4 files changed, 266 insertions, 157 deletions
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 7cf572ddb..40ec12da8 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
@@ -20,8 +20,14 @@
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
+import org.onap.cps.spi.FetchDescendantsOption
+import org.onap.cps.spi.exceptions.DataInUseException
+import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.model.Anchor
import org.onap.cps.spi.model.CmHandleQueryServiceParameters
import org.onap.cps.spi.model.ConditionProperties
@@ -32,87 +38,127 @@ import java.util.stream.Collectors
class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
+ def cmHandleQueries = Mock(CmHandleQueries)
def inventoryPersistence = Mock(InventoryPersistence)
- NetworkCmProxyCmHandlerQueryService objectUnderTest = new NetworkCmProxyCmHandlerQueryServiceImpl(inventoryPersistence)
+ def static someCmHandleDataNode = new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'some-cmhandle-id\']', leaves: ['id':'some-cmhandle-id'])
+ def dmiRegistry = new DataNode(xpath: '/dmi-registry', childDataNodes: createDataNodeList(['PNFDemo1', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4']))
- def 'Retrieve cm handles with public properties when #scenario.'() {
- given: 'a condition property'
+ def objectUnderTest = new NetworkCmProxyCmHandlerQueryServiceImpl(cmHandleQueries, inventoryPersistence)
+
+ def 'Retrieve cm handles with cpsPath when combined with no Module Query.'() {
+ given: 'a cmHandleWithCpsPath condition property'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
- def conditionProperties = new ConditionProperties()
- conditionProperties.conditionName = 'hasAllProperties'
- conditionProperties.conditionParameters = publicProperties
+ def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']])
cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
- and: 'mock services'
- mockResponses()
- when: 'a query is execute (with and without Data)'
+ and: 'cmHandleQueries returns a non null query result'
+ cmHandleQueries.getCmHandleDataNodesByCpsPath('/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'
def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
then: 'the correct expected cm handles ids are returned'
- returnedCmHandlesJustIds == expectedCmHandleIds as Set
- and: 'the correct cm handle data objects are returned'
- returnedCmHandlesWithData.stream().map(dataNode -> dataNode.cmHandleId).collect(Collectors.toSet()) == expectedCmHandleIds as Set
+ returnedCmHandlesJustIds == ['PNFDemo1', 'PNFDemo3'] as Set
+ and: 'the correct ncmp service cm handles are returned'
+ returnedCmHandlesWithData.stream().map(CmHandle -> CmHandle.cmHandleId).collect(Collectors.toSet()) == ['PNFDemo1', 'PNFDemo3'] as Set
+ }
+
+ def 'Retrieve cm handles with cpsPath where #scenario.'() {
+ given: 'a cmHandleWithCpsPath condition property'
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
+ 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 }
+ when: 'the query is executed for both cm handle ids and details'
+ objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
+ objectUnderTest.queryCmHandles(cmHandleQueryParameters)
+ then: 'a data validation exception is thrown'
+ thrown(expectedException)
where: 'the following data is used'
- scenario | publicProperties || expectedCmHandleIds
- 'single property matches' | [['Contact' : 'newemailforstore@bookstore.com']] || ['PNFDemo1', 'PNFDemo2', 'PNFDemo4']
- 'public property does not match' | [['wont_match' : 'wont_match']] || []
- '2 properties, only one match' | [['Contact' : 'newemailforstore@bookstore.com'], ['Contact2': 'newemailforstore2@bookstore.com']] || ['PNFDemo4']
- '2 properties, no matches' | [['Contact' : 'newemailforstore@bookstore.com'], ['Contact2': '']] || []
+ scenario | thrownException || expectedException
+ 'a PathParsingException is thrown' | new PathParsingException('some message', 'some details') || DataValidationException
+ 'any other Exception is thrown' | new DataInUseException('some message', 'some details') || DataInUseException
}
- def 'Retrieve cm handles with module names when #scenario.'() {
- given: 'a condition property'
+ def 'Query cm handles with public properties when combined with empty modules query result.'() {
+ given: 'a public properties condition property'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
- def conditionProperties = new ConditionProperties()
- conditionProperties.conditionName = 'hasAllModules'
- conditionProperties.conditionParameters = moduleNames
+ def conditionProperties = createConditionProperties('hasAllProperties', [['some-property-key': 'some-property-value']])
cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
- and: 'mock services'
- mockResponses()
- when: 'the service is invoked'
+ 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'
def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
- then: 'the correct expected cm handles are returned'
+ then: 'the correct expected cm handles ids are returned'
+ returnedCmHandlesJustIds == ['PNFDemo1', 'PNFDemo3'] as Set
+ and: 'the correct cm handle data objects are returned'
+ returnedCmHandlesWithData.stream().map(dataNode -> dataNode.cmHandleId).collect(Collectors.toSet()) == ['PNFDemo1', 'PNFDemo3'] as Set
+ }
+
+ def 'Retrieve cm handles with module names when #scenario from query.'() {
+ given: 'a modules condition property'
+ def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
+ def conditionProperties = createConditionProperties('hasAllModules', [['moduleName': 'some-module-name']])
+ cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
+ and: 'null is returned from the state and public property queries'
+ cmHandleQueries.combineCmHandleQueries(*_) >> null
+ and: '#scenario from the modules query'
+ inventoryPersistence.queryAnchors(*_) >> returnedAnchors
+ and: 'the same cmHandles are returned from the persistence service layer'
+ returnedAnchors.size() * inventoryPersistence.getDataNode(*_) >> returnedCmHandles
+ when: 'the query is executed for both cm handle ids and details'
+ def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
+ def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
+ then: 'the correct expected cm handles ids are returned'
returnedCmHandlesJustIds == expectedCmHandleIds as Set
+ and: 'the correct cm handle data objects are returned'
returnedCmHandlesWithData.stream().map(dataNode -> dataNode.cmHandleId).collect(Collectors.toSet()) == expectedCmHandleIds as Set
where: 'the following data is used'
- scenario | moduleNames || expectedCmHandleIds
- 'single matching module name' | [['moduleName' : 'MODULE-NAME-001']] || ['PNFDemo3', 'PNFDemo1', 'PNFDemo2']
- 'module name dont match' | [['moduleName' : 'MODULE-NAME-004']] || []
- '2 module names, only one match' | [['moduleName' : 'MODULE-NAME-002'], ['moduleName': 'MODULE-NAME-003']] || ['PNFDemo4']
- '2 module names, no matches' | [['moduleName' : 'MODULE-NAME-002'], ['moduleName': 'MODULE-NAME-004']] || []
+ scenario | returnedAnchors | returnedCmHandles || expectedCmHandleIds
+ 'One anchor returned' | [new Anchor(name: 'some-cmhandle-id')] | someCmHandleDataNode || ['some-cmhandle-id']
+ 'No anchors are returned' | [] | null || []
}
def 'Retrieve cm handles with combined queries when #scenario.'() {
- given: 'condition properties'
+ given: 'all condition properties used'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
- def conditionProperties1 = new ConditionProperties()
- conditionProperties1.conditionName = 'hasAllProperties'
- conditionProperties1.conditionParameters = publicProperties
- def conditionProperties2 = new ConditionProperties()
- conditionProperties2.conditionName = 'hasAllModules'
- conditionProperties2.conditionParameters = moduleNames
- cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties1,conditionProperties2])
- and: 'mock services'
- mockResponses()
- when: 'the service is invoked'
+ def conditionPubProps = createConditionProperties('hasAllProperties', [['some-property-key': 'some-property-value']])
+ def conditionModules = createConditionProperties('hasAllModules', [['moduleName': 'some-module-name']])
+ def conditionState = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']])
+ cmHandleQueryParameters.setCmHandleQueryParameters([conditionPubProps, conditionModules, conditionState])
+ and: 'cmHandles are returned from the state and public property combined queries'
+ cmHandleQueries.combineCmHandleQueries(*_) >> combinedQueryMap
+ 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]
+ when: 'the query is executed for both cm handle ids and details'
def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
- then: 'the correct expected cm handles are returned'
+ then: 'the correct expected cm handles ids are returned'
returnedCmHandlesJustIds == expectedCmHandleIds as Set
- returnedCmHandlesWithData.stream().map(d -> d.cmHandleId).collect(Collectors.toSet()) == expectedCmHandleIds as Set
+ and: 'the correct cm handle data objects are returned'
+ returnedCmHandlesWithData.stream().map(dataNode -> dataNode.cmHandleId).collect(Collectors.toSet()) == expectedCmHandleIds as Set
where: 'the following data is used'
- scenario | moduleNames | publicProperties || expectedCmHandleIds
- 'particularly intersect' | [['moduleName' : 'MODULE-NAME-001']] | [['Contact' : 'newemailforstore@bookstore.com']] || ['PNFDemo1', 'PNFDemo2']
- 'empty intersect' | [['moduleName' : 'MODULE-NAME-004']] | [['Contact' : 'newemailforstore@bookstore.com']] || []
- 'total intersect' | [['moduleName' : 'MODULE-NAME-002']] | [['Contact2' : 'newemailforstore2@bookstore.com']] || ['PNFDemo4']
+ scenario | combinedQueryMap | anchorsForModuleQuery || expectedCmHandleIds
+ 'combined and modules queries intersect' | ['PNFDemo1' : new NcmpServiceCmHandle(cmHandleId:'PNFDemo1')] | [new Anchor(name: 'PNFDemo1'), new Anchor(name: 'PNFDemo2')] || ['PNFDemo1']
+ 'only module query results exist' | [:] | [new Anchor(name: 'PNFDemo1'), new Anchor(name: 'PNFDemo2')] || []
+ 'only combined query results exist' | ['PNFDemo1' : new NcmpServiceCmHandle(cmHandleId:'PNFDemo1'), 'PNFDemo2' : new NcmpServiceCmHandle(cmHandleId:'PNFDemo2')] | [] || []
+ 'neither queries return results' | [:] | [] || []
+ 'none intersect' | ['PNFDemo1' : new NcmpServiceCmHandle(cmHandleId:'PNFDemo1')] | [new Anchor(name: 'PNFDemo2')] || []
}
def 'Retrieve cm handles when the query is empty.'() {
- given: 'mock services'
- mockResponses()
- when: 'the service is invoked'
+ given: 'We use an empty query'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
+ and: 'the inventory persistence returns the dmi registry datanode'
+ inventoryPersistence.getDataNode("/dmi-registry") >> dmiRegistry
+ and: 'the inventory persistence returns anchors for get anchors'
+ inventoryPersistence.getAnchors() >> [new Anchor(name: 'PNFDemo1'), new Anchor(name: 'PNFDemo2'), new Anchor(name: 'PNFDemo3'), new Anchor(name: 'PNFDemo4')]
+ when: 'the query is executed for both cm handle ids and details'
def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
def returnedCmHandlesWithData = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
then: 'the correct expected cm handles are returned'
@@ -120,43 +166,13 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
returnedCmHandlesWithData.stream().map(d -> d.cmHandleId).collect(Collectors.toSet()) == ['PNFDemo1', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4'] as Set
}
- void mockResponses() {
- def pNFDemo1 = new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'PNFDemo1\']', leaves: ['id':'PNFDemo1'])
- def pNFDemo2 = new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'PNFDemo2\']', leaves: ['id':'PNFDemo2'])
- def pNFDemo3 = new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'PNFDemo3\']', leaves: ['id':'PNFDemo3'])
- def pNFDemo4 = new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'PNFDemo4\']', leaves: ['id':'PNFDemo4'])
- def dmiRegistry = new DataNode(xpath: '/dmi-registry', childDataNodes: [pNFDemo1, pNFDemo2, pNFDemo3, pNFDemo4])
-
- inventoryPersistence.queryDataNodes('//public-properties[@name=\'Contact\' and @value=\'newemailforstore@bookstore.com\']/ancestor::cm-handles')
- >> [pNFDemo1, pNFDemo2, pNFDemo4]
- inventoryPersistence.queryDataNodes('//public-properties[@name=\'wont_match\' and @value=\'wont_match\']/ancestor::cm-handles')
- >> []
- inventoryPersistence.queryDataNodes('//public-properties[@name=\'Contact2\' and @value=\'newemailforstore2@bookstore.com\']/ancestor::cm-handles')
- >> [pNFDemo4]
- inventoryPersistence.queryDataNodes('//public-properties[@name=\'Contact2\' and @value=\'\']/ancestor::cm-handles')
- >> []
- inventoryPersistence.queryDataNodes('//public-properties/ancestor::cm-handles')
- >> [pNFDemo1, pNFDemo2, pNFDemo3, pNFDemo4]
-
- inventoryPersistence.queryDataNodes('//cm-handles[@id=\'PNFDemo\']') >> [pNFDemo1]
- inventoryPersistence.queryDataNodes('//cm-handles[@id=\'PNFDemo2\']') >> [pNFDemo2]
- inventoryPersistence.queryDataNodes('//cm-handles[@id=\'PNFDemo3\']') >> [pNFDemo3]
- inventoryPersistence.queryDataNodes('//cm-handles[@id=\'PNFDemo4\']') >> [pNFDemo4]
-
- inventoryPersistence.getDataNode('/dmi-registry') >> dmiRegistry
-
- inventoryPersistence.getDataNode('/dmi-registry/cm-handles[@id=\'PNFDemo1\']') >> pNFDemo1
- inventoryPersistence.getDataNode('/dmi-registry/cm-handles[@id=\'PNFDemo2\']') >> pNFDemo2
- inventoryPersistence.getDataNode('/dmi-registry/cm-handles[@id=\'PNFDemo3\']') >> pNFDemo3
- inventoryPersistence.getDataNode('/dmi-registry/cm-handles[@id=\'PNFDemo4\']') >> pNFDemo4
+ def createConditionProperties(String conditionName, List<Map<String, String>> conditionParameters) {
+ return new ConditionProperties(conditionName : conditionName, conditionParameters : conditionParameters)
+ }
- inventoryPersistence.queryAnchors(['MODULE-NAME-001']) >> [new Anchor(name: 'PNFDemo1'), new Anchor(name: 'PNFDemo2'), new Anchor(name: 'PNFDemo3')]
- inventoryPersistence.queryAnchors(['MODULE-NAME-004']) >> []
- inventoryPersistence.queryAnchors(['MODULE-NAME-003', 'MODULE-NAME-002']) >> [new Anchor(name: 'PNFDemo4')]
- inventoryPersistence.queryAnchors(['MODULE-NAME-002', 'MODULE-NAME-003']) >> [new Anchor(name: 'PNFDemo4')]
- inventoryPersistence.queryAnchors(['MODULE-NAME-004', 'MODULE-NAME-002']) >> []
- inventoryPersistence.queryAnchors(['MODULE-NAME-002', 'MODULE-NAME-004']) >> []
- inventoryPersistence.queryAnchors(['MODULE-NAME-002']) >> [new Anchor(name: 'PNFDemo2'), new Anchor(name: 'PNFDemo4')]
- inventoryPersistence.getAnchors() >> [new Anchor(name: 'PNFDemo1'), new Anchor(name: 'PNFDemo2'), new Anchor(name: 'PNFDemo3'), new Anchor(name: 'PNFDemo4')]
+ def static createDataNodeList(dataNodeIds) {
+ def dataNodes =[]
+ dataNodeIds.forEach(id -> {dataNodes.add(new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'' + id + '\']', leaves: ['id':id]))})
+ return dataNodes
}
}
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
new file mode 100644
index 000000000..10a5d6246
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesSpec.groovy
@@ -0,0 +1,150 @@
+/*
+ * ============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
+
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.spi.CpsDataPersistenceService
+import org.onap.cps.spi.model.DataNode
+import spock.lang.Shared
+import spock.lang.Specification
+
+import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
+
+class CmHandleQueriesSpec extends Specification {
+ def cpsDataPersistenceService = Mock(CpsDataPersistenceService)
+
+ def objectUnderTest = new CmHandleQueries(cpsDataPersistenceService)
+
+ @Shared
+ def static sampleDataNodes = [new DataNode()]
+
+ def static pnfDemo = createDataNode('PNFDemo')
+ def static pnfDemo2 = createDataNode('PNFDemo2')
+ def static pnfDemo3 = createDataNode('PNFDemo3')
+ def static pnfDemo4 = createDataNode('PNFDemo4')
+
+ def static pnfDemoCmHandle = new NcmpServiceCmHandle(cmHandleId: 'PNFDemo')
+ def static pnfDemo2CmHandle = new NcmpServiceCmHandle(cmHandleId: 'PNFDemo2')
+ def static pnfDemo3CmHandle = new NcmpServiceCmHandle(cmHandleId: 'PNFDemo3')
+
+ def 'Query CmHandles with public properties query pair.'() {
+ given: 'the DataNodes queried for a given cpsPath are returned from the persistence service.'
+ mockResponses()
+ when: 'a query on cmhandle public properties is performed with a public property pair'
+ def returnedCmHandlesWithData = objectUnderTest.queryCmHandlePublicProperties(publicPropertyPairs)
+ then: 'the correct cm handle data objects are returned'
+ returnedCmHandlesWithData.keySet().containsAll(expectedCmHandleIds)
+ returnedCmHandlesWithData.keySet().size() == expectedCmHandleIds.size()
+ where: 'the following data is used'
+ scenario | publicPropertyPairs || expectedCmHandleIds
+ 'single property matches' | ['Contact' : 'newemailforstore@bookstore.com'] || ['PNFDemo', 'PNFDemo2', 'PNFDemo4']
+ 'public property does not match' | ['wont_match' : 'wont_match'] || []
+ '2 properties, only one match' | ['Contact' : 'newemailforstore@bookstore.com', 'Contact2': 'newemailforstore2@bookstore.com'] || ['PNFDemo4']
+ '2 properties, no matches' | ['Contact' : 'newemailforstore@bookstore.com', 'Contact2': ''] || []
+ }
+
+ def 'Query CmHandles using empty public properties query pair.'() {
+ when: 'a query on CmHandle public properties is executed using an empty map'
+ def returnedCmHandlesWithData = objectUnderTest.queryCmHandlePublicProperties([:])
+ then: 'no cm handles are returned'
+ returnedCmHandlesWithData.keySet().size() == 0
+ }
+
+ def 'Combine two query results where #scenario.'() {
+ when: 'two query results in the form of a map of NcmpServiceCmHandles are combined into a single query result'
+ def result = objectUnderTest.combineCmHandleQueries(firstQuery, secondQuery)
+ then: 'the returned result is the same as the expected result'
+ result == expectedResult
+ where:
+ scenario | firstQuery | secondQuery || expectedResult
+ 'two queries with unique and non unique entries exist' | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo2': pnfDemo2CmHandle] | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo3': pnfDemo3CmHandle] || ['PNFDemo': pnfDemoCmHandle]
+ 'the first query contains entries and second query is empty' | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo2': pnfDemo2CmHandle] | [:] || [:]
+ 'the second query contains entries and first query is empty' | [:] | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo3': pnfDemo3CmHandle] || [:]
+ 'the first query contains entries and second query is null' | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo2': pnfDemo2CmHandle] | null || ['PNFDemo': pnfDemoCmHandle, 'PNFDemo2': pnfDemo2CmHandle]
+ 'the second query contains entries and first query is null' | null | ['PNFDemo': pnfDemoCmHandle, 'PNFDemo3': pnfDemo3CmHandle] || ['PNFDemo': pnfDemoCmHandle, 'PNFDemo3': pnfDemo3CmHandle]
+ 'both queries are empty' | [:] | [:] || [:]
+ 'both queries are null' | null | null || [:]
+ }
+
+ def 'Get Cm Handles By State'() {
+ given: 'a cm handle state to query'
+ def cmHandleState = CmHandleState.ADVISED
+ and: 'the persistence service returns a list of data nodes'
+ 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)
+ then: 'the returned result matches the result from the persistence service'
+ assert result == sampleDataNodes
+ }
+
+ def 'Get Cm Handles By State and 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
+ when: 'cm handles are fetched by state and id'
+ def result = objectUnderTest.getCmHandlesByIdAndState('some-cm-handle', cmHandleState)
+ then: 'the returned result is a list of data nodes returned by cps data service'
+ assert result == sampleDataNodes
+ }
+
+ def 'Get 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)
+ then: 'the returned result is a list of data nodes returned by cps data service'
+ assert result == sampleDataNodes
+ }
+
+ def 'Retrieve cm handle by cps path '() {
+ given: 'a cm handle state to query based on the cps path'
+ def cmHandleDataNode = new DataNode(xpath: 'xpath', leaves: ['cm-handle-state': 'LOCKED'])
+ def cpsPath = '//cps-path'
+ and: 'cps data service returns a valid data node'
+ cpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
+ 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)
+ then: 'the returned result is a list of data nodes returned by cps data service'
+ assert result.contains(cmHandleDataNode)
+ }
+
+ void mockResponses() {
+ cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"Contact\" and @value=\"newemailforstore@bookstore.com\"]/ancestor::cm-handles', _) >> [pnfDemo, pnfDemo2, pnfDemo4]
+ cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"wont_match\" and @value=\"wont_match\"]/ancestor::cm-handles', _) >> []
+ cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"Contact2\" and @value=\"newemailforstore2@bookstore.com\"]/ancestor::cm-handles', _) >> [pnfDemo4]
+ cpsDataPersistenceService.queryDataNodes(_, _, '//public-properties[@name=\"Contact2\" and @value=\"\"]/ancestor::cm-handles', _) >> []
+ cpsDataPersistenceService.queryDataNodes(_, _, '//state[@cm-handle-state=\"READY\"]/ancestor::cm-handles', _) >> [pnfDemo, pnfDemo3]
+ cpsDataPersistenceService.queryDataNodes(_, _, '//state[@cm-handle-state=\"LOCKED\"]/ancestor::cm-handles', _) >> [pnfDemo2, pnfDemo4]
+ }
+
+ def static createDataNode(dataNodeId) {
+ return new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'' + dataNodeId + '\']', leaves: ['id':dataNodeId])
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
index 7ac231c16..f9ca676f3 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/InventoryPersistenceSpec.groovy
@@ -80,9 +80,6 @@ class InventoryPersistenceSpec extends Specification {
@Shared
def childDataNodesForCmHandleWithState = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some-cm-handle']/state", leaves: ['cm-handle-state': 'ADVISED'])]
- @Shared
- def static sampleDataNodes = [new DataNode()]
-
def "Retrieve CmHandle using datanode with #scenario."() {
given: 'the cps data service returns a data node from the DMI registry'
def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves)
@@ -157,56 +154,6 @@ class InventoryPersistenceSpec extends Specification {
'DELETING' | CmHandleState.DELETING || '{"state":{"cm-handle-state":"DELETING","last-update-time":"2022-12-31T20:30:40.000+0000"}}'
}
- def 'Get Cm Handles By State'() {
- given: 'a cm handle state to query'
- def cmHandleState = CmHandleState.ADVISED
- and: 'cps data service returns a list of data nodes'
- mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- '//state[@cm-handle-state="ADVISED"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes
- when: 'get cm handles by state is invoked'
- def result = objectUnderTest.getCmHandlesByState(cmHandleState)
- then: 'the returned result is a list of data nodes returned by cps data service'
- assert result == sampleDataNodes
- }
-
- def 'Get Cm Handles By State and Cm-Handle Id'() {
- given: 'a cm handle state to query'
- def cmHandleState = CmHandleState.READY
- and: 'cps data service returns a list of data nodes'
- mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- '//cm-handles[@id=\'some-cm-handle\']/state[@cm-handle-state="'+ 'READY'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes
- when: 'get cm handles by state and id is invoked'
- def result = objectUnderTest.getCmHandlesByIdAndState(cmHandleId, cmHandleState)
- then: 'the returned result is a list of data nodes returned by cps data service'
- assert result == sampleDataNodes
- }
-
- def 'Get 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'
- mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- '//state/datastores/operational[@sync-state="'+'UNSYNCHRONIZED'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes
- when: 'get cm handles by operational sync state as UNSYNCHRONIZED is invoked'
- def result = objectUnderTest.getCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED)
- then: 'the returned result is a list of data nodes returned by cps data service'
- assert result == sampleDataNodes
- }
-
- def 'Retrieve cm handle by cps path '() {
- given: 'a cm handle state to query based on the cps path'
- def cmHandleDataNode = new DataNode(xpath: 'xpath', leaves: ['cm-handle-state': 'LOCKED'])
- def cpsPath = '//cps-path'
- and: 'cps data service returns a valid data node'
- mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- cpsPath, INCLUDE_ALL_DESCENDANTS)
- >> Arrays.asList(cmHandleDataNode)
- when: 'get cm handles by cps path is invoked'
- def result = objectUnderTest.getCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS)
- then: 'the returned result is a list of data nodes returned by cps data service'
- assert result.contains(cmHandleDataNode)
- }
-
def 'Get module definitions'() {
given: 'cps module service returns a collection of module definitions'
def moduleDefinitions = [new ModuleDefinition('moduleName','revision','content')]
@@ -263,13 +210,6 @@ class InventoryPersistenceSpec extends Specification {
0 * mockCpsModuleService.deleteSchemaSet('NFP-Operational', 'sampleSchemaSetName', CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED)
}
- def 'Query data nodes via cpsPath'() {
- when: 'the method to query data nodes is called'
- objectUnderTest.queryDataNodes('sample cpsPath')
- then: 'the data persistence service method to query data nodes is invoked once'
- 1 * mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','sample cpsPath', INCLUDE_ALL_DESCENDANTS)
- }
-
def 'Get data node via xPath'() {
when: 'the method to get data nodes is called'
objectUnderTest.getDataNode('sample xPath')
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 6c2d8f15b..82e9d33ae 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
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode
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.inventory.CmHandleState
import org.onap.cps.ncmp.api.inventory.CompositeState
import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
@@ -47,11 +48,13 @@ class SyncUtilsSpec extends Specification{
def mockInventoryPersistence = Mock(InventoryPersistence)
+ def mockCmHandleQueries = Mock(CmHandleQueries)
+
def mockDmiDataOperations = Mock(DmiDataOperations)
def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
- def objectUnderTest = new SyncUtils(mockInventoryPersistence, mockDmiDataOperations, jsonObjectMapper)
+ def objectUnderTest = new SyncUtils(mockInventoryPersistence, mockCmHandleQueries, mockDmiDataOperations, jsonObjectMapper)
@Shared
def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(OffsetDateTime.now())
@@ -61,14 +64,14 @@ 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'
- mockInventoryPersistence.getCmHandlesByState(CmHandleState.ADVISED) >> dataNodeCollection
+ mockCmHandleQueries.getCmHandlesByState(CmHandleState.ADVISED) >> dataNodeCollection
when: 'get advised cm handles are fetched'
def yangModelCmHandles = objectUnderTest.getAdvisedCmHandles()
then: 'the returned data node collection is the correct size'
yangModelCmHandles.size() == expectedDataNodeSize
and: 'yang model collection contains the correct data'
yangModelCmHandles.stream().map(yangModel -> yangModel.id).collect(Collectors.toSet()) ==
- dataNodeCollection.stream().map(dataNode -> dataNode.leaves.get("id")).collect(Collectors.toSet())
+ dataNodeCollection.stream().map(dataNode -> dataNode.leaves.get("id")).collect(Collectors.toSet())
where: 'the following scenarios are used'
scenario | dataNodeCollection || expectedCallsToGetYangModelCmHandle | expectedDataNodeSize
'exists' | [dataNode] || 1 | 1
@@ -77,7 +80,7 @@ class SyncUtilsSpec extends Specification{
def 'Update Lock Reason, Details and Attempts where lock reason #scenario'() {
given: 'A locked state'
- def compositeState = new CompositeState(lockReason: lockReason)
+ def compositeState = new CompositeState(lockReason: lockReason)
when: 'update cm handle details and attempts is called'
objectUnderTest.updateLockReasonDetailsAndAttempts(compositeState, LockReasonCategory.LOCKED_MODULE_SYNC_FAILED, 'new error message')
then: 'the composite state lock reason and details are updated'
@@ -91,9 +94,9 @@ 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'
- mockInventoryPersistence.getCmHandleDataNodesByCpsPath(
- '//lock-reason[@reason="LOCKED_MODULE_SYNC_FAILED"]/ancestor::cm-handles',
- FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode ]
+ mockCmHandleQueries.getCmHandleDataNodesByCpsPath(
+ '//lock-reason[@reason="LOCKED_MODULE_SYNC_FAILED"]',
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode]
when: 'get locked Misbehaving cm handle is called'
def result = objectUnderTest.getModuleSyncFailedCmHandles()
then: 'the returned cm handle collection is the correct size'
@@ -119,8 +122,8 @@ class SyncUtilsSpec extends Specification{
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(DataStoreSyncState.UNSYNCHRONIZED) >> unSynchronizedDataNodes
- mockInventoryPersistence.getCmHandlesByIdAndState("cm-handle-123", CmHandleState.READY) >> readyDataNodes
+ mockCmHandleQueries.getCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) >> unSynchronizedDataNodes
+ mockCmHandleQueries.getCmHandlesByIdAndState("cm-handle-123", CmHandleState.READY) >> readyDataNodes
when: 'get advised cm handles are fetched'
objectUnderTest.getAnUnSynchronizedReadyCmHandle()
then: 'the returned data node collection is the correct size'