/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
package org.onap.cps.integration.functional
-import org.onap.cps.api.impl.CpsModuleServiceImpl
+import org.onap.cps.api.CpsModuleService
import org.onap.cps.integration.base.FunctionalSpecBase
import org.onap.cps.spi.CascadeDeleteAllowed
import org.onap.cps.spi.exceptions.AlreadyDefinedException
class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
- CpsModuleServiceImpl objectUnderTest
+ CpsModuleService objectUnderTest
- private static def originalNumberOfModuleReferences = 1
- private static def existingModuleReference = new ModuleReference('stores','2020-09-15')
+ private static def originalNumberOfModuleReferences = 2 // bookstore has two modules
+ private static def bookStoreModuleReference = new ModuleReference('stores','2024-01-30')
+ private static def bookStoreModuleReferenceWithNamespace = new ModuleReference('stores','2024-01-30', 'org:onap:cps:sample')
+ private static def bookStoreTypesModuleReference = new ModuleReference('bookstore-types','2024-01-30')
+ private static def bookStoreTypesModuleReferenceWithNamespace = new ModuleReference('bookstore-types','2024-01-30', 'org:onap:cps:types:sample')
static def NEW_RESOURCE_REVISION = '2023-05-10'
static def NEW_RESOURCE_CONTENT = 'module test_module {\n' +
' yang-version 1.1;\n' +
def newYangResourcesNameToContentMap = [:]
def moduleReferences = []
+ def noNewModules = [:]
+ def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
+ def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
def setup() {
objectUnderTest = cpsModuleService
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'
+ then: 'the number of module references has increased by #numberOfNewModules'
def yangResourceModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1)
originalNumberOfModuleReferences + numberOfNewModules == yangResourceModuleReferences.size()
cleanup:
moduleReferences.addAll(existingModuleReferences)
when: 'the new schema set is created'
def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules"
- objectUnderTest.createOrUpgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
and: 'associated with a new anchor'
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor')
+ cpsAnchorService.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()
where: 'the following module references are provided'
scenario | numberOfNewModules | existingModuleReferences || expectedNumberOfModulesForAnchor
'empty schema set' | 0 | [ ] || 0
- 'one existing module' | 0 | [ existingModuleReference ] || 1
+ 'one existing module' | 0 | [bookStoreModuleReference ] || 1
'two new modules' | 2 | [ ] || 2
- 'two new modules, one existing' | 2 | [ existingModuleReference ] || 3
+ 'two new modules, one existing' | 2 | [bookStoreModuleReference ] || 3
'over max batch size #modules' | 101 | [ ] || 101
'two valid, one invalid module' | 2 | [ new ModuleReference('NOT EXIST','IRRELEVANT') ] || 2
}
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','')]
+ assert result.size() == 2
+ assert result.contains(new ModuleDefinition('stores','2024-01-30',bookstoreModelFileContent))
+ assert result.contains(new ModuleDefinition('bookstore-types','2024-01-30', bookstoreTypesFileContent))
+ }
+
+ def 'Retrieving module definitions: #scenarios'() {
+ when: 'module definitions for module name are retrieved'
+ def result = objectUnderTest.getModuleDefinitionsByAnchorAndModule(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, moduleName, moduleRevision)
+ then: 'the correct module definitions are returned'
+ if (expectedNumberOfDefinitions > 0) {
+ assert result.size() == expectedNumberOfDefinitions
+ def expectedModuleDefinition = new ModuleDefinition('stores', '2024-01-30', bookstoreModelFileContent)
+ assert result[0] == expectedModuleDefinition
+ }
+ where: 'following parameters are used'
+ scenarios | moduleName | moduleRevision || expectedNumberOfDefinitions
+ 'correct module name and revision' | 'stores' | '2024-01-30' || 1
+ 'correct module name' | 'stores' | null || 1
+ 'incorrect module name' | 'other' | null || 0
+ 'incorrect revision' | 'stores' | '2025-11-22' || 0
}
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 ]
+ assert result.size() == 2
+ assert result.containsAll(bookStoreModuleReference, bookStoreTypesModuleReference)
}
def 'Identifying new module references with #scenario'() {
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] || []
+ 'one new module,one existing reference' | [new ModuleReference('new1', 'r1'), bookStoreModuleReference] || [new ModuleReference('new1', 'r1')]
+ 'no new module references' | [bookStoreModuleReference] || []
'no module references' | [] || []
'module references collection is null' | null || []
}
def 'Retrieve schema set.'() {
- when: 'a specific schema set is retreived'
+ when: 'a specific schema set is retrieved'
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') ]
+ assert result.moduleReferences.size() == 2
+ assert result.moduleReferences.containsAll(bookStoreModuleReferenceWithNamespace, bookStoreTypesModuleReferenceWithNamespace)
}
def 'Retrieve all schema sets.'() {
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')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor')
}
when: 'attempt to delete the schema set'
try {
'schema set does not exists' | FUNCTIONAL_TEST_DATASPACE_1 | 'unknown' || SchemaSetNotFoundException
}
+ /*
+ U P G R A D E
+ */
+
+ def 'Upgrade schema set (with existing and new modules, no matching module set tag in NCMP)'() {
+ given: 'an anchor and schema set with 2 modules (to be upgraded)'
+ populateNewYangResourcesNameToContentMapAndAllModuleReferences('original', 2)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+ def yangResourceModuleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+ assert yangResourceModuleReferencesBeforeUpgrade.size() == 2
+ assert yangResourceModuleReferencesBeforeUpgrade.containsAll([new ModuleReference('original_0','2000-01-01'),new ModuleReference('original_1','2001-01-01')])
+ and: 'two new 2 modules (from node)'
+ populateNewYangResourcesNameToContentMapAndAllModuleReferences('new', 2)
+ def newModuleReferences = [new ModuleReference('new_0','2000-01-01'),new ModuleReference('new_1','2001-01-01')]
+ and: 'a list of all module references (normally retrieved from node)'
+ def allModuleReferences = []
+ allModuleReferences.add(bookStoreModuleReference)
+ allModuleReferences.addAll(newModuleReferences)
+ when: 'the schema set is upgraded'
+ objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, allModuleReferences)
+ then: 'the new anchor has the correct new and existing modules'
+ def yangResourceModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+ assert yangResourceModuleReferencesAfterUpgrade.size() == 3
+ assert yangResourceModuleReferencesAfterUpgrade.contains(bookStoreModuleReference)
+ assert yangResourceModuleReferencesAfterUpgrade.containsAll(newModuleReferences);
+ cleanup:
+ objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
+ }
+
+ def 'Upgrade existing schema set from another anchor (used in NCMP for matching module set tag)'() {
+ given: 'an anchor and schema set with 1 module (target)'
+ populateNewYangResourcesNameToContentMapAndAllModuleReferences('target', 1)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+ def moduleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+ assert moduleReferencesBeforeUpgrade.size() == 1
+ and: 'another anchor and schema set with 2 other modules (source for upgrade)'
+ populateNewYangResourcesNameToContentMapAndAllModuleReferences('source', 2)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', newYangResourcesNameToContentMap, [])
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
+ assert objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor').size() == 2
+ when: 'the target schema is upgraded using the module references from the source anchor'
+ def moduleReferencesFromSourceAnchor = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor')
+ objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', noNewModules, moduleReferencesFromSourceAnchor)
+ then: 'the target schema now refers to the source modules (with namespace) modules'
+ def schemaSetModuleReferencesAfterUpgrade = getObjectUnderTest().getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema').moduleReferences
+ assert schemaSetModuleReferencesAfterUpgrade.containsAll([new ModuleReference('source_0','2000-01-01','org:onap:ccsdk:sample'),new ModuleReference('source_1','2001-01-01','org:onap:ccsdk:sample')]);
+ and: 'the associated target anchor has the same module references (without namespace but that is a legacy issue)'
+ def anchorModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+ assert anchorModuleReferencesAfterUpgrade.containsAll([new ModuleReference('source_0','2000-01-01'),new ModuleReference('source_1','2001-01-01')]);
+ cleanup:
+ objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['sourceSchema', 'targetSchema'])
+ }
+
/*
H E L P E R M E T H O D S
*/
def populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfModules) {
+ populateNewYangResourcesNameToContentMapAndAllModuleReferences('name', numberOfModules)
+ }
+
+ def populateNewYangResourcesNameToContentMapAndAllModuleReferences(namePrefix, numberOfModules) {
numberOfModules.times {
- def uniqueName = 'name_' + it
+ def uniqueName = namePrefix + '_' + 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)
+ def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision).replace('module test_module', 'module '+uniqueName)
newYangResourcesNameToContentMap.put(uniqueRevision, uniqueContent)
}
}