summaryrefslogtreecommitdiffstats
path: root/integration-test/src
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 /integration-test/src
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
Diffstat (limited to 'integration-test/src')
-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
6 files changed, 229 insertions, 102 deletions
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 349f0854e..000000000
--- 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 000000000..7eb47b35a
--- /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 960483270..567b33cb4 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 0673f7eb4..18a294161 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 000000000..d504a9e0d
--- /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 000000000..5e839f27a
--- /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
+ }
+
+}