2  *  ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2023-2025 Nordix Foundation
 
   4  *  ================================================================================
 
   5  *  Licensed under the Apache License, Version 2.0 (the 'License');
 
   6  *  you may not use this file except in compliance with the License.
 
   7  *  You may obtain a copy of the License at
 
   9  *        http://www.apache.org/licenses/LICENSE-2.0
 
  11  *  Unless required by applicable law or agreed to in writing, software
 
  12  *  distributed under the License is distributed on an 'AS IS' BASIS,
 
  13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  *  See the License for the specific language governing permissions and
 
  15  *  limitations under the License.
 
  17  *  SPDX-License-Identifier: Apache-2.0
 
  18  *  ============LICENSE_END=========================================================
 
  21 package org.onap.cps.integration.functional.cps
 
  23 import org.onap.cps.api.CpsModuleService
 
  24 import org.onap.cps.integration.base.FunctionalSpecBase
 
  25 import org.onap.cps.api.parameters.CascadeDeleteAllowed
 
  26 import org.onap.cps.api.exceptions.AlreadyDefinedException
 
  27 import org.onap.cps.api.exceptions.DataspaceNotFoundException
 
  28 import org.onap.cps.api.exceptions.ModelValidationException
 
  29 import org.onap.cps.api.exceptions.SchemaSetInUseException
 
  30 import org.onap.cps.api.exceptions.SchemaSetNotFoundException
 
  31 import org.onap.cps.api.model.ModuleDefinition
 
  32 import org.onap.cps.api.model.ModuleReference
 
  34 class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
 
  36     CpsModuleService objectUnderTest
 
  38     private static def originalNumberOfModuleReferences = 2 // bookstore has two modules
 
  39     private static def bookStoreModuleReference = new ModuleReference('stores','2024-02-08')
 
  40     private static def bookStoreModuleReferenceWithNamespace = new ModuleReference('stores','2024-02-08', 'org:onap:cps:sample')
 
  41     private static def bookStoreTypesModuleReference = new ModuleReference('bookstore-types','2024-01-30')
 
  42     private static def bookStoreTypesModuleReferenceWithNamespace = new ModuleReference('bookstore-types','2024-01-30', 'org:onap:cps:types:sample')
 
  43     static def NEW_RESOURCE_REVISION = '2023-05-10'
 
  44     static def NEW_RESOURCE_CONTENT = """
 
  47             namespace "org:onap:ccsdk:sample";
 
  49             revision "2023-05-10" {
 
  56     def newYangResourcesNameToContentMap = [:]
 
  57     def moduleReferences = []
 
  58     def noNewModules = [:]
 
  59     def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
 
  60     def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
 
  62     def setup() { objectUnderTest = cpsModuleService }
 
  65         C R E A T E   S C H E M A   S E T   U S E - C A S E S
 
  68     def 'Create new schema set from yang resources with #scenario'() {
 
  69         given: 'a new schema set with #numberOfModules modules'
 
  70             populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules)
 
  71         when: 'the new schema set is created'
 
  72             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap)
 
  73         then: 'the number of module references has increased by #numberOfNewModules'
 
  74             def yangResourceModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1)
 
  75             originalNumberOfModuleReferences + numberOfNewModules == yangResourceModuleReferences.size()
 
  77             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchemaSet' ])
 
  78         where: 'the following parameters are used'
 
  79             scenario                       | numberOfNewModules
 
  80             'two valid new modules'        | 2
 
  81             'empty schema set'             | 0
 
  82             'over max batch size #modules' | 101
 
  85     def 'Create new schema set with recommended filename format but invalid yang'() {
 
  86         given: 'a filename using RFC6020 recommended format (for coverage only)'
 
  87             def fileName = 'test@2023-05-11.yang'
 
  88         when: 'attempt to create a schema set with invalid Yang'
 
  89             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', [(fileName) :'invalid yang'])
 
  90         then: 'a model validation exception'
 
  91             thrown(ModelValidationException)
 
  94     def 'Create new schema set from modules with #scenario'() {
 
  95         given: 'a new schema set with #numberOfNewModules modules'
 
  96             populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules)
 
  97         and: 'add existing module references (optional)'
 
  98             moduleReferences.addAll(existingModuleReferences)
 
  99         when: 'the new schema set is created'
 
 100             def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules"
 
 101             objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
 
 102         and: 'associated with a new anchor'
 
 103             cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor')
 
 104         then: 'the new anchor has the correct number of modules'
 
 105             def yangResourceModuleReferences = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'newAnchor')
 
 106             assert expectedNumberOfModulesForAnchor == yangResourceModuleReferences.size()
 
 108             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ schemaSetName.toString() ])
 
 109         where: 'the following module references are provided'
 
 110             scenario                        | numberOfNewModules | existingModuleReferences                          || expectedNumberOfModulesForAnchor
 
 111             'empty schema set'              | 0                  | [ ]                                               || 0
 
 112             'one existing module'           | 0                  | [bookStoreModuleReference ]                       || 1
 
 113             'two new modules'               | 2                  | [ ]                                               || 2
 
 114             'two new modules, one existing' | 2                  | [bookStoreModuleReference ]                       || 3
 
 115             'over max batch size #modules'  | 101                | [ ]                                               || 101
 
 116             'two valid, one invalid module' | 2                  | [ new ModuleReference('NOT EXIST','IRRELEVANT') ] || 2
 
 119     def 'Duplicate schema content.'() {
 
 120         given: 'a map of yang resources'
 
 121             populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
 
 122         when: 'a new schema set is created'
 
 123             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap)
 
 124         then: 'the dataspace has one new module (reference)'
 
 125             def numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size()
 
 126             assert numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded == originalNumberOfModuleReferences + 1
 
 127         when: 'a second new schema set is created'
 
 128             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema2', newYangResourcesNameToContentMap)
 
 129         then: 'the dataspace has no additional module (reference)'
 
 130             assert numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded  == objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size()
 
 132             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchema1', 'newSchema2'])
 
 135     def 'Attempt to create schema set, error scenario: #scenario.'() {
 
 136         when: 'attempt to store schema set #schemaSetName in dataspace #dataspaceName'
 
 137             populateNewYangResourcesNameToContentMapAndAllModuleReferences(0)
 
 138             objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, newYangResourcesNameToContentMap)
 
 139         then: 'an #expectedException is thrown'
 
 140             thrown(expectedException)
 
 141         where: 'the following data is used'
 
 142             scenario                    | dataspaceName               | schemaSetName        || expectedException
 
 143             'dataspace does not exist'  | 'unknown'                   | 'not-relevant'       || DataspaceNotFoundException
 
 144             'schema set already exists' | FUNCTIONAL_TEST_DATASPACE_1 | BOOKSTORE_SCHEMA_SET || AlreadyDefinedException
 
 147     def 'Attempt to create duplicate schema set from modules.'() {
 
 148         when: 'attempt to store duplicate schema set from modules'
 
 149             objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, newYangResourcesNameToContentMap, [])
 
 150         then: 'an Already Defined Exception is thrown'
 
 151             thrown(AlreadyDefinedException)
 
 156         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
 
 159     def 'Retrieving module definitions by anchor.'() {
 
 160         when: 'the module definitions for an anchor are retrieved'
 
 161             def result = objectUnderTest.getModuleDefinitionsByAnchorName(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1)
 
 162         then: 'the correct module definitions are returned'
 
 163             assert result.size() == 2
 
 164             assert result.contains(new ModuleDefinition('stores','2024-02-08',bookstoreModelFileContent))
 
 165             assert result.contains(new ModuleDefinition('bookstore-types','2024-01-30', bookstoreTypesFileContent))
 
 168     def 'Retrieving module definitions: #scenarios'() {
 
 169         when: 'module definitions for module name are retrieved'
 
 170             def result = objectUnderTest.getModuleDefinitionsByAnchorAndModule(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, moduleName, moduleRevision)
 
 171         then: 'the correct module definitions are returned'
 
 172             if (expectedNumberOfDefinitions > 0) {
 
 173                 assert result.size() == expectedNumberOfDefinitions
 
 174                 def expectedModuleDefinition = new ModuleDefinition('stores', '2024-02-08', bookstoreModelFileContent)
 
 175                 assert result[0] == expectedModuleDefinition
 
 177         where: 'following parameters are used'
 
 178             scenarios                          | moduleName | moduleRevision || expectedNumberOfDefinitions
 
 179             'correct module name and revision' | 'stores'   | '2024-02-08'   || 1
 
 180             'correct module name'              | 'stores'   | null           || 1
 
 181             'incorrect module name'            | 'other'    | null           || 0
 
 182             'incorrect revision'               | 'stores'   | '2025-11-22'   || 0
 
 185     def 'Retrieving yang resource module references by anchor.'() {
 
 186         when: 'the yang resource module references for an anchor are retrieved'
 
 187             def result = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1)
 
 188         then: 'the correct module references are returned'
 
 189             assert result.size() == 2
 
 190             assert result.containsAll(bookStoreModuleReference, bookStoreTypesModuleReference)
 
 193     def 'Identifying new module references with #scenario'() {
 
 194         when: 'identifyNewModuleReferences is called'
 
 195             def result = objectUnderTest.identifyNewModuleReferences(moduleReferences)
 
 196         then: 'the correct module references are returned'
 
 197             assert result.size() == expectedResult.size()
 
 198             assert result.containsAll(expectedResult)
 
 199         where: 'the following data is used'
 
 200             scenario                                | moduleReferences                                                       || expectedResult
 
 201             'just new module references'            | [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')] || [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')]
 
 202             'one new module,one existing reference' | [new ModuleReference('new1', 'r1'), bookStoreModuleReference]          || [new ModuleReference('new1', 'r1')]
 
 203             'no new module references'              | [bookStoreModuleReference]                                             || []
 
 204             'no module references'                  | []                                                                     || []
 
 205             'module references collection is null'  | null                                                                   || []
 
 208     def 'Retrieve schema set.'() {
 
 209         when: 'a specific schema set is retrieved'
 
 210             def result = objectUnderTest.getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET)
 
 211         then: 'the result has the correct name and module(s)'
 
 212             assert result.name == 'bookstoreSchemaSet'
 
 213             assert result.moduleReferences.size() == 2
 
 214             assert result.moduleReferences.containsAll(bookStoreModuleReferenceWithNamespace, bookStoreTypesModuleReferenceWithNamespace)
 
 217     def 'Retrieve all schema sets.'() {
 
 218         given: 'an extra schema set is stored'
 
 219             populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
 
 220             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap)
 
 221         when: 'all schema sets are retrieved'
 
 222             def result = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1)
 
 223         then: 'the result contains all expected schema sets'
 
 224             assert result.name.size() == 2
 
 225             assert result.name.containsAll('bookstoreSchemaSet', 'newSchema1')
 
 227             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchema1'])
 
 231         D E L E T E   S C H E M A   S E T   U S E - C A S E S
 
 234     def 'Delete schema sets with(out) cascade.'() {
 
 235         given: 'a schema set'
 
 236             populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
 
 237             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap)
 
 238         and: 'optionally create anchor for the schema set'
 
 239             if (associateWithAnchor) {
 
 240                 cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor')
 
 242         when: 'attempt to delete the schema set'
 
 244                 objectUnderTest.deleteSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', cascadeDeleteAllowedOption)
 
 246             catch (Exception e) {  // only accept correct exception when schema set cannot be deleted
 
 247                 assert e instanceof SchemaSetInUseException && expectSchemaSetStillPresent
 
 249         then: 'check if the dataspace still contains the new schema set or not'
 
 250             def remainingSchemaSetNames = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).name
 
 251             assert remainingSchemaSetNames.contains('newSchemaSet') == expectSchemaSetStillPresent
 
 253             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet'])
 
 254         where: 'the following options are used'
 
 255             associateWithAnchor | cascadeDeleteAllowedOption                     || expectSchemaSetStillPresent
 
 256             false               | CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED    || false
 
 257             false               | CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED || false
 
 258             true                | CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED    || false
 
 259             true                | CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED || true
 
 262     def 'Delete schema sets with shared resources.'() {
 
 263         given: 'a new schema set'
 
 264             populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
 
 265             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet1', newYangResourcesNameToContentMap)
 
 266         and: 'another schema set which shares one yang resource (module)'
 
 267             populateNewYangResourcesNameToContentMapAndAllModuleReferences(2)
 
 268             objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet2', newYangResourcesNameToContentMap)
 
 269         when: 'all schema sets are retrieved'
 
 270             def moduleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision
 
 271         then: 'both modules (revisions) are present'
 
 272             assert moduleRevisions.containsAll(['2000-01-01', '2000-01-01'])
 
 273         when: 'delete the second schema set that has two resources  one of which is a shared resource'
 
 274             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet2'])
 
 275         then: 'only the second schema set is deleted'
 
 276             def remainingSchemaSetNames = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).name
 
 277             assert remainingSchemaSetNames.contains('newSchemaSet1')
 
 278             assert !remainingSchemaSetNames.contains('newSchemaSet2')
 
 279         and: 'only the shared module (revision) remains'
 
 280             def remainingModuleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision
 
 281             assert remainingModuleRevisions.contains('2000-01-01')
 
 282             assert !remainingModuleRevisions.contains('2001-01-01')
 
 284             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet1'])
 
 287     def 'Delete schema set error scenario: #scenario.'() {
 
 288         when: 'attempt to delete a schema set where #scenario'
 
 289             objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName, CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED)
 
 290         then: 'an #expectedException is thrown'
 
 291             thrown(expectedException)
 
 292         where: 'the following data is used'
 
 293             scenario                     | dataspaceName               | schemaSetName   || expectedException
 
 294             'dataspace does not exist'   | 'unknown'                   | 'not-relevant'  || DataspaceNotFoundException
 
 295             'schema set does not exists' | FUNCTIONAL_TEST_DATASPACE_1 | 'unknown'       || SchemaSetNotFoundException
 
 302     def 'Upgrade schema set (with existing and new modules, no matching module set tag in NCMP)'() {
 
 303         given: 'an anchor and schema set with 2 modules (to be upgraded)'
 
 304             populateNewYangResourcesNameToContentMapAndAllModuleReferences('original', 2)
 
 305             objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
 
 306             cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
 
 307             def yangResourceModuleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
 
 308             assert yangResourceModuleReferencesBeforeUpgrade.size() == 2
 
 309             assert yangResourceModuleReferencesBeforeUpgrade.containsAll([new ModuleReference('original_0','2000-01-01'),new ModuleReference('original_1','2001-01-01')])
 
 310         and: 'two new 2 modules (from node)'
 
 311             populateNewYangResourcesNameToContentMapAndAllModuleReferences('new', 2)
 
 312             def newModuleReferences = [new ModuleReference('new_0','2000-01-01'),new ModuleReference('new_1','2001-01-01')]
 
 313         and: 'a list of all module references (normally retrieved from node)'
 
 314             def allModuleReferences = []
 
 315             allModuleReferences.add(bookStoreModuleReference)
 
 316             allModuleReferences.addAll(newModuleReferences)
 
 317         when: 'the schema set is upgraded'
 
 318             objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, allModuleReferences)
 
 319         then: 'the new anchor has the correct new and existing modules'
 
 320             def yangResourceModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
 
 321             assert yangResourceModuleReferencesAfterUpgrade.size() == 3
 
 322             assert yangResourceModuleReferencesAfterUpgrade.contains(bookStoreModuleReference)
 
 323             assert yangResourceModuleReferencesAfterUpgrade.containsAll(newModuleReferences);
 
 325             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
 
 328     def 'Upgrade existing schema set from another anchor (used in NCMP for matching module set tag)'() {
 
 329         given: 'an anchor and schema set with 1 module (target)'
 
 330             populateNewYangResourcesNameToContentMapAndAllModuleReferences('target', 1)
 
 331             objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
 
 332             cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
 
 333             def moduleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
 
 334             assert moduleReferencesBeforeUpgrade.size() == 1
 
 335         and: 'another anchor and schema set with 2 other modules (source for upgrade)'
 
 336             populateNewYangResourcesNameToContentMapAndAllModuleReferences('source', 2)
 
 337             objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', newYangResourcesNameToContentMap, [])
 
 338             cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
 
 339             assert objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor').size() == 2
 
 340         when: 'the target schema is upgraded using the module references from the source anchor'
 
 341             def moduleReferencesFromSourceAnchor = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor')
 
 342             objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', noNewModules, moduleReferencesFromSourceAnchor)
 
 343         then: 'the target schema now refers to the source modules (with namespace) modules'
 
 344             def schemaSetModuleReferencesAfterUpgrade = getObjectUnderTest().getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema').moduleReferences
 
 345             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')]);
 
 346         and: 'the associated target anchor has the same module references (without namespace but that is a legacy issue)'
 
 347             def anchorModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
 
 348             assert anchorModuleReferencesAfterUpgrade.containsAll([new ModuleReference('source_0','2000-01-01'),new ModuleReference('source_1','2001-01-01')]);
 
 350             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['sourceSchema', 'targetSchema'])
 
 354         H E L P E R   M E T H O D S
 
 357     def populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfModules) {
 
 358         populateNewYangResourcesNameToContentMapAndAllModuleReferences('name', numberOfModules)
 
 361     def populateNewYangResourcesNameToContentMapAndAllModuleReferences(namePrefix, numberOfModules) {
 
 362         numberOfModules.times {
 
 363             def uniqueName = namePrefix + '_' + it
 
 364             def uniqueRevision = String.valueOf(2000 + it) + '-01-01'
 
 365             moduleReferences.add(new ModuleReference(uniqueName, uniqueRevision))
 
 366             def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision).replace('module test_module', 'module '+uniqueName)
 
 367             newYangResourcesNameToContentMap.put(uniqueRevision, uniqueContent)