summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-ri/pom.xml2
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy69
-rw-r--r--cps-ri/src/test/resources/data/cps-path-query.sql109
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy11
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy18
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsQueryServiceIntegrationSpec.groovy86
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy28
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy4
9 files changed, 112 insertions, 223 deletions
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 6ee2d2183..e9b2abb3f 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -33,7 +33,7 @@
<artifactId>cps-ri</artifactId>
<properties>
- <minimum-coverage>0.94</minimum-coverage>
+ <minimum-coverage>0.82</minimum-coverage>
</properties>
<dependencies>
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
deleted file mode 100644
index f025206c3..000000000
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceQueryDataNodeSpec.groovy
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
- * Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2021 Bell Canada.
- * 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.
- * 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.impl
-
-import org.onap.cps.spi.CpsDataPersistenceService
-import org.onap.cps.spi.exceptions.CpsPathException
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.test.context.jdbc.Sql
-
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
-
-class CpsDataPersistenceQueryDataNodeSpec extends CpsPersistenceSpecBase {
-
- @Autowired
- CpsDataPersistenceService objectUnderTest
-
- static final String SET_DATA = '/data/cps-path-query.sql'
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Cps Path query across anchors for leaf value(s) with : #scenario.'() {
- when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodesAcrossAnchors(DATASPACE_NAME, cpsPath, includeDescendantsOption)
- then: 'the correct number of queried nodes are returned'
- assert result.size() == expectedNumberOfQueriedNodes
- and : 'correct anchors are queried'
- assert result.anchorName.containsAll(expectedAnchors)
- where: 'the following data is used'
- scenario | cpsPath | includeDescendantsOption || expectedNumberOfQueriedNodes || expectedAnchors
- 'String and no descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@title="Dune"]' | OMIT_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005']
- 'Integer and descendants' | '/shops/shop[@id=1]/categories[@code=1]/book[@price=5]' | INCLUDE_ALL_DESCENDANTS || 3 || ['ANCHOR-004', 'ANCHOR-005']
- 'No condition no descendants' | '/shops/shop[@id=1]/categories' | OMIT_DESCENDANTS || 6 || ['ANCHOR-004', 'ANCHOR-005']
- 'multiple list-ancestors' | '//book/ancestor::categories' | INCLUDE_ALL_DESCENDANTS || 4 || ['ANCHOR-004', 'ANCHOR-005']
- 'one ancestor with list value' | '//book/ancestor::categories[@code=1]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005']
- 'list with index value in the xpath prefix' | '//categories[@code=1]/book/ancestor::shop[@id=1]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005']
- 'ancestor with parent list' | '//book/ancestor::shop[@id=1]/categories[@code=2]' | INCLUDE_ALL_DESCENDANTS || 2 || ['ANCHOR-004', 'ANCHOR-005']
- 'ancestor with parent' | '//phonenumbers[@type="mob"]/ancestor::info/contact' | INCLUDE_ALL_DESCENDANTS || 5 || ['ANCHOR-004', 'ANCHOR-005']
- 'ancestor combined with text condition' | '//book/title[text()="Dune"]/ancestor::shop' | INCLUDE_ALL_DESCENDANTS || 10 || ['ANCHOR-004', 'ANCHOR-005']
- 'ancestor with parent that does not exist' | '//book/ancestor::parentDoesNoExist/categories' | INCLUDE_ALL_DESCENDANTS || 0 || []
- 'ancestor does not exist' | '//book/ancestor::ancestorDoesNotExist' | INCLUDE_ALL_DESCENDANTS || 0 || []
- }
-
- 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(DATASPACE_NAME, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS)
- then: 'a cps path exception is thrown'
- thrown(CpsPathException)
- }
-}
diff --git a/cps-ri/src/test/resources/data/cps-path-query.sql b/cps-ri/src/test/resources/data/cps-path-query.sql
deleted file mode 100644
index 5fe927bc0..000000000
--- a/cps-ri/src/test/resources/data/cps-path-query.sql
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- ============LICENSE_START=======================================================
- Copyright (C) 2021-2022 Nordix Foundation.
- Modifications Copyright (C) 2021 Bell Canada.
- 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.
- 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=========================================================
-*/
-
-INSERT INTO DATASPACE (ID, NAME) VALUES
- (1001, 'DATASPACE-001');
-
-INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES
- (2001, 'SCHEMA-SET-001', 1001);
-
-INSERT INTO YANG_RESOURCE (ID, FILE_NAME, CONTENT, CHECKSUM, MODULE_NAME, REVISION) VALUES
- (4001, 'TEST','', 'SAMPLECHECKSUM','TESTMODULENAME', 'SAMPLEREVISION');
-
-UPDATE YANG_RESOURCE SET
-content = 'module stores {
- yang-version 1.1;
- namespace "org:onap:ccsdk:sample";
-
- prefix book-store;
-
- revision "2020-09-15" {
- description
- "Sample Model";
- }
- }
-'
-where ID = 4001;
-
-
-INSERT INTO SCHEMA_SET_YANG_RESOURCES (SCHEMA_SET_ID, YANG_RESOURCE_ID) VALUES
- (2001, 4001);
-
-INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES
- (1003, 'ANCHOR-004', 1001, 2001);
-
-INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES
- (1004, 'ANCHOR-005', 1001, 2001);
-
-INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (1, 1001, 1003, null, '/shops', null),
- (2, 1001, 1003, 1, '/shops/shop[@id=''1'']', '{"id" : 1, "type" : "bookstore"}'),
- (3, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''1'']', '{"code" : 1, "type" : "bookstore", "name": "SciFi"}'),
- (4, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'),
- (31, 1001, 1003, 2, '/shops/shop[@id=''1'']/categories[@code=''string/with/slash/'']', '{"code" : "string/with/slash", "type" : "text/with/slash", "name": "Fiction"}'),
- (5, 1001, 1003, 3, '/shops/shop[@id=''1'']/categories[@code=''1'']/book', '{"price" : 5, "title" : "Dune", "labels" : ["special offer","classics",""]}'),
- (6, 1001, 1003, 4, '/shops/shop[@id=''1'']/categories[@code=''2'']/book', '{"price" : 15, "title" : "Chapters", "editions" : [2000,2010,2020]}'),
- (7, 1001, 1003, 5, '/shops/shop[@id=''1'']/categories[@code=''1'']/book/author[@FirstName=''Joe'' and @Surname=''Bloggs'']', '{"FirstName" : "Joe", "Surname": "Bloggs","title": "Dune"}'),
- (8, 1001, 1003, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Surname=''Smith'']', '{"FirstName" : "Joe", "Surname": "Smith","title": "Chapters"}'),
- (32, 1001, 1003, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Address=''string[with]square[brackets]'']', '{"FirstName" : "Joe", "Address": "string[with]square[brackets]","title": "Chapters"}');
-
- INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (9, 1001, 1003, 1, '/shops/shop[@id=''2'']', '{"type" : "bookstore"}'),
- (10, 1001, 1003, 9, '/shops/shop[@id=''2'']/categories[@code=''1'']', '{"code" : 2, "type" : "bookstore", "name": "Kids"}'),
- (11, 1001, 1003, 10, '/shops/shop[@id=''2'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}');
-
- INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (12, 1001, 1003, 1, '/shops/shop[@id=''3'']', '{"type" : "garden centre"}'),
- (13, 1001, 1003, 12, '/shops/shop[@id=''3'']/categories[@code=''1'']', '{"id" : 1, "type" : "garden centre", "name": "indoor plants"}'),
- (14, 1001, 1003, 12, '/shops/shop[@id=''3'']/categories[@code=''2'']', '{"id" : 2, "type" : "garden centre", "name": "outdoor plants"}'),
- (16, 1001, 1003, 1, '/shops/shop[@id=''3'']/info', null),
- (17, 1001, 1003, 1, '/shops/shop[@id=''3'']/info/contact', null),
- (18, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/website', '{"address" : "myshop.ie"}'),
- (19, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''mob'']', '{"type" : "mob", "number" : "123123456"}'),
- (20, 1001, 1003, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''landline'']', '{"type" : "landline", "number" : "012123456"}');
-
- INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (41, 1001, 1004, null, '/shops', null),
- (42, 1001, 1004, 1, '/shops/shop[@id=''1'']', '{"id" : 1, "type" : "bookstore"}'),
- (43, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''1'']', '{"code" : 1, "type" : "bookstore", "name": "SciFi"}'),
- (44, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}'),
- (71, 1001, 1004, 2, '/shops/shop[@id=''1'']/categories[@code=''string/with/slash/'']', '{"code" : "string/with/slash", "type" : "text/with/slash", "name": "Fiction"}'),
- (45, 1001, 1004, 3, '/shops/shop[@id=''1'']/categories[@code=''1'']/book', '{"price" : 5, "title" : "Dune", "labels" : ["special offer","classics",""]}'),
- (46, 1001, 1004, 4, '/shops/shop[@id=''1'']/categories[@code=''2'']/book', '{"price" : 15, "title" : "Chapters", "editions" : [2000,2010,2020]}'),
- (47, 1001, 1004, 5, '/shops/shop[@id=''1'']/categories[@code=''1'']/book/author[@FirstName=''Joe'' and @Surname=''Bloggs'']', '{"FirstName" : "Joe", "Surname": "Bloggs","title": "Dune"}'),
- (48, 1001, 1004, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Surname=''Smith'']', '{"FirstName" : "Joe", "Surname": "Smith","title": "Chapters"}'),
- (72, 1001, 1004, 6, '/shops/shop[@id=''1'']/categories[@code=''2'']/book/author[@FirstName=''Joe'' and @Address=''string[with]square[brackets]'']', '{"FirstName" : "Joe", "Address": "string[with]square[brackets]","title": "Chapters"}');
-
- INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (49, 1001, 1004, 1, '/shops/shop[@id=''2'']', '{"type" : "bookstore"}'),
- (50, 1001, 1004, 9, '/shops/shop[@id=''2'']/categories[@code=''1'']', '{"code" : 2, "type" : "bookstore", "name": "Kids"}'),
- (51, 1001, 1004, 10, '/shops/shop[@id=''2'']/categories[@code=''2'']', '{"code" : 2, "type" : "bookstore", "name": "Fiction"}');
-
- INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) VALUES
- (52, 1001, 1004, 1, '/shops/shop[@id=''3'']', '{"type" : "garden centre"}'),
- (53, 1001, 1004, 12, '/shops/shop[@id=''3'']/categories[@code=''1'']', '{"id" : 1, "type" : "garden centre", "name": "indoor plants"}'),
- (54, 1001, 1004, 12, '/shops/shop[@id=''3'']/categories[@code=''2'']', '{"id" : 2, "type" : "garden centre", "name": "outdoor plants"}'),
- (56, 1001, 1004, 1, '/shops/shop[@id=''3'']/info', null),
- (57, 1001, 1004, 1, '/shops/shop[@id=''3'']/info/contact', null),
- (58, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/website', '{"address" : "myshop.ie"}'),
- (59, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''mob'']', '{"type" : "mob", "number" : "123123456"}'),
- (60, 1001, 1004, 17, '/shops/shop[@id=''3'']/info/contact/phonenumbers[@type=''landline'']', '{"type" : "landline", "number" : "012123456"}');
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 866fef4f2..b942a43af 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
@@ -40,6 +40,8 @@ import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
import spock.lang.Specification
+import java.time.OffsetDateTime
+
@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl])
@Testcontainers
@EnableAutoConfiguration
@@ -68,9 +70,7 @@ class CpsIntegrationSpecBase extends Specification {
CpsQueryService cpsQueryService
def static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
- def static FUNCTIONAL_TEST_DATASPACE = 'functionalTestDataspace'
def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
- def static BOOKSTORE_ANCHOR = 'bookstoreAnchor'
def static initialized = false
@@ -107,4 +107,11 @@ class CpsIntegrationSpecBase extends Specification {
}
return true
}
+
+ def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
+ (1..numberOfAnchors).each {
+ cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
+ cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data, 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 5e5269114..b7a6030d8 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
@@ -20,10 +20,14 @@
package org.onap.cps.integration.base
-import java.time.OffsetDateTime
-
class FunctionalSpecBase extends CpsIntegrationSpecBase {
+ def static FUNCTIONAL_TEST_DATASPACE_1 = 'functionalTestDataspace1'
+ def static FUNCTIONAL_TEST_DATASPACE_2 = 'functionalTestDataspace2'
+ def static NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA = 2
+ def static BOOKSTORE_ANCHOR_1 = 'bookstoreAnchor1'
+ def static BOOKSTORE_ANCHOR_2 = 'bookstoreAnchor2'
+
def static initialized = false
def setup() {
@@ -35,15 +39,17 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
}
def setupBookstoreInfraStructure() {
- cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE)
+ cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1)
+ cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2)
def bookstoreYangModelAsString = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, BOOKSTORE_ANCHOR)
+ cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
+ cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
}
def addBookstoreData() {
def bookstoreJsonData = readResourceDataFile('bookstore/bookstoreData.json')
- cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, bookstoreJsonData, OffsetDateTime.now())
+ addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA, FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchor', bookstoreJsonData)
+ addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA, FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchor', bookstoreJsonData)
}
}
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 25e71f18d..f609ba00e 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
@@ -33,7 +33,7 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase {
def 'Read bookstore top-level container(s) using #fetchDescendantsOption.'() {
when: 'get data nodes for bookstore container'
- def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '/bookstore', fetchDescendantsOption)
+ def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', fetchDescendantsOption)
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'
@@ -48,11 +48,11 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase {
def 'Read bookstore top-level container(s) has correct dataspace and anchor.'() {
when: 'get data nodes for bookstore container'
- def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
then: 'the correct dataspace was queried'
- assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE].toSet()
+ assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet()
and: 'the correct anchor was queried'
- assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR].toSet()
+ assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1].toSet()
}
}
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 1a31cdde3..47027e463 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
@@ -24,6 +24,7 @@ import org.onap.cps.api.CpsQueryService
import org.onap.cps.integration.base.FunctionalSpecBase
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.CpsPathException
+import spock.lang.Ignore
import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
@@ -37,7 +38,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Query bookstore using CPS path where #scenario.'() {
when: 'query data nodes for bookstore container'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS)
then: 'the result contains expected number of nodes'
assert result.size() == expectedResultSize
and: 'the result contains the expected leaf values'
@@ -54,7 +55,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query for leaf value(s) with #scenario.'() {
when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, fetchDescendantsOption)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, fetchDescendantsOption)
then: 'the correct number of parent nodes are returned'
assert result.size() == expectedNumberOfParentNodes
and: 'the correct total number of data nodes are returned'
@@ -70,7 +71,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Query for attribute by cps path with cps paths that return no data because of #scenario.'() {
when: 'a query is executed to get data nodes for the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, OMIT_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
then: 'no data is returned'
assert result.isEmpty()
where: 'following cps queries are performed'
@@ -82,7 +83,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query using descendant anywhere and #type (further) descendants.'() {
when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '/bookstore/categories[@code="1"]', fetchDescendantsOption)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="1"]', fetchDescendantsOption)
then: 'the data node has the correct number of children'
assert result[0].childDataNodes.xpath.sort() == expectedChildNodes.sort()
where: 'the following data is used'
@@ -94,14 +95,14 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query for all books.'() {
when: 'a query is executed to get all books'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '//books', OMIT_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '//books', OMIT_DESCENDANTS)
then: 'the expected number of books are returned'
assert result.size() == 9
}
def 'Cps Path query using descendant anywhere with #scenario.'() {
when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, OMIT_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
then: 'xpaths of the retrieved data nodes are as expected'
def bookTitles = result.collect { it.getLeaves().get('title') }
assert bookTitles.sort() == expectedBookTitles.sort()
@@ -123,7 +124,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query using descendant anywhere with #scenario condition for a container element.'() {
when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, OMIT_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
then: 'book titles from the retrieved data nodes are as expected'
def bookTitles = result.collect { it.getLeaves().get('title') }
assert bookTitles.sort() == expectedBookTitles.sort()
@@ -138,7 +139,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query using descendant anywhere with #scenario condition(s) for a list element.'() {
when: 'a query is executed to get a data node by the given cps path'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS)
then: 'xpaths of the retrieved data nodes are as expected'
result.xpath.toList() == ["/bookstore/premises/addresses[@house-number='2' and @street='Main Street']"]
where: 'the following data is used'
@@ -151,7 +152,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Query for attribute by cps path of type ancestor with #scenario.'() {
when: 'the given cps path is parsed'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, cpsPath, OMIT_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
then: 'the xpaths of the retrieved data nodes are as expected'
assert result.xpath.sort() == expectedXPaths.sort()
where: 'the following data is used'
@@ -169,7 +170,7 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Query for attribute by cps path of type ancestor with #scenario descendants.'() {
when: 'the given cps path is parsed'
- def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, '//books/ancestor::bookstore', fetchDescendantsOption)
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '//books/ancestor::bookstore', fetchDescendantsOption)
then: 'the xpaths of the retrieved data nodes are as expected'
assert countDataNodesInTree(result) == expectedNumberOfNodes
where: 'the following data is used'
@@ -181,7 +182,70 @@ class CpsQueryServiceIntegrationSpec extends FunctionalSpecBase {
def 'Cps Path query with syntax error throws a CPS Path Exception.'() {
when: 'trying to execute a query with a syntax (parsing) error'
- objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE, BOOKSTORE_ANCHOR, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS)
+ objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, 'cpsPath that cannot be parsed' , OMIT_DESCENDANTS)
+ then: 'a cps path exception is thrown'
+ thrown(CpsPathException)
+ }
+
+ @Ignore
+ 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)
+ then: 'the correct dataspace is queried'
+ assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet()
+ and: 'correct anchors are queried'
+ assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2].toSet()
+ and: 'the correct number of nodes is returned'
+ assert result.size() == expectedXpathsPerAnchor.size() * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA
+ and: 'the queried nodes have expected xpaths'
+ assert result.xpath.toSet() == expectedXpathsPerAnchor.toSet()
+ where: 'the following data is used'
+ 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']"]
+ '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']"]
+ 'one ancestor with list value' | '//books/ancestor::categories[@code="1"]' || ["/bookstore/categories[@code='1']"]
+ 'list with index value in the xpath prefix' | '//categories[@code="1"]/books/ancestor::bookstore' || ["/bookstore"]
+ 'ancestor with parent list' | '//books/ancestor::bookstore/categories' || ["/bookstore/categories[@code='1']", "/bookstore/categories[@code='2']", "/bookstore/categories[@code='3']", "/bookstore/categories[@code='4']"]
+ 'ancestor with parent list element' | '//books/ancestor::bookstore/categories[@code="2"]' || ["/bookstore/categories[@code='2']"]
+ 'ancestor combined with text condition' | '//books/title[text()="Matilda"]/ancestor::bookstore' || ["/bookstore"]
+ }
+
+ @Ignore
+ 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)
+ then: 'the correct dataspace was queried'
+ assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet()
+ and: 'correct number of datanodes are returned'
+ assert countDataNodesInTree(result) == expectedNumberOfNodesPerAnchor * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA
+ where: 'the following data is used'
+ scenario | fetchDescendantsOption || expectedNumberOfNodesPerAnchor
+ 'no' | OMIT_DESCENDANTS || 1
+ 'direct' | DIRECT_CHILDREN_ONLY || 6
+ 'all' | INCLUDE_ALL_DESCENDANTS || 17
+ }
+
+ @Ignore
+ 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)
+ then: 'the correct dataspace was queried'
+ assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet()
+ and: 'correct number of datanodes are returned'
+ assert countDataNodesInTree(result) == expectedNumberOfNodesPerAnchor * NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA
+ where: 'the following data is used'
+ scenario | fetchDescendantsOption || expectedNumberOfNodesPerAnchor
+ 'no' | OMIT_DESCENDANTS || 1
+ 'direct' | DIRECT_CHILDREN_ONLY || 6
+ 'all' | INCLUDE_ALL_DESCENDANTS || 17
+ }
+
+ 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)
then: 'a cps path exception is thrown'
thrown(CpsPathException)
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
index 3b5f69c6e..d339f6ddc 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
@@ -20,11 +20,8 @@
package org.onap.cps.integration.performance.base
-import org.onap.cps.spi.FetchDescendantsOption
-
-import java.time.OffsetDateTime
-import org.onap.cps.integration.base.CpsIntegrationSpecBase
import org.onap.cps.rest.utils.MultipartFileUtil
+import org.onap.cps.spi.FetchDescendantsOption
import org.springframework.web.multipart.MultipartFile
class CpsPerfTestBase extends PerfTestBase {
@@ -41,8 +38,8 @@ class CpsPerfTestBase extends PerfTestBase {
def setupPerformanceInfraStructure() {
cpsAdminService.createDataspace(CPS_PERFORMANCE_TEST_DATASPACE)
- def modelAsString = CpsIntegrationSpecBase.readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString])
+ def modelAsString = readResourceDataFile('bookstore/bookstore.yang')
+ cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString])
}
def createInitialData() {
@@ -55,16 +52,16 @@ class CpsPerfTestBase extends PerfTestBase {
def createWarmupData() {
def data = "{\"bookstore\":{}}"
stopWatch.start()
- addAnchorsWithData(1, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, 'warmup', data)
+ addAnchorsWithData(1, CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'warmup', data)
stopWatch.stop()
def durationInMillis = stopWatch.getTotalTimeMillis()
recordAndAssertPerformance('Creating warmup anchor with tiny data tree', 500, durationInMillis)
}
def createLargeBookstoresData() {
- def data = CpsIntegrationSpecBase.readResourceDataFile('bookstore/largeModelData.json')
+ def data = readResourceDataFile('bookstore/largeModelData.json')
stopWatch.start()
- addAnchorsWithData(5, CpsIntegrationSpecBase.BOOKSTORE_SCHEMA_SET, 'bookstore', data)
+ addAnchorsWithData(5, CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'bookstore', data)
stopWatch.stop()
def durationInMillis = stopWatch.getTotalTimeMillis()
recordAndAssertPerformance('Creating bookstore anchors with large data tree', 3_000, durationInMillis)
@@ -75,32 +72,25 @@ class CpsPerfTestBase extends PerfTestBase {
def multipartFile = Mock(MultipartFile)
multipartFile.getOriginalFilename() >> file.getName()
multipartFile.getInputStream() >> new FileInputStream(file)
- cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, PerfTestBase.LARGE_SCHEMA_SET, MultipartFileUtil.extractYangResourcesMap(multipartFile))
+ cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, MultipartFileUtil.extractYangResourcesMap(multipartFile))
}
def addOpenRoadData() {
def data = generateOpenRoadData(50)
stopWatch.start()
- addAnchorsWithData(5, PerfTestBase.LARGE_SCHEMA_SET, 'openroadm', data)
+ addAnchorsWithData(5, CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'openroadm', data)
stopWatch.stop()
def durationInMillis = stopWatch.getTotalTimeMillis()
recordAndAssertPerformance('Creating openroadm anchors with large data tree', 25_000, durationInMillis)
}
def generateOpenRoadData(numberOfNodes) {
- def innerNode = CpsIntegrationSpecBase.readResourceDataFile('openroadm/innerNode.json')
+ def innerNode = readResourceDataFile('openroadm/innerNode.json')
return '{ "openroadm-devices": { "openroadm-device": [' +
(1..numberOfNodes).collect { innerNode.replace('NODE_ID_HERE', it.toString()) }.join(',') +
']}}'
}
- def addAnchorsWithData(numberOfAnchors, schemaSetName, anchorNamePrefix, data) {
- (1..numberOfAnchors).each {
- cpsAdminService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, anchorNamePrefix + it)
- cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, anchorNamePrefix + it, data, OffsetDateTime.now())
- }
- }
-
def 'Warm the database'() {
when: 'get data nodes for warmup anchor'
stopWatch.start()
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy
index adece2ebf..d169bd757 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpRegistryPerfTestBase.groovy
@@ -40,12 +40,12 @@ class NcmpRegistryPerfTestBase extends PerfTestBase {
def setupPerformanceInfraStructure() {
cpsAdminService.createDataspace(NCMP_PERFORMANCE_TEST_DATASPACE)
- def modelAsString = CpsIntegrationSpecBase.readResourceDataFile('ncmp-registry/dmi-registry@2022-05-10.yang')
+ def modelAsString = readResourceDataFile('ncmp-registry/dmi-registry@2022-05-10.yang')
cpsModuleService.createSchemaSet(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, [registry: modelAsString])
}
def createInitialData() {
- def data = CpsIntegrationSpecBase.readResourceDataFile('ncmp-registry/1000-cmhandles.json')
+ def data = readResourceDataFile('ncmp-registry/1000-cmhandles.json')
cpsAdminService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, REGISTRY_ANCHOR)
cpsDataService.saveData(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, data, OffsetDateTime.now())
}