summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToineSiebelink <toine.siebelink@est.tech>2023-02-23 15:49:40 +0000
committerToineSiebelink <toine.siebelink@est.tech>2023-02-27 16:11:01 +0000
commit048350463a68b774f42e80e94afe16a541711ae4 (patch)
tree56d9d921813419d39fdd5e9cb7ebe47109f046ca
parent003de55a8e6c53643032731e68edc43c0698fd81 (diff)
Expand CPS Service Integration Test (framework)
- Created package structure - Created several test bases - Created complete test set for Admin service - Created first test for Data service - Added human-readable toString() to FetchDescendantsOption for test reporting and debuging purposes - Renamed fetch descendants (enum) direct children option for consistency with others options - TODO: Add sample performance test (and base) Issue-ID: CPS-475 Signed-off-by: ToineSiebelink <toine.siebelink@est.tech> Change-Id: I75317686161be41662b6bf81314a9cd425ddd6eb
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java6
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy4
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java22
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy4
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy30
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy62
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/BookstoreSpecBase.groovy49
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy (renamed from integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy)61
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy (renamed from integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy)2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy109
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy48
11 files changed, 275 insertions, 122 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
index a98c6008cf..f6f042dc12 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============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");
@@ -24,7 +24,7 @@ package org.onap.cps.ncmp.api.impl;
import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCpsPathConditionProperties;
import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateModuleNameConditionProperties;
import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
-import static org.onap.cps.spi.FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY;
+import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
import java.util.ArrayList;
@@ -304,7 +304,7 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
}
private Set<String> getAllCmHandleIds() {
- final DataNode dataNodes = inventoryPersistence.getDataNode("/dmi-registry", FETCH_DIRECT_CHILDREN_ONLY)
+ final DataNode dataNodes = inventoryPersistence.getDataNode("/dmi-registry", DIRECT_CHILDREN_ONLY)
.iterator().next();
return dataNodes.getChildDataNodes().stream().map(dataNode -> dataNode.getLeaves().get("id").toString())
.collect(Collectors.toSet());
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
index 5cd702a6b9..f2494e6fc4 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============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");
@@ -158,7 +158,7 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
given: 'We use an empty query'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
and: 'the inventory persistence returns the dmi registry datanode with just ids'
- mockInventoryPersistence.getDataNode("/dmi-registry", FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY) >> [dmiRegistry]
+ mockInventoryPersistence.getDataNode("/dmi-registry", FetchDescendantsOption.DIRECT_CHILDREN_ONLY) >> [dmiRegistry]
and: 'the inventory persistence returns the dmi registry datanode with data'
mockInventoryPersistence.getDataNode("/dmi-registry") >> [dmiRegistry]
when: 'the query is executed for both cm handle ids and details'
diff --git a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
index 0c8cddcd73..cf5e04dc46 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Pantheon.tech
- * 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");
@@ -30,15 +30,24 @@ import org.onap.cps.spi.exceptions.DataValidationException;
@RequiredArgsConstructor
public class FetchDescendantsOption {
- public static final FetchDescendantsOption FETCH_DIRECT_CHILDREN_ONLY = new FetchDescendantsOption(1);
- public static final FetchDescendantsOption OMIT_DESCENDANTS = new FetchDescendantsOption(0);
- public static final FetchDescendantsOption INCLUDE_ALL_DESCENDANTS = new FetchDescendantsOption(-1);
+ public static final FetchDescendantsOption DIRECT_CHILDREN_ONLY
+ = new FetchDescendantsOption(1, "DirectChildrenOnly");
+ public static final FetchDescendantsOption OMIT_DESCENDANTS
+ = new FetchDescendantsOption(0, "OmitDescendants");
+ public static final FetchDescendantsOption INCLUDE_ALL_DESCENDANTS
+ = new FetchDescendantsOption(-1, "IncludeAllDescendants");
+
+ FetchDescendantsOption(final int depth) {
+ this(depth, "Depth=" + depth);
+ }
private static final Pattern FETCH_DESCENDANTS_OPTION_PATTERN =
Pattern.compile("^$|^all$|^none$|^[0-9]+$|^-1$");
private final int depth;
+ private final String optionName;
+
/**
* Has next depth.
*
@@ -85,6 +94,11 @@ public class FetchDescendantsOption {
}
}
+ @Override
+ public String toString() {
+ return optionName;
+ }
+
private static void validateFetchDescendantsOption(final String fetchDescendantsOptionAsString) {
if (Strings.isNullOrEmpty(fetchDescendantsOptionAsString)) {
return;
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
index 60286b6643..56c43d1633 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2023 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -45,7 +45,7 @@ class CpsQueryServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
where: 'all fetch descendants options are supported'
fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS,
- FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY, new FetchDescendantsOption(10)]
+ FetchDescendantsOption.DIRECT_CHILDREN_ONLY, new FetchDescendantsOption(10)]
}
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy
index c4d3dd8b7b..24f3487d17 100644
--- a/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============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");
@@ -21,15 +21,15 @@
package org.onap.cps.spi
-import org.onap.cps.spi.exceptions.DataValidationException
import spock.lang.Specification
class FetchDescendantsOptionSpec extends Specification {
- def 'Check has next descendant for fetch descendant option: #scenario'() {
+
+ def 'Has next descendant for fetch descendant option: #scenario'() {
when: 'fetch descendant option with #depth depth'
def fetchDescendantsOption = new FetchDescendantsOption(depth)
then: 'next level descendants available: #expectedHasNext'
- fetchDescendantsOption.hasNext() == expectedHasNext
+ assert fetchDescendantsOption.hasNext() == expectedHasNext
where: 'following parameters are used'
scenario | depth || expectedHasNext
'omit descendants' | 0 || false
@@ -38,7 +38,7 @@ class FetchDescendantsOptionSpec extends Specification {
'include all descendants' | -1 || true
}
- def 'Check has next descendant for fetch descendant option: invalid depth'() {
+ def 'Has next descendant for fetch descendant option: invalid depth'() {
given: 'fetch descendant option with -2 depth'
def fetchDescendantsOption = new FetchDescendantsOption(-2)
when: 'next level descendants not available'
@@ -47,7 +47,7 @@ class FetchDescendantsOptionSpec extends Specification {
thrown IllegalArgumentException
}
- def 'Get next descendant for fetch descendant option: #scenario'() {
+ def 'Next descendant for fetch descendant option: #scenario.'() {
when: 'fetch descendant option with #depth depth'
def fetchDescendantsOption = new FetchDescendantsOption(depth)
then: 'the next level of depth is as expected'
@@ -58,14 +58,14 @@ class FetchDescendantsOptionSpec extends Specification {
'second child' | 2
}
- def 'Get next descendant for fetch descendant option: include all descendants'() {
+ def 'Next descendant for fetch descendant option: include all descendants.'() {
when: 'fetch descendant option with -1 depth'
def fetchDescendantsOption = new FetchDescendantsOption(-1)
then: 'the next level of depth is as expected'
fetchDescendantsOption.next().depth == -1
}
- def 'Get next descendant for fetch descendant option: omit descendants'() {
+ def 'Next descendant for fetch descendant option: omit descendants.'() {
given: 'fetch descendant option with 0 depth'
def fetchDescendantsOption = new FetchDescendantsOption(0)
when: 'the next level of depth is not allowed'
@@ -74,7 +74,7 @@ class FetchDescendantsOptionSpec extends Specification {
thrown IllegalArgumentException
}
- def 'Create fetch descendant option with descendant using #scenario'() {
+ def 'Create fetch descendant option with descendant using #scenario.'() {
when: 'the next level of depth is not allowed'
def FetchDescendantsOption fetchDescendantsOption = FetchDescendantsOption.getFetchDescendantsOption(fetchDescendantsOptionAsString)
then: 'fetch descendant object created'
@@ -87,4 +87,16 @@ class FetchDescendantsOptionSpec extends Specification {
'No descendants using none' | 'none' || 0
'til 10th descendants using number' | '10' || 10
}
+
+ def 'String values.'() {
+ expect: 'each fetch descendant option has the correct String value'
+ assert fetchDescendantsOption.toString() == expectedStringValue
+ where: 'the following option is used'
+ fetchDescendantsOption || expectedStringValue
+ FetchDescendantsOption.OMIT_DESCENDANTS || 'OmitDescendants'
+ FetchDescendantsOption.DIRECT_CHILDREN_ONLY || 'DirectChildrenOnly'
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS || 'IncludeAllDescendants'
+ new FetchDescendantsOption(2) || 'Depth=2'
+ }
+
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy
deleted file mode 100644
index 349f0854ef..0000000000
--- a/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 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.
- * 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.integration
-
-import org.onap.cps.spi.FetchDescendantsOption
-
-class CpsPersistenceSpec extends CpsIntegrationSpecBase{
-
- def 'Test creation of test data'() {
- when: 'A dataspace, schema set and anchor are persisted'
- createDataspaceSchemaSetAnchor(TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'bookstore.yang', TEST_ANCHOR)
- and: 'data nodes are persisted under the created anchor'
- saveDataNodes(TEST_DATASPACE, TEST_ANCHOR, '/', 'BookstoreDataNodes.json')
- then: 'The dataspace has been persisted successfully'
- cpsAdminService.getDataspace(TEST_DATASPACE).getName() == TEST_DATASPACE
- and: 'The schema set has been persisted successfully'
- cpsModuleService.getSchemaSet(TEST_DATASPACE, BOOKSTORE_SCHEMA_SET).getName() == BOOKSTORE_SCHEMA_SET
- and: 'The anchor has been persisted successfully'
- cpsAdminService.getAnchor(TEST_DATASPACE, TEST_ANCHOR).getName() == TEST_ANCHOR
- and: 'The data nodes have been persisted successfully'
- cpsDataService.getDataNodes(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).iterator().next().xpath == '/bookstore'
- }
-
- def 'Test deletion of all test data'() {
- when: 'delete all from test dataspace method is called'
- deleteAllFromTestDataspace()
- and: 'the test dataspace is deleted'
- cpsAdminService.deleteDataspace(TEST_DATASPACE)
- then: 'there is no test dataspace'
- !cpsAdminService.getAllDataspaces().contains(TEST_DATASPACE)
- }
-
- def 'Read test for persisted data nodes'() {
- given:'There is a test dataspace created'
- cpsAdminService.createDataspace(TEST_DATASPACE)
- and: 'There is a schema set and anchor for the test dataspace'
- createSchemaSetAnchor(TEST_DATASPACE, 'bookstoreSchemaSet', 'bookstore.yang', TEST_ANCHOR)
- when: 'data is persisted to the database'
- saveDataNodes(TEST_DATASPACE, TEST_ANCHOR, "/", "BookstoreDataNodes.json")
- then: 'the correct data is saved'
- cpsDataService.getDataNodes(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.OMIT_DESCENDANTS).iterator().next().leaves['bookstore-name'] == 'Easons'
- }
-}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/BookstoreSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/BookstoreSpecBase.groovy
new file mode 100644
index 0000000000..7eb47b35ae
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/BookstoreSpecBase.groovy
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 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.integration.base
+
+import java.time.OffsetDateTime
+
+class BookstoreSpecBase extends CpsIntegrationSpecBase {
+
+ def static initialized = false
+
+ def setup() {
+ if (!initialized) {
+ setupBookstoreInfraStructure()
+ addBookstoreData()
+ initialized = true
+ }
+ }
+
+ def setupBookstoreInfraStructure() {
+ cpsAdminService.createDataspace(BOOKSTORE_DATASPACE)
+ def bookstoreYangModelAsString = readResourceFile('bookstore.yang')
+ cpsModuleService.createSchemaSet(BOOKSTORE_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore : bookstoreYangModelAsString])
+ cpsAdminService.createAnchor(BOOKSTORE_DATASPACE, BOOKSTORE_SCHEMA_SET, BOOKSTORE_ANCHOR)
+ }
+
+ def addBookstoreData() {
+ def bookstoreJsonData = readResourceFile('BookstoreDataNodes.json')
+ cpsDataService.saveData(BOOKSTORE_DATASPACE, BOOKSTORE_ANCHOR, bookstoreJsonData, OffsetDateTime.now())
+ }
+
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
index 960483270b..567b33cb46 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
@@ -18,15 +18,15 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.integration
+package org.onap.cps.integration.base
import org.onap.cps.api.impl.CpsAdminServiceImpl
import org.onap.cps.api.impl.CpsDataServiceImpl
import org.onap.cps.api.impl.CpsModuleServiceImpl
-import org.onap.cps.spi.CascadeDeleteAllowed
+import org.onap.cps.integration.DatabaseTestContainer
+import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.repository.DataspaceRepository
import org.onap.cps.spi.impl.utils.CpsValidatorImpl
-import org.onap.cps.utils.ContentType
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
@@ -38,8 +38,6 @@ import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
import spock.lang.Specification
-import java.time.OffsetDateTime
-
@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl])
@Testcontainers
@EnableAutoConfiguration
@@ -63,50 +61,35 @@ class CpsIntegrationSpecBase extends Specification {
@Lazy
CpsModuleServiceImpl cpsModuleService
-
- def static TEST_DATASPACE = 'testDataspace'
+ def static GENERAL_TEST_DATASPACE = 'generalTestDataSpace'
+ def static BOOKSTORE_DATASPACE = 'bookstoreDataspace'
def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
- def static TEST_ANCHOR = 'testAnchor'
+ def static BOOKSTORE_ANCHOR = 'bookstoreAnchor'
- def createDataspaceSchemaSetAnchor(String dataspaceName, String schemaSetName, String schemaSetFileName, String anchorName) {
- cpsAdminService.createDataspace(dataspaceName)
- createSchemaSetAnchor(dataspaceName, schemaSetName, schemaSetFileName, anchorName)
- }
+ def static initialized = false
- def createSchemaSetAnchor(String dataspaceName, String schemaSetName, String schemaSetFileName, String anchorName) {
- def bookstoreFileContent = readResourceFile(schemaSetFileName)
- cpsModuleService.createSchemaSet(dataspaceName, schemaSetName, [(schemaSetFileName) : bookstoreFileContent])
- cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName)
+ def setup() {
+ if (!initialized) {
+ cpsAdminService.createDataspace(GENERAL_TEST_DATASPACE)
+ def bookstoreModelFileContent = readResourceFile('bookstore.yang')
+ cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore : bookstoreModelFileContent])
+ initialized = true;
+ }
}
- def saveDataNodes(String dataspaceName, String anchorName, String parentNodeXpath, String dataNodesFileName) {
- def dataNodesAsJSON = readResourceFile(dataNodesFileName)
- if (isRootXpath(parentNodeXpath)) {
- cpsDataService.saveData(dataspaceName, anchorName, dataNodesAsJSON,
- OffsetDateTime.now(), ContentType.JSON);
- } else {
- cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath,
- dataNodesAsJSON, OffsetDateTime.now(), ContentType.JSON);
- }
+ def static countDataNodesInTree(DataNode dataNode) {
+ return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
}
- def deleteAllFromTestDataspace() {
- def anchors = cpsAdminService.getAnchors(TEST_DATASPACE)
- for(anchor in anchors) {
- cpsDataService.deleteDataNodes(TEST_DATASPACE, anchor.getName(), OffsetDateTime.now())
- cpsAdminService.deleteAnchor(TEST_DATASPACE, anchor.getName())
- }
- def schemaSets = cpsModuleService.getSchemaSets(TEST_DATASPACE)
- for(schemaSet in schemaSets) {
- cpsModuleService.deleteSchemaSet(TEST_DATASPACE, schemaSet.getName(), CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED)
+ def static countDataNodesInTree(Collection<DataNode> dataNodes) {
+ int nodeCount = 0
+ for (DataNode parent : dataNodes) {
+ nodeCount += countDataNodesInTree(parent)
}
+ return nodeCount
}
- def static readResourceFile(String filename) {
+ def static readResourceFile(filename) {
return new File('src/test/resources/data/' + filename).text
}
-
- def static isRootXpath(final String xpath) {
- return "/".equals(xpath);
- }
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy
index 0673f7eb43..18a2941615 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.integration
+package org.onap.cps.integration.base
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.notification.NotificationService
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy
new file mode 100644
index 0000000000..d504a9e0dd
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy
@@ -0,0 +1,109 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 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.integration.functional
+
+import org.onap.cps.integration.base.CpsIntegrationSpecBase
+import org.onap.cps.spi.exceptions.AlreadyDefinedException
+import org.onap.cps.spi.exceptions.AnchorNotFoundException
+import org.onap.cps.spi.exceptions.DataspaceNotFoundException
+
+class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase {
+
+ def objectUnderTest
+
+ def setup() { objectUnderTest = cpsAdminService }
+
+ def 'Dataspace CRUD operations.'() {
+ when: 'a dataspace is created'
+ objectUnderTest.createDataspace('newDataspace')
+ then: 'the dataspace can be read'
+ assert objectUnderTest.getDataspace('newDataspace').name == 'newDataspace'
+ and: 'it can be deleted'
+ objectUnderTest.deleteDataspace('newDataspace')
+ then: 'the dataspace no longer exists i.e. an exception is thrown if an attempt is made to retrieve it'
+ def thrown = null
+ try {
+ objectUnderTest.getDataspace('newDataspace')
+ } catch(Exception e) {
+ thrown = e
+ }
+ assert thrown instanceof DataspaceNotFoundException
+ }
+
+ def 'Retrieve all dataspaces (depends on total test suite).'() {
+ given: 'two addtional dataspaces are created'
+ objectUnderTest.createDataspace('dataspace1')
+ objectUnderTest.createDataspace('dataspace2')
+ when: 'all datespaces are retreived'
+ def result = objectUnderTest.getAllDataspaces()
+ then: 'there are at least 3 dataspaces (2 new ones plus the general test dataspace)'
+ result.size() >= 3
+ assert result.name.containsAll([GENERAL_TEST_DATASPACE, 'dataspace1', 'dataspace2'])
+ }
+
+ def 'Duplicate dataspaces.'() {
+ when: 'attempting to create a dataspace with the same name as an existing one'
+ objectUnderTest.createDataspace(GENERAL_TEST_DATASPACE)
+ then: 'an exception is thrown indicating the dataspace already exists'
+ thrown(AlreadyDefinedException)
+ }
+
+ def 'Anchor CRUD operations.'() {
+ when: 'a anchor is created'
+ objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor')
+ then: 'the anchor be read'
+ assert objectUnderTest.getAnchor(GENERAL_TEST_DATASPACE, 'newAnchor').name == 'newAnchor'
+ and: 'it can be deleted'
+ objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE,'newAnchor')
+ then: 'the anchor no longer exists i.e. an exception is thrown if an attempt is made to retrieve it'
+ def thrown = null
+ try {
+ objectUnderTest.getAnchor(GENERAL_TEST_DATASPACE, 'newAnchor')
+ } catch(Exception e) {
+ thrown = e
+ }
+ assert thrown instanceof AnchorNotFoundException
+ }
+
+ def 'Filtering multiple anchors.'() {
+ when: '2 anchors with bookstore schema set are created'
+ objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor1')
+ objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor2')
+ and: '1 anchor with "other" schema set is created'
+ def bookstoreModelFileContent = readResourceFile('bookstore.yang')
+ cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, 'otherSchemaSet', [someFileName: bookstoreModelFileContent])
+ objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, 'otherSchemaSet', 'anchor3')
+ then: 'there are 3 anchors in the general test database'
+ assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE).size() == 3
+ and: 'there are 2 anchors associated with bookstore schema set'
+ assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET).size() == 2
+ and: 'there is 1 anchor associated with other schema set'
+ assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE, 'otherSchemaSet').size() == 1
+ }
+
+ def 'Querying anchor(name)s (depends on previous test!).'() {
+ expect: 'there are now 3 anchors using the "stores" module (both schema sets use the same modules) '
+ assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores']).size() == 3
+ and: 'there are no anchors using both "stores" and a "unused-model"'
+ assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'unused-model']).size() == 0
+ }
+
+}
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
new file mode 100644
index 0000000000..5e839f27a8
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 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.
+ * 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.integration.functional
+
+import org.onap.cps.integration.base.BookstoreSpecBase
+import org.onap.cps.spi.FetchDescendantsOption
+
+class CpsDataServiceIntegrationSpec extends BookstoreSpecBase {
+
+ def objectUnderTest
+
+ def setup() { objectUnderTest = cpsDataService }
+
+ def 'Read bookstore top-level container(s) using #fetchDescendantsOption.'() {
+ when: 'get data nodes for bookstore container'
+ def result = objectUnderTest.getDataNodes(BOOKSTORE_DATASPACE, BOOKSTORE_ANCHOR, '/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'
+ assert result.leaves['bookstore-name'] == ['Easons']
+ where: 'the following option is used'
+ fetchDescendantsOption || expectNumberOfDataNodes
+ FetchDescendantsOption.OMIT_DESCENDANTS || 1
+ FetchDescendantsOption.DIRECT_CHILDREN_ONLY || 4
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS || 8
+ new FetchDescendantsOption(2) || 8
+ }
+
+}