From 6c9c100daba10717641a08b6c6dc3ec3b51c56a8 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Fri, 30 Apr 2021 12:09:44 +0100 Subject: Implement cps path query to get ancestor by schema node identifier Cleaned up some legcy issues in related testware Issue-ID: CPS-305 Signed-off-by: niamhcore Change-Id: Ic4b21308478f399e3a454dbcd73943e077b0f3f2 Signed-off-by: ToineSiebelink --- .../CpsDataPersistenceQueryDataNodeSpec.groovy | 73 ++++++++-------------- .../spi/impl/CpsDataPersistenceServiceSpec.groovy | 42 ++++++------- .../org/onap/cps/spi/query/CpsPathQuerySpec.groovy | 37 +++++++---- 3 files changed, 72 insertions(+), 80 deletions(-) (limited to 'cps-ri/src/test/groovy/org/onap') diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy index 8acfe783d..4bebff9f8 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy @@ -20,14 +20,10 @@ */ package org.onap.cps.spi.impl -import com.google.common.collect.ImmutableSet -import com.google.gson.Gson -import com.google.gson.GsonBuilder import org.onap.cps.spi.CpsDataPersistenceService import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.exceptions.CpsPathException import org.onap.cps.spi.model.DataNode -import org.onap.cps.spi.model.DataNodeBuilder import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.jdbc.Sql @@ -39,42 +35,7 @@ class CpsDataPersistenceQueryDataNodeSpec extends CpsPersistenceSpecBase { @Autowired CpsDataPersistenceService objectUnderTest - static final Gson GSON = new GsonBuilder().create() - static final String SET_DATA = '/data/fragment.sql' - static final String XPATH_DATA_NODE_WITH_DESCENDANTS = '/parent-1' - - static DataNode existingDataNode - static DataNode existingChildDataNode - - def expectedLeavesByXpathMap = [ - '/parent-100' : ['parent-leaf': 'parent-leaf value'], - '/parent-100/child-001' : ['first-child-leaf': 'first-child-leaf value'], - '/parent-100/child-002' : ['second-child-leaf': 'second-child-leaf value'], - '/parent-100/child-002/grand-child': ['grand-child-leaf': 'grand-child-leaf value'] - ] - - static { - existingDataNode = createDataNodeTree(XPATH_DATA_NODE_WITH_DESCENDANTS) - existingChildDataNode = createDataNodeTree('/parent-1/child-1') - } - - static def createDataNodeTree(String... xpaths) { - def dataNodeBuilder = new DataNodeBuilder().withXpath(xpaths[0]) - if (xpaths.length > 1) { - def xPathsDescendant = Arrays.copyOfRange(xpaths, 1, xpaths.length) - def childDataNode = createDataNodeTree(xPathsDescendant) - dataNodeBuilder.withChildDataNodes(ImmutableSet.of(childDataNode)) - } - dataNodeBuilder.build() - } - - def static treeToFlatMapByXpath(Map flatMap, DataNode dataNodeTree) { - flatMap.put(dataNodeTree.getXpath(), dataNodeTree) - dataNodeTree.getChildDataNodes() - .forEach(childDataNode -> treeToFlatMapByXpath(flatMap, childDataNode)) - return flatMap - } @Sql([CLEAR_DATA, SET_DATA]) def 'Cps Path query for single leaf value with type: #type.'() { @@ -98,10 +59,10 @@ class CpsDataPersistenceQueryDataNodeSpec extends CpsPersistenceSpecBase { 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]' - '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]' + scenario | cpsPath + 'cps path is incomplete' | '/parent-200[@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]' } @Sql([CLEAR_DATA, SET_DATA]) @@ -125,13 +86,13 @@ class CpsDataPersistenceQueryDataNodeSpec extends CpsPersistenceSpecBase { then: 'the correct number of data nodes are retrieved' result.size() == expectedXPaths.size() and: 'xpaths of the retrieved data nodes are as expected' - for(int i = 0; i { - def actualValue = actualLeavesMap[key] - if (value instanceof Collection && actualValue instanceof Collection) { - assert value.size() == actualValue.size() - assert value.containsAll(actualValue) - } else { - assert value == actualValue - } - } - ) - return true - } - - def static treeToFlatMapByXpath(Map flatMap, DataNode dataNodeTree) { - flatMap.put(dataNodeTree.getXpath(), dataNodeTree) - dataNodeTree.getChildDataNodes() - .forEach(childDataNode -> treeToFlatMapByXpath(flatMap, childDataNode)) - return flatMap - } - @Sql([CLEAR_DATA, SET_DATA]) def 'Get data node error scenario: #scenario.'() { when: 'attempt to get data node with #scenario' @@ -327,4 +306,25 @@ class CpsDataPersistenceServiceSpec extends CpsPersistenceSpecBase { static Map getLeavesMap(FragmentEntity fragmentEntity) { return GSON.fromJson(fragmentEntity.getAttributes(), Map.class) } + + def static assertLeavesMaps(actualLeavesMap, expectedLeavesMap) { + expectedLeavesMap.forEach((key, value) -> { + def actualValue = actualLeavesMap[key] + if (value instanceof Collection && actualValue instanceof Collection) { + assert value.size() == actualValue.size() + assert value.containsAll(actualValue) + } else { + assert value == actualValue + } + }) + return true + } + + def static treeToFlatMapByXpath(Map flatMap, DataNode dataNodeTree) { + flatMap.put(dataNodeTree.getXpath(), dataNodeTree) + dataNodeTree.getChildDataNodes() + .forEach(childDataNode -> treeToFlatMapByXpath(flatMap, childDataNode)) + return flatMap + } + } 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 index bd0fb44fe..ee641d102 100644 --- 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 @@ -38,10 +38,10 @@ class CpsPathQuerySpec extends Specification { result.leafValue == expectedLeafValue where: 'the following data is used' scenario | cpsPath || expectedXpathPrefix | expectedLeafName | expectedLeafValue - 'leaf of type String' | '/parent/child[@common-leaf-name=\'common-leaf-value\']' || '/parent/child' |'common-leaf-name' | 'common-leaf-value' - 'leaf of type Integer' | '/parent/child[@common-leaf-name-int=5]' || '/parent/child' |'common-leaf-name-int' | 5 - 'spaces around =' | '/parent/child[@common-leaf-name-int = 5]' || '/parent/child' |'common-leaf-name-int' | 5 - 'key in top container' | '/parent[@common-leaf-name-int=5]' || '/parent' |'common-leaf-name-int' | 5 + 'leaf of type String' | '/parent/child[@common-leaf-name=\'common-leaf-value\']' || '/parent/child' | 'common-leaf-name' | 'common-leaf-value' + 'leaf of type Integer' | '/parent/child[@common-leaf-name-int=5]' || '/parent/child' | 'common-leaf-name-int' | 5 + 'spaces around =' | '/parent/child[@common-leaf-name-int = 5]' || '/parent/child' | 'common-leaf-name-int' | 5 + 'key in top container' | '/parent[@common-leaf-name-int=5]' || '/parent' | 'common-leaf-name-int' | 5 } def 'Parse cps path of type ends with a #scenario.'() { @@ -52,9 +52,9 @@ class CpsPathQuerySpec extends Specification { and: 'the right ends with parameters are set' result.descendantName == expectedEndsWithValue where: 'the following data is used' - scenario | cpsPath || expectedEndsWithValue - 'yang container' | '//cps-path' || 'cps-path' - 'parent & child' | '//parent/child' || 'parent/child' + scenario | cpsPath || expectedEndsWithValue + 'yang container' | '//cps-path' || 'cps-path' + 'parent & child' | '//parent/child' || 'parent/child' } def 'Parse cps path that ends with a yang list containing #scenario.'() { @@ -67,8 +67,8 @@ class CpsPathQuerySpec extends Specification { result.leavesData.size() == expectedNumberOfLeaves where: 'the following data is used' scenario | cpsPath || expectedNumberOfLeaves - 'one attribute' | '//child[@common-leaf-name-int=5]' || 1 - 'more than one attribute' | '//child[@int-leaf=5 and @leaf-name="leaf value"]' || 2 + 'one attribute' | '//child[@common-leaf-name-int=5]' || 1 + 'more than one attribute' | '//child[@int-leaf=5 and @leaf-name="leaf value"]' || 2 } def 'Parse cps path with #scenario.'() { @@ -86,6 +86,7 @@ class CpsPathQuerySpec extends Specification { 'too many containers' | '/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42/43/44/45/46/47/48/49/50/51/52/53/54/55/56/57/58/59/60/61/62/63/64/65/66/67/68/69/70/71/72/73/74/75/76/77/78/79/80/81/82/83/84/85/86/87/88/89/90/91/92/93/94/95/96/97/98/99/100[@a=1]' 'end with descendant and more than one attribute separated by "or"' | '//child[@int-leaf=5 or @leaf-name="leaf value"]' 'missing attribute value' | '//child[@int-leaf=5 and @name]' + 'incomplete ancestor value' | '//books/ancestor::' } def 'Convert cps leaf value to valid type with leaf of type #scenario.'() { @@ -94,12 +95,22 @@ class CpsPathQuerySpec extends Specification { then: 'the leaf value returned is of the right type' result == expectedLeafOutputValue where: "the following data is used" - scenario | leafValueInputString || expectedLeafOutputValue - 'Integer' | "5" || 5 + scenario | leafValueInputString || expectedLeafOutputValue + 'Integer' | "5" || 5 'String with single quotes' | '\'value in single quotes\'' || 'value in single quotes' 'String with double quotes' | '"value in double quotes"' || 'value in double quotes' 'String containing single quote' | '"value with \'"' || 'value with \'' 'String containing double quote' | '\'value with "\'' || 'value with "' } - -} \ No newline at end of file + + def 'Parse cps path using ancestor by schema node identifier.'() { + when: 'the given cps path is parsed' + def result = objectUnderTest.createFrom('//someXpath/ancestor::someAncestor') + then: 'the query has the right type' + result.cpsPathQueryType == CpsPathQueryType.XPATH_HAS_DESCENDANT_ANYWHERE + and: 'the correct ancestor schema node identifier is set' + result.ancestorSchemaNodeIdentifier == 'someAncestor' + and: 'the result has ancestor axis' + result.hasAncestorAxis() + } +} -- cgit 1.2.3-korg