From 760e597acc7854a736363a0136343b5a77462cfb Mon Sep 17 00:00:00 2001 From: niamhcore Date: Thu, 11 Feb 2021 14:49:11 +0000 Subject: Persistence layer - Query Datanodes using cpsPath that contains contains a leaf name and a leaf value Issue-ID: CPS-231 Signed-off-by: niamhcore Change-Id: I9bd483a4b76e233ab6c64b3ef8aacb593e4e9da0 --- .../spi/impl/CpsDataPersistenceServiceSpec.groovy | 41 ++++++++++++++-- .../org/onap/cps/spi/query/CpsPathQuerySpec.groovy | 55 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 cps-ri/src/test/groovy/org/onap/cps/spi/query/CpsPathQuerySpec.groovy (limited to 'cps-ri/src/test/groovy/org') diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy index a6e4701366..015893817a 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy @@ -19,9 +19,6 @@ */ package org.onap.cps.spi.impl -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS - import com.google.common.collect.ImmutableSet import com.google.gson.Gson import com.google.gson.GsonBuilder @@ -37,6 +34,9 @@ import org.springframework.dao.DataIntegrityViolationException import org.springframework.test.context.jdbc.Sql import spock.lang.Unroll +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { @Autowired @@ -87,6 +87,7 @@ class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { grandchildFragment.xpath == grandChildXpath } + @Unroll @Sql([CLEAR_DATA, SET_DATA]) def 'Store datanode error scenario: #scenario.'() { when: 'attempt to store a data node with #scenario' @@ -116,6 +117,7 @@ class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { parentFragment.getChildFragments().find({ it.xpath == newChild.xpath }) } + @Unroll @Sql([CLEAR_DATA, SET_DATA]) def 'Add child error scenario: #scenario.'() { when: 'attempt to add a child data node with #scenario' @@ -283,7 +285,7 @@ class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { @Sql([CLEAR_DATA, SET_DATA]) def 'Replace data node tree error scenario: #scenario.'() { given: 'data node object' - def submittedDataNode = buildDataNode(xpath, ['leaf-name':'leaf-value'], []) + def submittedDataNode = buildDataNode(xpath, ['leaf-name': 'leaf-value'], []) when: 'attempt to update data node for #scenario' objectUnderTest.replaceDataNodeTree(dataspaceName, anchorName, submittedDataNode) then: 'a #expectedException is thrown' @@ -302,4 +304,35 @@ class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { static Map getLeavesMap(FragmentEntity fragmentEntity) { return GSON.fromJson(fragmentEntity.getAttributes(), Map.class) } + + @Unroll + @Sql([CLEAR_DATA, SET_DATA]) + def 'Cps Path query for single leaf value with type: #type.'() { + when: 'a query is executed to get a data node by the given cps path' + def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, cpsPath) + then: 'the correct data is returned' + def leaves ='[common-leaf-name:common-leaf-value, common-leaf-name-int:5.0]' + result.size() == 1 + def dataNode = result.stream().findFirst().get() + dataNode.getLeaves().toString() == leaves + where: 'the following data is used' + type | cpsPath + 'String' | '/parent-200/child-202[@common-leaf-name=\'common-leaf-value\']' + 'Integer' | '/parent-200/child-202[@common-leaf-name-int=5]' + } + + @Unroll + @Sql([CLEAR_DATA, SET_DATA]) + def 'Query for attribute by cps path with cps paths that return no data because of #scenario.'() { + when: 'a query is executed to get datanodes for the given cps path' + def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, cpsPath) + then: 'no data is returned' + result.isEmpty() + where: 'following cps queries are performed' + scenario | cpsPath + 'cps path is incomplete' | '/parent-200[@common-leaf-name-int=5]' + 'missing / at beginning of path' | 'parent-200/child-202[@common-leaf-name-int=5]' + 'leaf value does not exist' | '/parent-200/child-202[@common-leaf-name=\'does not exist\']' + 'incomplete end of xpath prefix' | '/parent-200/child-20[@common-leaf-name-int=5]' + } } diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/query/CpsPathQuerySpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/query/CpsPathQuerySpec.groovy new file mode 100644 index 0000000000..1e457fb062 --- /dev/null +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/query/CpsPathQuerySpec.groovy @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.spi.query + +import org.onap.cps.spi.exceptions.CpsPathException +import spock.lang.Specification +import spock.lang.Unroll + +class CpsPathQuerySpec extends Specification { + + def objectUnderTest = new CpsPathQuery() + + @Unroll + def 'Parse cps path with valid cps path and a filter for a leaf of type : #type.'() + { when: 'the given cps path is parsed' + def result = objectUnderTest.createFrom(cpsPath) + then: 'object has the expected attribute' + result.xpathPrefix == '/parent-200/child-202' + result.leafName == expectedLeafName + result.leafValue == expectedLeafValue + where: 'the following data is used' + type | cpsPath || expectedLeafName | expectedLeafValue + 'String' | '/parent-200/child-202[@common-leaf-name=\'common-leaf-value\']' || 'common-leaf-name' | 'common-leaf-value' + 'Integer' | '/parent-200/child-202[@common-leaf-name-int=5]' || 'common-leaf-name-int' | 5 + } + + @Unroll + def 'Parse cps path with : #scenario.'() + { when: 'the given cps path is parsed' + objectUnderTest.createFrom(cpsPath) + then: 'a CpsPathException is thrown' + thrown(CpsPathException) + where: 'the following data is used' + scenario | cpsPath + 'invalid cps path' | 'invalid-cps-path' + 'cps path with float value' | '/parent-200/child-202[@common-leaf-name-float=5.0]' + } +} -- cgit 1.2.3-korg