From 665e22472f9658a4d439da0323e6e8760ec60840 Mon Sep 17 00:00:00 2001 From: lukegleeson Date: Wed, 11 Jan 2023 09:45:53 +0000 Subject: Springboot Integration tests improvements Creation of CpsIntegrationSpecBase Demonstration of test class implementing CpsIntegrationSpecBase in CpsPersistenceSpec Tests use reduced liquibase steps, basic bookstore yang model and bookstore json payload Issue-ID: CPS-1379 Signed-off-by: lukegleeson Change-Id: I38202d0888808d08d85fce1aab45fc43e8b0cec3 --- .../cps/integration/CpsIntegrationSpecBase.groovy | 112 +++++++++++++++++++++ .../onap/cps/integration/CpsPersistenceSpec.groovy | 61 +++++++++++ .../org/onap/cps/integration/TestConfig.groovy | 111 ++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy create mode 100644 integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy create mode 100644 integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy (limited to 'integration-test/src/test/groovy/org') diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy new file mode 100644 index 0000000000..960483270b --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy @@ -0,0 +1,112 @@ +/* + * ============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 + +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.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 +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Lazy +import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.testcontainers.spock.Testcontainers +import spock.lang.Shared +import spock.lang.Specification + +import java.time.OffsetDateTime + +@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl]) +@Testcontainers +@EnableAutoConfiguration +@EnableJpaRepositories(basePackageClasses = [DataspaceRepository]) +@ComponentScan(basePackages = ["org.onap.cps.api", "org.onap.cps.spi.repository"]) +@EntityScan("org.onap.cps.spi.entities") +class CpsIntegrationSpecBase extends Specification { + + @Shared + DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance() + + @Autowired + @Lazy + CpsAdminServiceImpl cpsAdminService + + @Autowired + @Lazy + CpsDataServiceImpl cpsDataService + + @Autowired + @Lazy + CpsModuleServiceImpl cpsModuleService + + + def static TEST_DATASPACE = 'testDataspace' + def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet' + def static TEST_ANCHOR = 'testAnchor' + + def createDataspaceSchemaSetAnchor(String dataspaceName, String schemaSetName, String schemaSetFileName, String anchorName) { + cpsAdminService.createDataspace(dataspaceName) + createSchemaSetAnchor(dataspaceName, schemaSetName, schemaSetFileName, anchorName) + } + + 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 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 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 readResourceFile(String 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/CpsPersistenceSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy new file mode 100644 index 0000000000..94bcb0a6fe --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy @@ -0,0 +1,61 @@ +/* + * ============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 + +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.getDataNode(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).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.getDataNode(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.OMIT_DESCENDANTS).leaves['bookstore-name'] == 'Easons' + } +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy new file mode 100644 index 0000000000..273d7bb55a --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy @@ -0,0 +1,111 @@ +/* + * ============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 + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.notification.NotificationService +import org.onap.cps.spi.CpsDataPersistenceService +import org.onap.cps.spi.CpsModulePersistenceService +import org.onap.cps.spi.impl.CpsAdminPersistenceServiceImpl +import org.onap.cps.spi.impl.CpsDataPersistenceServiceImpl +import org.onap.cps.spi.impl.CpsModulePersistenceServiceImpl +import org.onap.cps.spi.repository.AnchorRepository +import org.onap.cps.spi.repository.DataspaceRepository +import org.onap.cps.spi.repository.FragmentRepository +import org.onap.cps.spi.repository.ModuleReferenceRepository +import org.onap.cps.spi.repository.SchemaSetRepository +import org.onap.cps.spi.repository.YangResourceRepository +import org.onap.cps.spi.utils.SessionManager +import org.onap.cps.utils.JsonObjectMapper +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Lazy +import spock.lang.Specification + +@Configuration +class TestConfig extends Specification{ + @Autowired + @Lazy + DataspaceRepository dataspaceRepository + + @Autowired + @Lazy + AnchorRepository anchorRepository + + @Autowired + @Lazy + SchemaSetRepository schemaSetRepository + + @Autowired + @Lazy + YangResourceRepository yangResourceRepository + + @Autowired + @Lazy + FragmentRepository fragmentRepository + + @Autowired + @Lazy + ModuleReferenceRepository moduleReferenceRepository + + @Autowired + @Lazy + JsonObjectMapper jsonObjectMapper + + @Autowired + @Lazy + NotificationService stubbedNotificationService + + @Autowired + @Lazy + SessionManager stubbedSessionManager + + @Bean + CpsAdminPersistenceServiceImpl cpsAdminPersistenceService() { + new CpsAdminPersistenceServiceImpl(dataspaceRepository, anchorRepository, schemaSetRepository, yangResourceRepository) + } + + @Bean + CpsDataPersistenceService cpsDataPersistenceService() { + return (CpsDataPersistenceService) new CpsDataPersistenceServiceImpl(dataspaceRepository, anchorRepository, fragmentRepository, jsonObjectMapper, stubbedSessionManager) + } + + @Bean + CpsModulePersistenceService cpsModulePersistenceService() { + return (CpsModulePersistenceService) new CpsModulePersistenceServiceImpl(yangResourceRepository, schemaSetRepository, dataspaceRepository, cpsAdminPersistenceService(), moduleReferenceRepository) + } + + @Bean + JsonObjectMapper jsonObjectMapper() { + return new JsonObjectMapper(new ObjectMapper()) + } + + @Bean + NotificationService notificationService() { + return Stub(NotificationService) + } + + @Bean + SessionManager sessionManager() { + return Stub(SessionManager) + } +} \ No newline at end of file -- cgit 1.2.3-korg