X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ncmp-service%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Fncmp%2Fapi%2Finventory%2FCmHandleQueriesImplSpec.groovy;h=a3a5efc7486c321e18994c75820a527b29a50731;hb=624f04c03146e002bab2ca88e55b7f586c6e1aff;hp=752b9f3ec2b62f3a5ffb3a1cf7a73d1a69d859c2;hpb=dd151f17eed71ea1ef7c2e6e5fe9168a5ae37abb;p=cps.git diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImplSpec.groovy index 752b9f3ec..a3a5efc74 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImplSpec.groovy @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,76 +21,94 @@ package org.onap.cps.ncmp.api.inventory -import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle +import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel + +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + +import com.hazelcast.map.IMap +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueriesImpl +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState +import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState 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 CmHandleQueriesImplSpec extends Specification { def cpsDataPersistenceService = Mock(CpsDataPersistenceService) + def trustLevelPerCmHandle = [ 'my completed cm handle': TrustLevel.COMPLETE, 'my untrusted cm handle': TrustLevel.NONE ] - def objectUnderTest = new CmHandleQueriesImpl(cpsDataPersistenceService) + def objectUnderTest = new CmHandleQueriesImpl(cpsDataPersistenceService, trustLevelPerCmHandle) @Shared def static sampleDataNodes = [new DataNode()] + def dataNodeWithPrivateField = '//additional-properties[@name=\"Contact3\" and @value=\"newemailforstore3@bookstore.com\"]/ancestor::cm-handles' + 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 static pnfDemo5 = createDataNode('PNFDemo5') 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) + def result = objectUnderTest.queryCmHandlePublicProperties(publicPropertyPairs) then: 'the correct cm handle data objects are returned' - returnedCmHandlesWithData.keySet().containsAll(expectedCmHandleIds) - returnedCmHandlesWithData.keySet().size() == expectedCmHandleIds.size() + result.containsAll(expectedCmHandleIds) + result.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': ''] || [] + 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 cm handles on trust level'() { + given: 'query properties for trustlevel COMPLETE' + def trustLevelPropertyQueryPairs = ['trustLevel' : TrustLevel.COMPLETE.toString()] + when: 'the query is executed' + def result = objectUnderTest.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs) + then: 'the result only contains the completed cm handle' + assert result.size() == 1 + assert result[0] == 'my completed cm handle' } 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([:]) + def result = objectUnderTest.queryCmHandlePublicProperties([:]) then: 'no cm handles are returned' - returnedCmHandlesWithData.keySet().size() == 0 + result.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 || null + def 'Query CmHandles using empty private properties query pair.'() { + when: 'a query on CmHandle private properties is executed using an empty map' + def result = objectUnderTest.queryCmHandleAdditionalProperties([:]) + then: 'no cm handles are returned' + result.size() == 0 + } + + def 'Query CmHandles by a private field\'s value.'() { + given: 'a data node exists with a certain additional-property' + cpsDataPersistenceService.queryDataNodes(_, _, dataNodeWithPrivateField, _) >> [pnfDemo5] + when: 'a query on CmHandle private properties is executed using a map' + def result = objectUnderTest.queryCmHandleAdditionalProperties(['Contact3': 'newemailforstore3@bookstore.com']) + then: 'one cm handle is returned' + result.size() == 1 } - def 'Get Cm Handles By State'() { + def 'Get CmHandles by it\'s 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', + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '//state[@cm-handle-state="ADVISED"]/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS) >> sampleDataNodes when: 'cm handles are fetched by state' def result = objectUnderTest.queryCmHandlesByState(cmHandleState) @@ -97,12 +116,30 @@ class CmHandleQueriesImplSpec extends Specification { assert result == sampleDataNodes } + def 'Check the state of a cmHandle when #scenario.'() { + given: 'a cm handle state to compare' + def cmHandleState = state + and: 'the persistence service returns a list of data nodes' + cpsDataPersistenceService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, + NCMP_DMI_REGISTRY_PARENT + '/cm-handles[@id=\'some-cm-handle\']/state', + OMIT_DESCENDANTS) >> [new DataNode(leaves: ['cm-handle-state': 'READY'])] + when: 'cm handles are compared by state' + def result = objectUnderTest.cmHandleHasState('some-cm-handle', cmHandleState) + then: 'the returned result matches the expected result from the persistence service' + result == expectedResult + where: + scenario | state || expectedResult + 'the provided state matches' | CmHandleState.READY || true + 'the provided state does not match'| CmHandleState.DELETED || false + } + 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.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - '/dmi-registry/cm-handles[@id=\'some-cm-handle\']/state', OMIT_DESCENDANTS) >> new DataNode(leaves: ['cm-handle-state': 'READY']) + cpsDataPersistenceService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, + NCMP_DMI_REGISTRY_PARENT + '/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.getCmHandleState('some-cm-handle') then: 'the returned result is a list of data nodes returned by cps data service' @@ -113,7 +150,7 @@ class CmHandleQueriesImplSpec extends Specification { 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', + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '//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.queryCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) @@ -126,11 +163,11 @@ class CmHandleQueriesImplSpec extends Specification { 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', + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath + '/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS) >> Arrays.asList(cmHandleDataNode) when: 'get cm handles by cps path is invoked' - def result = objectUnderTest.queryCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) + def result = objectUnderTest.queryCmHandleAncestorsByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) then: 'the returned result is a list of data nodes returned by cps data service' assert result.contains(cmHandleDataNode) } @@ -139,11 +176,11 @@ class CmHandleQueriesImplSpec extends Specification { given: 'the DataNodes queried for a given cpsPath are returned from the persistence service.' mockResponses() when: 'cm Handles are fetched for a given dmi plugin identifier' - def result = objectUnderTest.getCmHandlesByDmiPluginIdentifier('my-dmi-plugin-identifier') + def result = objectUnderTest.getCmHandleIdsByDmiPluginIdentifier('my-dmi-plugin-identifier') then: 'result is the correct size' assert result.size() == 3 and: 'result contains the correct cm handles' - assert result.cmHandleId.containsAll('PNFDemo', 'PNFDemo2', 'PNFDemo4') + assert result.containsAll('PNFDemo', 'PNFDemo2', 'PNFDemo4') } void mockResponses() { @@ -153,9 +190,9 @@ class CmHandleQueriesImplSpec extends Specification { 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] - cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo2] - cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo,pnfDemo4] - cpsDataPersistenceService.queryDataNodes('NCMP-Admin','ncmp-dmi-registry','/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']',OMIT_DESCENDANTS) >> [pnfDemo2,pnfDemo4] + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo2] + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo4] + cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo2, pnfDemo4] } def static createDataNode(dataNodeId) {