diff options
author | Luke Gleeson <luke.gleeson@est.tech> | 2023-08-03 13:13:47 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2023-08-03 13:13:47 +0000 |
commit | 478c5dac54ed508f0ce97e18e91aac7b821d814f (patch) | |
tree | 6b8d3d25972ebacf2d429ede2fff601cce15bc2e /integration-test/src | |
parent | 2a1e576e6d12456e43c47d4cd81be7f88d1a2a2b (diff) | |
parent | f248b5d9b794d5bdff59145406e0398d6fdcafa4 (diff) |
Merge "Support pagination in query across all anchors(ep4)"
Diffstat (limited to 'integration-test/src')
4 files changed, 70 insertions, 24 deletions
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy index a1e03529c3..4780e36428 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy @@ -117,7 +117,7 @@ class CpsIntegrationSpecBase extends Specification { def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) { (1..numberOfAnchors).each { cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it) - cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data, OffsetDateTime.now()) + cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now()) } } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy index 89a5e4074b..327a39ee4f 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy @@ -58,7 +58,7 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase { def anchorName = 'bookstoreAnchor' + anchorNumber cpsAdminService.deleteAnchor(FUNCTIONAL_TEST_DATASPACE_1, anchorName) cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, anchorName) - cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE_1, anchorName, bookstoreJsonData, OffsetDateTime.now()) + cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE_1, anchorName, bookstoreJsonData.replace("Easons", "Easons-"+anchorNumber.toString()), OffsetDateTime.now()) } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy index 678aa64460..475d3d2fdb 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy @@ -58,7 +58,7 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { then: 'the tree consist ouf of #expectNumberOfDataNodes data nodes' assert countDataNodesInTree(result) == expectNumberOfDataNodes and: 'the top level data node has the expected attribute and value' - assert result.leaves['bookstore-name'] == ['Easons'] + assert result.leaves['bookstore-name'] == ['Easons-1'] and: 'they are from the correct dataspace' assert result.dataspace == [FUNCTIONAL_TEST_DATASPACE_1] and: 'they are from the correct anchor' @@ -74,9 +74,9 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { def 'Read bookstore top-level container(s) using "root" path variations.'() { when: 'get data nodes for bookstore container' def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, root, OMIT_DESCENDANTS) - then: 'the tree consist ouf of one data node' + then: 'the tree consist correct number of data nodes' assert countDataNodesInTree(result) == 2 - and: 'the top level data node has the expected attribute and value' + and: 'the top level data node has the expected number of leaves' assert result.leaves.size() == 2 where: 'the following variations of "root" are used' root << [ '/', '' ] @@ -350,20 +350,6 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { 'new code, new child' | 'new' | ', "books" : [ { "title": "New Book" } ]' || 2 } - def 'Update multiple data node leaves.'() { - given: 'Updated json for bookstore data' - def jsonData = "{'book-store:books':{'lang':'English/French','price':100,'title':'Matilda'}}" - when: 'update is performed for leaves' - objectUnderTest.updateNodeLeaves(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_2, "/bookstore/categories[@code='1']", jsonData, now) - then: 'the updated data nodes are retrieved' - def result = cpsDataService.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_2, "/bookstore/categories[@code=1]/books[@title='Matilda']", INCLUDE_ALL_DESCENDANTS) - and: 'the leaf values are updated as expected' - assert result.leaves['lang'] == ['English/French'] - assert result.leaves['price'] == [100] - cleanup: - restoreBookstoreDataAnchor(2) - } - def 'Update data node leaves for node that has no leaves (yet).'() { given: 'new (webinfo) datanode without leaves' def json = '{"webinfo": {} }' @@ -408,6 +394,20 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { restoreBookstoreDataAnchor(1) } + def 'Update multiple data node leaves.'() { + given: 'Updated json for bookstore data' + def jsonData = "{'book-store:books':{'lang':'English/French','price':100,'title':'Matilda'}}" + when: 'update is performed for leaves' + objectUnderTest.updateNodeLeaves(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_2, "/bookstore/categories[@code='1']", jsonData, now) + then: 'the updated data nodes are retrieved' + def result = cpsDataService.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_2, "/bookstore/categories[@code=1]/books[@title='Matilda']", INCLUDE_ALL_DESCENDANTS) + and: 'the leaf values are updated as expected' + assert result.leaves['lang'] == ['English/French'] + assert result.leaves['price'] == [100] + cleanup: + restoreBookstoreDataAnchor(2) + } + def countDataNodesInBookstore() { return countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', INCLUDE_ALL_DESCENDANTS)) } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy index 74496d3016..146ea95e8b 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy @@ -25,11 +25,13 @@ import java.time.OffsetDateTime import org.onap.cps.api.CpsQueryService import org.onap.cps.integration.base.FunctionalSpecBase import org.onap.cps.spi.FetchDescendantsOption +import org.onap.cps.spi.PaginationOption import org.onap.cps.spi.exceptions.CpsPathException import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS +import static org.onap.cps.spi.PaginationOption.NO_PAGINATION class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { @@ -249,7 +251,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { def 'Cps Path query across anchors with #scenario.'() { when: 'a query is executed to get a data nodes across anchors by the given CpsPath' - def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, cpsPath, OMIT_DESCENDANTS) + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, cpsPath, OMIT_DESCENDANTS, NO_PAGINATION) then: 'the correct dataspace is queried' assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() and: 'correct anchors are queried' @@ -262,7 +264,6 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { scenario | cpsPath || expectedXpathsPerAnchor 'container node' | '/bookstore' || ["/bookstore"] 'list node' | '/bookstore/categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']", "/bookstore/categories[@code='5']"] - 'string leaf-condition' | '/bookstore[@bookstore-name="Easons"]' || ["/bookstore"] 'integer leaf-condition' | '/bookstore/categories[@code="1"]/books[@price=15]' || ["/bookstore/categories[@code='1']/books[@title='The Gruffalo']"] 'multiple list-ancestors' | '//books/ancestor::categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']", "/bookstore/categories[@code='5']"] 'one ancestor with list value' | '//books/ancestor::categories[@code="1"]' || ["/bookstore/categories[@code='1']"] @@ -274,7 +275,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { def 'Cps Path query across anchors with #scenario descendants.'() { when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', fetchDescendantsOption) + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', fetchDescendantsOption, NO_PAGINATION) then: 'the correct dataspace was queried' assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() and: 'correct number of datanodes are returned' @@ -288,7 +289,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { def 'Cps Path query across anchors with ancestors and #scenario descendants.'() { when: 'a query is executed to get a data node by the given cps path' - def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '//books/ancestor::bookstore', fetchDescendantsOption) + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '//books/ancestor::bookstore', fetchDescendantsOption, NO_PAGINATION) then: 'the correct dataspace was queried' assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() and: 'correct number of datanodes are returned' @@ -302,7 +303,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { def 'Cps Path query across anchors with syntax error throws a CPS Path Exception.'() { when: 'trying to execute a query with a syntax (parsing) error' - objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS) + objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS, NO_PAGINATION) then: 'a cps path exception is thrown' thrown(CpsPathException) } @@ -375,4 +376,49 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase { 'text-condition' || "/bookstore/categories[@code='1']/books/title[text()='I''m escaping']" 'contains-condition' || "/bookstore/categories[@code='1']/books[contains(@title, 'I''m escaping')]" } + + def 'Cps Path query across anchors using pagination option with #scenario.'() { + when: 'a query is executed to get a data nodes across anchors by the given CpsPath and pagination option' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', OMIT_DESCENDANTS, new PaginationOption(pageIndex, pageSize)) + then: 'correct bookstore names are queried' + def bookstoreNames = result.collect { it.getLeaves().get('bookstore-name') } + assert bookstoreNames.toList() == expectedBookstoreNames + and: 'the correct number of page size is returned' + assert result.size() == expectedPageSize + and: 'the queried nodes have expected anchor names' + assert result.anchorName.toSet() == expectedAnchors.toSet() + where: 'the following data is used' + scenario | pageIndex | pageSize || expectedPageSize || expectedAnchors || expectedBookstoreNames + '1st page with one anchor' | 1 | 1 || 1 || [BOOKSTORE_ANCHOR_1] || ['Easons-1'] + '1st page with two anchor' | 1 | 2 || 2 || [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2] || ['Easons-1', 'Easons-2'] + '2nd page' | 2 | 1 || 1 || [BOOKSTORE_ANCHOR_2] || ['Easons-2'] + 'no 2nd page due to page size' | 2 | 2 || 0 || [] || [] + } + + def 'Cps Path query across anchors using pagination option for ancestor axis.'() { + when: 'a query is executed to get a data nodes across anchors by the given CpsPath and pagination option' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '//books/ancestor::categories', INCLUDE_ALL_DESCENDANTS, new PaginationOption(1, 2)) + then: 'correct category codes are queried' + def categoryNames = result.collect { it.getLeaves().get('name') } + assert categoryNames.toSet() == ['Discount books', 'Computing', 'Comedy', 'Thriller', 'Children'].toSet() + and: 'the queried nodes have expected anchors' + assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2].toSet() + } + + def 'Count number of anchors for given dataspace name and cps path'() { + expect: '/bookstore is present in two anchors' + assert objectUnderTest.countAnchorsForDataspaceAndCpsPath(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore') == 2 + } + + def 'Cps Path query across anchors using no pagination'() { + when: 'a query is executed to get a data nodes across anchors by the given CpsPath and pagination option' + def result = objectUnderTest.queryDataNodesAcrossAnchors(FUNCTIONAL_TEST_DATASPACE_1, '/bookstore', OMIT_DESCENDANTS, NO_PAGINATION) + then: 'all bookstore names are queried' + def bookstoreNames = result.collect { it.getLeaves().get('bookstore-name') } + assert bookstoreNames.toSet() == ['Easons-1', 'Easons-2'].toSet() + and: 'the correct number of page size is returned' + assert result.size() == 2 + and: 'the queried nodes have expected bookstore names' + assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2].toSet() + } } |