From 26a51754dd8aa9b467bcb442e6042f22af2ba001 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Mon, 8 May 2023 17:54:46 +0100 Subject: Move integration test for moduleService - all modules service interation test moved - added some aditional scenarios to increase coverage - removed unused method(s) - remove javdoc on private methods - some minor refactoring like replace 'var' with correct type Issue-ID: CPS-1687 Signed-off-by: ToineSiebelink Change-Id: I03ff1f3562cfe38318e8b9af81be47a1fe667da2 --- .../CpsModuleServiceIntegrationSpec.groovy | 278 +++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy (limited to 'integration-test') diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy new file mode 100644 index 000000000..cfc8ab7ad --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy @@ -0,0 +1,278 @@ +/* + * ============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.api.impl.CpsModuleServiceImpl +import org.onap.cps.integration.base.FunctionalSpecBase +import org.onap.cps.spi.CascadeDeleteAllowed +import org.onap.cps.spi.exceptions.AlreadyDefinedException +import org.onap.cps.spi.exceptions.DataspaceNotFoundException +import org.onap.cps.spi.exceptions.ModelValidationException +import org.onap.cps.spi.exceptions.SchemaSetInUseException +import org.onap.cps.spi.exceptions.SchemaSetNotFoundException +import org.onap.cps.spi.model.ModuleDefinition +import org.onap.cps.spi.model.ModuleReference + +class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase { + + CpsModuleServiceImpl objectUnderTest + + private static def originalNumberOfModuleReferences = 1 + private static def existingModuleReference = new ModuleReference('stores','2020-09-15') + static def NEW_RESOURCE_REVISION = '2023-05-10' + static def NEW_RESOURCE_CONTENT = 'module test_module {\n' + + ' yang-version 1.1;\n' + + ' namespace "org:onap:ccsdk:sample";\n' + + '\n' + + ' prefix book-store;\n' + + '\n' + + ' revision "2023-05-10" {\n' + + ' description\n' + + ' "Sample Model";\n' + + ' }' + + '}' + + def newYangResourcesNameToContentMap = [:] + def moduleReferences = [] + + def setup() { + objectUnderTest = cpsModuleService + } + + /* + C R E A T E S C H E M A S E T U S E - C A S E S + */ + + def 'Create new schema set from yang resources with #scenario'() { + given: 'a new schema set with #numberOfModules modules' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules) + when: 'the new schema set is created' + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap) + then: 'the number of module references has increased by #expectedIncrease' + def yangResourceModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1) + originalNumberOfModuleReferences + numberOfNewModules == yangResourceModuleReferences.size() + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchemaSet' ]) + where: 'the following parameters are use' + scenario | numberOfNewModules + 'two valid new modules' | 2 + 'empty schema set' | 0 + 'over max batch size #modules' | 101 + } + + def 'Create new schema set with recommended filename format but invalid yang'() { + given: 'a filename using RFC6020 recommended format (for coverage only)' + def fileName = 'test@2023-05-11.yang' + when: 'attempt to create a schema set with invalid Yang' + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', [(fileName) :'invalid yang']) + then: 'a model validation exception' + thrown(ModelValidationException) + } + + def 'Create new schema set from modules with #scenario'() { + given: 'a new schema set with #numberOfNewModules modules' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules) + and: 'add existing module references (optional)' + moduleReferences.addAll(existingModuleReferences) + when: 'the new schema set is created' + def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules" + objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences) + and: 'associated with a new anchor' + cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor') + then: 'the new anchor has the correct number of modules' + def yangResourceModuleReferences = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'newAnchor') + assert expectedNumberOfModulesForAnchor == yangResourceModuleReferences.size() + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ schemaSetName.toString() ]) + where: 'the following module references are provided' + scenario | numberOfNewModules | existingModuleReferences || expectedNumberOfModulesForAnchor + 'empty schema set' | 0 | [ ] || 0 + 'one existing module' | 0 | [ existingModuleReference ] || 1 + 'two new modules' | 2 | [ ] || 2 + 'two new modules, one existing' | 2 | [ existingModuleReference ] || 3 + 'over max batch size #modules' | 101 | [ ] || 101 + 'two valid, one invalid module' | 2 | [ new ModuleReference('NOT EXIST','IRRELEVANT') ] || 2 + } + + def 'Duplicate schema content.'() { + given: 'a map of yang resources' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(1) + when: 'a new schema set is created' + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap) + then: 'the dataspace has one new module (reference)' + def numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size() + assert numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded == originalNumberOfModuleReferences + 1 + when: 'a second new schema set is created' + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema2', newYangResourcesNameToContentMap) + then: 'the dataspace has no additional module (reference)' + assert numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded == objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size() + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchema1', 'newSchema2']) + } + + def 'Create schema set error scenario: #scenario.'() { + when: 'attempt to store schema set #schemaSetName in dataspace #dataspaceName' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(0) + objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, newYangResourcesNameToContentMap) + then: 'an #expectedException is thrown' + thrown(expectedException) + where: 'the following data is used' + scenario | dataspaceName | schemaSetName || expectedException + 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException + 'schema set already exists' | FUNCTIONAL_TEST_DATASPACE_1 | BOOKSTORE_SCHEMA_SET || AlreadyDefinedException + } + + /* + R E A D S C H E M A S E T I N F O U S E - C A S E S + */ + + def 'Retrieving module definitions by anchor.'() { + when: 'the module definitions for an anchor are retrieved' + def result = objectUnderTest.getModuleDefinitionsByAnchorName(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1) + then: 'the correct module definitions are returned' + result == [new ModuleDefinition('stores','2020-09-15','')] + } + + def 'Retrieving yang resource module references by anchor.'() { + when: 'the yang resource module references for an anchor are retrieved' + def result = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1) + then: 'the correct module references are returned' + result == [ existingModuleReference ] + } + + def 'Identifying new module references with #scenario'() { + when: 'identifyNewModuleReferences is called' + def result = objectUnderTest.identifyNewModuleReferences(moduleReferences) + then: 'the correct module references are returned' + assert result.size() == expectedResult.size() + assert result.containsAll(expectedResult) + where: 'the following data is used' + scenario | moduleReferences || expectedResult + 'just new module references' | [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')] || [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')] + 'one new module,one existing reference' | [new ModuleReference('new1', 'r1'), existingModuleReference] || [new ModuleReference('new1', 'r1')] + 'no new module references' | [existingModuleReference] || [] + 'no module references' | [] || [] + 'module references collection is null' | null || [] + } + + def 'Retrieve schema set.'() { + when: 'a specific schema set is retreived' + def result = objectUnderTest.getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET) + then: 'the result has the correct name and module(s)' + assert result.name == 'bookstoreSchemaSet' + assert result.moduleReferences == [ new ModuleReference('stores', '2020-09-15', 'org:onap:ccsdk:sample') ] + } + + def 'Retrieve all schema sets.'() { + given: 'an extra schema set is stored' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(1) + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap) + when: 'all schema sets are retrieved' + def result = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1) + then: 'the result contains all expected schema sets' + assert result.name == [ 'bookstoreSchemaSet', 'newSchema1' ] + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchema1']) + } + + /* + D E L E T E S C H E M A S E T U S E - C A S E S + */ + + def 'Delete schema sets with(out) cascade.'() { + given: 'a schema set' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(1) + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap) + and: 'optionally create anchor for the schema set' + if (associateWithAnchor) { + cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor') + } + when: 'attempt to delete the schema set' + try { + objectUnderTest.deleteSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', cascadeDeleteAllowedOption) + } + catch (Exception e) { // only accept correct exception when schema set cannot be deleted + assert e instanceof SchemaSetInUseException && expectSchemaSetStillPresent + } + then: 'check if the dataspace still contains the new schema set or not' + def remainingSchemaSetNames = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).name + assert remainingSchemaSetNames.contains('newSchemaSet') == expectSchemaSetStillPresent + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet']) + where: 'the following options are used' + associateWithAnchor | cascadeDeleteAllowedOption || expectSchemaSetStillPresent + false | CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED || false + false | CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED || false + true | CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED || false + true | CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED || true + } + + def 'Delete schema sets with shared resources.'() { + given: 'a new schema set' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(1) + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet1', newYangResourcesNameToContentMap) + and: 'another schema set which shares one yang resource (module)' + populateNewYangResourcesNameToContentMapAndAllModuleReferences(2) + objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet2', newYangResourcesNameToContentMap) + when: 'all schema sets are retrieved' + def moduleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision + then: 'both modules (revisions) are present' + assert moduleRevisions.containsAll(['2000-01-01', '2000-01-01']) + when: 'delete the second schema set that has two resources one of which is a shared resource' + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet2']) + then: 'only the second schema set is deleted' + def remainingSchemaSetNames = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).name + assert remainingSchemaSetNames.contains('newSchemaSet1') + assert !remainingSchemaSetNames.contains('newSchemaSet2') + and: 'only the shared module (revision) remains' + def remainingModuleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision + assert remainingModuleRevisions.contains('2000-01-01') + assert !remainingModuleRevisions.contains('2001-01-01') + cleanup: + objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet1']) + } + + def 'Delete schema set error scenario: #scenario.'() { + when: 'attempt to delete a schema set where #scenario' + objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName, CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED) + then: 'an #expectedException is thrown' + thrown(expectedException) + where: 'the following data is used' + scenario | dataspaceName | schemaSetName || expectedException + 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException + 'schema set does not exists' | FUNCTIONAL_TEST_DATASPACE_1 | 'unknown' || SchemaSetNotFoundException + } + + /* + H E L P E R M E T H O D S + */ + + def populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfModules) { + numberOfModules.times { + def uniqueName = 'name_' + it + def uniqueRevision = String.valueOf(2000 + it) + '-01-01' + moduleReferences.add(new ModuleReference(uniqueName, uniqueRevision)) + def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision) + newYangResourcesNameToContentMap.put(uniqueRevision, uniqueContent) + } + } + +} -- cgit 1.2.3-korg