aboutsummaryrefslogtreecommitdiffstats
path: root/integration-test/src
diff options
context:
space:
mode:
Diffstat (limited to 'integration-test/src')
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy32
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy16
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy153
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/QueryServiceIntegrationSpec.groovy19
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/AlternateIdSpec.groovy24
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy32
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy17
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobStatusServiceSpec.groovy2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/RestApiSpec.groovy15
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/WriteSubJobSpec.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy6
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy1
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/AlternateIdPerfTest.groovy47
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy8
-rw-r--r--integration-test/src/test/java/org/onap/cps/integration/KafkaTestContainer.java11
-rw-r--r--integration-test/src/test/resources/application.yml5
-rw-r--r--integration-test/src/test/resources/hibernate.cfg.xml16
18 files changed, 247 insertions, 173 deletions
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
index 75cb3cd7a2..9b79af95ff 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
@@ -22,6 +22,8 @@
package org.onap.cps.integration.base
import com.hazelcast.map.IMap
+import java.time.OffsetDateTime
+import java.util.concurrent.BlockingQueue
import okhttp3.mockwebserver.MockWebServer
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDataService
@@ -44,7 +46,9 @@ import org.onap.cps.ncmp.impl.inventory.sync.ModuleSyncService
import org.onap.cps.ncmp.impl.inventory.sync.ModuleSyncWatchdog
import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher
import org.onap.cps.ri.repository.DataspaceRepository
+import org.onap.cps.ri.repository.SchemaSetRepository
import org.onap.cps.ri.utils.SessionManager
+import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -59,10 +63,6 @@ import org.springframework.test.web.servlet.MockMvc
import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
import spock.lang.Specification
-import spock.util.concurrent.PollingConditions
-
-import java.time.OffsetDateTime
-import java.util.concurrent.BlockingQueue
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
@Testcontainers
@@ -102,6 +102,15 @@ abstract class CpsIntegrationSpecBase extends Specification {
SessionManager sessionManager
@Autowired
+ CpsModulePersistenceService cpsModulePersistenceService
+
+ @Autowired
+ DataspaceRepository dataspaceRepository
+
+ @Autowired
+ SchemaSetRepository schemaSetRepository
+
+ @Autowired
ParameterizedCmHandleQueryService networkCmProxyCmHandleQueryService
@Autowired
@@ -153,7 +162,6 @@ abstract class CpsIntegrationSpecBase extends Specification {
static NO_ALTERNATE_ID = ''
static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
- static MODULE_SYNC_WAIT_TIME_IN_SECONDS = 2
static initialized = false
def now = OffsetDateTime.now()
@@ -204,18 +212,18 @@ abstract class CpsIntegrationSpecBase extends Specification {
return nodeCount
}
- def getBookstoreYangResourcesNameToContentMap() {
+ def getBookstoreyangResourceContentPerName() {
def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
}
def createStandardBookStoreSchemaSet(targetDataspace) {
- cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
+ cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreyangResourceContentPerName())
}
def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
- cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
+ cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreyangResourceContentPerName())
}
def dataspaceExists(dataspaceName) {
@@ -255,13 +263,11 @@ abstract class CpsIntegrationSpecBase extends Specification {
def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag, alternateId) {
registerCmHandleWithoutWaitForReady(dmiPlugin, cmHandleId, moduleSetTag, alternateId)
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- CmHandleState.READY == networkCmProxyInventoryFacade.getCmHandleCompositeState(cmHandleId).cmHandleState
- })
+ CmHandleState.READY == networkCmProxyInventoryFacade.getCmHandleCompositeState(cmHandleId).cmHandleState
}
def registerCmHandleWithoutWaitForReady(dmiPlugin, cmHandleId, moduleSetTag, alternateId) {
- def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag, alternateId: alternateId)
+ def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag, alternateId: alternateId, dataProducerIdentifier: 'some data producer id')
networkCmProxyInventoryFacade.updateDmiRegistration(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
}
@@ -275,7 +281,7 @@ abstract class CpsIntegrationSpecBase extends Specification {
def modulePrefix = moduleNameStrategy.OVERLAPPING.equals(moduleNameStrategy) ? 'same' : moduleSetTag
def moduleReferences = (1..200).collect { "${modulePrefix}Module${it}" }
(1..numberOfCmHandles).each {
- def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: "ch-${id}", moduleSetTag: moduleSetTag, alternateId: NO_ALTERNATE_ID)
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: "ch-${id}", moduleSetTag: moduleSetTag, alternateId: "alt=${id}")
cmHandles.add(ncmpServiceCmHandle)
dmiDispatcher1.moduleNamesPerCmHandleId[ncmpServiceCmHandle.cmHandleId] = moduleReferences
dmiDispatcher2.moduleNamesPerCmHandleId[ncmpServiceCmHandle.cmHandleId] = moduleReferences
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
index 35a7b6a7c2..11c0ff2743 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import java.util.regex.Matcher
+import java.util.stream.Collectors
import static org.onap.cps.integration.base.CpsIntegrationSpecBase.readResourceDataFile
@@ -81,7 +82,7 @@ class DmiDispatcher extends Dispatcher {
// get module resources for a CM-handle
case ~'^/dmi/v1/ch/(.*)/moduleResources$':
def cmHandleId = Matcher.lastMatcher[0][1]
- return getModuleResourcesResponse(cmHandleId)
+ return getModuleResourcesResponse(request, cmHandleId)
// pass-through data operation for a CM-handle
case ~'^/dmi/v1/ch/(.*)/data/ds/(.*)$':
@@ -113,7 +114,7 @@ class DmiDispatcher extends Dispatcher {
def destination = Matcher.lastMatcher[0][1]
def subJobWriteRequest = jsonSlurper.parseText(request.getBody().readUtf8())
this.receivedSubJobs.put(destination, subJobWriteRequest)
- def response = '{"subJobId":"some sub job id", "dmiServiceName":"some dmi service name", "dataProducerId":"some data producer id"}'
+ def response = '{"subJobId":"some sub job id"}'
return mockResponseWithBody(HttpStatus.OK, response)
}
@@ -124,8 +125,13 @@ class DmiDispatcher extends Dispatcher {
return mockResponseWithBody(HttpStatus.OK, moduleReferences)
}
- def getModuleResourcesResponse(cmHandleId) {
- def moduleResources = '[' + getModuleNamesForCmHandle(cmHandleId).collect {
+ def getModuleResourcesResponse(request, cmHandleId) {
+ def moduleResourcesRequest = jsonSlurper.parseText(request.getBody().readUtf8())
+ def requestedModuleNames = moduleResourcesRequest.get('data').get('modules').collect{it.get('name')}
+ def candidateModuleNames = getModuleNamesForCmHandle(cmHandleId)
+ def moduleNames = candidateModuleNames.stream().filter(candidate -> requestedModuleNames.contains(candidate)).toList()
+
+ def moduleResources = '[' + moduleNames.collect {
MODULE_RESOURCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
}.join(',') + ']'
return mockResponseWithBody(HttpStatus.OK, moduleResources)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
index c787b4209e..9a48dd72f3 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
@@ -21,8 +21,6 @@
package org.onap.cps.integration.functional.cps
import org.onap.cps.api.CpsModuleService
-import org.onap.cps.integration.base.FunctionalSpecBase
-import org.onap.cps.api.parameters.CascadeDeleteAllowed
import org.onap.cps.api.exceptions.AlreadyDefinedException
import org.onap.cps.api.exceptions.DataspaceNotFoundException
import org.onap.cps.api.exceptions.ModelValidationException
@@ -30,6 +28,8 @@ import org.onap.cps.api.exceptions.SchemaSetInUseException
import org.onap.cps.api.exceptions.SchemaSetNotFoundException
import org.onap.cps.api.model.ModuleDefinition
import org.onap.cps.api.model.ModuleReference
+import org.onap.cps.api.parameters.CascadeDeleteAllowed
+import org.onap.cps.integration.base.FunctionalSpecBase
class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
@@ -53,8 +53,8 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
}
"""
- def newYangResourcesNameToContentMap = [:]
- def moduleReferences = []
+ def yangResourceContentPerName = [:]
+ def allModuleReferences = []
def noNewModules = [:]
def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
@@ -67,9 +67,9 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def 'Create new schema set from yang resources with #scenario'() {
given: 'a new schema set with #numberOfModules modules'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules)
+ populateYangResourceContentPerNameAndAllModuleReferences(numberOfNewModules)
when: 'the new schema set is created'
- objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', yangResourceContentPerName)
then: 'the number of module references has increased by #numberOfNewModules'
def yangResourceModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1)
originalNumberOfModuleReferences + numberOfNewModules == yangResourceModuleReferences.size()
@@ -93,49 +93,53 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def 'Create new schema set from modules with #scenario'() {
given: 'a new schema set with #numberOfNewModules modules'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules)
+ populateYangResourceContentPerNameAndAllModuleReferences(numberOfNewModules)
and: 'add existing module references (optional)'
- moduleReferences.addAll(existingModuleReferences)
+ allModuleReferences.addAll(existingModuleReferences)
when: 'the new schema set is created'
def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules"
- objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, yangResourceContentPerName, allModuleReferences)
and: 'associated with a new anchor'
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()
+ and: 'the schema set has the correct number of modules too'
+ def dataspaceEntity = dataspaceRepository.getByName(FUNCTIONAL_TEST_DATASPACE_1)
+ def schemaSetEntity = schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName)
+ assert expectedNumberOfModulesForAnchor == schemaSetEntity.yangResources.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 | [bookStoreModuleReference ] || 1
+ 'one existing module' | 0 | [ bookStoreModuleReference ] || 1
'two new modules' | 2 | [ ] || 2
- 'two new modules, one existing' | 2 | [bookStoreModuleReference ] || 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
}
def 'Duplicate schema content.'() {
given: 'a map of yang resources'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
+ populateYangResourceContentPerNameAndAllModuleReferences(1)
when: 'a new schema set is created'
- objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', yangResourceContentPerName)
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)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema2', yangResourceContentPerName)
then: 'the dataspace has no additional module (reference)'
assert numberOfModuleReferencesAfterFirstSchemaSetHasBeenAdded == objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size()
- cleanup:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchema1', 'newSchema2'])
}
def 'Attempt to create schema set, error scenario: #scenario.'() {
when: 'attempt to store schema set #schemaSetName in dataspace #dataspaceName'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(0)
- objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, newYangResourcesNameToContentMap)
+ populateYangResourceContentPerNameAndAllModuleReferences(0)
+ objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, yangResourceContentPerName)
then: 'an #expectedException is thrown'
thrown(expectedException)
where: 'the following data is used'
@@ -146,7 +150,7 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def 'Attempt to create duplicate schema set from modules.'() {
when: 'attempt to store duplicate schema set from modules'
- objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, newYangResourcesNameToContentMap, [])
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, yangResourceContentPerName, [])
then: 'an Already Defined Exception is thrown'
thrown(AlreadyDefinedException)
}
@@ -192,12 +196,12 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def 'Identifying new module references with #scenario'() {
when: 'identifyNewModuleReferences is called'
- def result = objectUnderTest.identifyNewModuleReferences(moduleReferences)
+ def result = objectUnderTest.identifyNewModuleReferences(allModuleReferences)
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
+ scenario | allModuleReferences || 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'), bookStoreModuleReference] || [new ModuleReference('new1', 'r1')]
'no new module references' | [bookStoreModuleReference] || []
@@ -212,29 +216,71 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
assert result.name == 'bookstoreSchemaSet'
assert result.moduleReferences.size() == 2
assert result.moduleReferences.containsAll(bookStoreModuleReferenceWithNamespace, bookStoreTypesModuleReferenceWithNamespace)
+ and: 'the yang resource is stored with the normalized filename'
+ def fileName = cpsModulePersistenceService.getYangSchemaResources(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET).keySet()[0]
+ assert fileName == 'bookstore-types@2024-01-30.yang'
}
def 'Retrieve all schema sets.'() {
given: 'an extra schema set is stored'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
- objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', newYangResourcesNameToContentMap)
+ populateYangResourceContentPerNameAndAllModuleReferences(1)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema1', yangResourceContentPerName)
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.size() == 2
assert result.name.containsAll('bookstoreSchemaSet', 'newSchema1')
- cleanup:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchema1'])
}
+ def 'Create schema set with duplicate module filename [CPS-138].'() {
+ given: 'store the original number of sets and modules'
+ def numberOfSchemaSets = objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).size()
+ def numberOfModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size()
+ and: 'create a new schema set using a module with filename identical to a previously stored module (e.g. bookstore)'
+ populateYangResourceContentPerNameAndAllModuleReferences('otherModule', 1)
+ def otherModuleContent = yangResourceContentPerName.values()[0]
+ def mapWithDuplicateName = ['bookstore' : otherModuleContent]
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema', mapWithDuplicateName)
+ when: 'the yang resource details are retrieved'
+ def yangSchemaResources = cpsModulePersistenceService.getYangSchemaResources(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema')
+ then: 'the file name of the resource has been normalized'
+ def fileName = yangSchemaResources.keySet()[0]
+ assert fileName == 'otherModule_0@2000-01-01.yang'
+ and: 'the yang resource has the correct content'
+ assert yangSchemaResources.get(fileName) == otherModuleContent
+ and: 'the number of schema sets and modules has increased as expected'
+ assert objectUnderTest.getSchemaSets(FUNCTIONAL_TEST_DATASPACE_1).size() == numberOfSchemaSets + 1
+ assert objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).size() == numberOfModuleReferences + 1
+ cleanup: 'the data created in this test'
+ objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchema'])
+ }
+
+ def 'Create schema set with RFC-6020 filename pattern but incorrect details [CPS-138].'() {
+ given: 'create a new schema set using a module with filename identical to a previously stored module (e.g. bookstore)'
+ populateYangResourceContentPerNameAndAllModuleReferences('otherModule', 1)
+ def otherModuleContent = yangResourceContentPerName.values()[0]
+ def mapIncorrectName = ['wrongModuleAndRevision@1999-08-08.yang': otherModuleContent]
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema', mapIncorrectName)
+ when: 'the yang resource details are retrieved'
+ def yangSchemaResources = cpsModulePersistenceService.getYangSchemaResources(FUNCTIONAL_TEST_DATASPACE_1, 'newSchema')
+ then: 'the file name of the resource has been normalized'
+ def fileName = yangSchemaResources.keySet()[0]
+ assert fileName == 'otherModule_0@2000-01-01.yang'
+ cleanup: 'the data created in this test'
+ objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchema'])
+ }
+
+
/*
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)
+ populateYangResourceContentPerNameAndAllModuleReferences(1)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', yangResourceContentPerName)
and: 'optionally create anchor for the schema set'
if (associateWithAnchor) {
cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor')
@@ -249,7 +295,7 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
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:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet'])
where: 'the following options are used'
associateWithAnchor | cascadeDeleteAllowedOption || expectSchemaSetStillPresent
@@ -261,11 +307,11 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def 'Delete schema sets with shared resources.'() {
given: 'a new schema set'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(1)
- objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet1', newYangResourcesNameToContentMap)
+ populateYangResourceContentPerNameAndAllModuleReferences(1)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet1', yangResourceContentPerName)
and: 'another schema set which shares one yang resource (module)'
- populateNewYangResourcesNameToContentMapAndAllModuleReferences(2)
- objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet2', newYangResourcesNameToContentMap)
+ populateYangResourceContentPerNameAndAllModuleReferences(2)
+ objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet2', yangResourceContentPerName)
when: 'all schema sets are retrieved'
def moduleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision
then: 'both modules (revisions) are present'
@@ -280,7 +326,7 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def remainingModuleRevisions = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1).revision
assert remainingModuleRevisions.contains('2000-01-01')
assert !remainingModuleRevisions.contains('2001-01-01')
- cleanup:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['newSchemaSet1'])
}
@@ -299,44 +345,45 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
U P G R A D E
*/
- def 'Upgrade schema set (with existing and new modules, no matching module set tag in NCMP)'() {
+ 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, [])
+ populateYangResourceContentPerNameAndAllModuleReferences('original', 2)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', yangResourceContentPerName, allModuleReferences)
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)
+ populateYangResourceContentPerNameAndAllModuleReferences('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)
+ def allOtherModuleReferences = []
+ allOtherModuleReferences.add(bookStoreModuleReference)
+ allOtherModuleReferences.addAll(newModuleReferences)
when: 'the schema set is upgraded'
- objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, allModuleReferences)
+ objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', yangResourceContentPerName, allOtherModuleReferences)
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:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
}
- def 'Upgrade existing schema set from another anchor (used in NCMP for matching module set tag)'() {
+ 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, [])
+ populateYangResourceContentPerNameAndAllModuleReferences('target', 1)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', yangResourceContentPerName, allModuleReferences)
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, [])
+ populateYangResourceContentPerNameAndAllModuleReferences('source', 2)
+ objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', yangResourceContentPerName, allModuleReferences)
cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
- assert objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor').size() == 2
+ def yangResourcesModuleReferences = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor')
+ assert yangResourcesModuleReferences.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)
@@ -346,7 +393,7 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
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:
+ cleanup: 'the data created in this test'
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['sourceSchema', 'targetSchema'])
}
@@ -354,17 +401,19 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
H E L P E R M E T H O D S
*/
- def populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfModules) {
- populateNewYangResourcesNameToContentMapAndAllModuleReferences('name', numberOfModules)
+ def populateYangResourceContentPerNameAndAllModuleReferences(numberOfModules) {
+ populateYangResourceContentPerNameAndAllModuleReferences('name', numberOfModules)
}
- def populateNewYangResourcesNameToContentMapAndAllModuleReferences(namePrefix, numberOfModules) {
+ def populateYangResourceContentPerNameAndAllModuleReferences(namePrefix, numberOfModules) {
+ yangResourceContentPerName.clear()
+ allModuleReferences.clear()
numberOfModules.times {
def uniqueName = namePrefix + '_' + it
def uniqueRevision = String.valueOf(2000 + it) + '-01-01'
- moduleReferences.add(new ModuleReference(uniqueName, uniqueRevision))
+ allModuleReferences.add(new ModuleReference(uniqueName, uniqueRevision))
def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision).replace('module test_module', 'module '+uniqueName)
- newYangResourcesNameToContentMap.put(uniqueRevision, uniqueContent)
+ yangResourceContentPerName.put(uniqueName, uniqueContent)
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/QueryServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/QueryServiceIntegrationSpec.groovy
index e4d75aa378..42fb964d52 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/QueryServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/QueryServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation
+ * Copyright (C) 2023-2025 Nordix Foundation
* Modifications Copyright (C) 2023-2025 TechMahindra Ltd
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
@@ -27,7 +27,6 @@ import org.onap.cps.integration.base.FunctionalSpecBase
import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.parameters.PaginationOption
import org.onap.cps.api.exceptions.CpsPathException
-import spock.lang.Ignore
import static org.onap.cps.api.parameters.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
import static org.onap.cps.api.parameters.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
@@ -57,7 +56,6 @@ class QueryServiceIntegrationSpec extends FunctionalSpecBase {
'the AND is used where result does not exist' | '//books[@lang="English" and @price=1000]' || 0 | []
}
- @Ignore // TODO will be implemented in CPS-2416
def 'Query data leaf using CPS path for #scenario.'() {
when: 'query data leaf for bookstore container'
def result = objectUnderTest.queryDataLeaf(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, Object.class)
@@ -70,7 +68,6 @@ class QueryServiceIntegrationSpec extends FunctionalSpecBase {
'non-existing path' | '/non-existing/@title' || 0
}
- @Ignore
def 'Query data leaf with type #leafType using CPS path.'() {
given: 'a cps path query for two books, returning only #leafName'
def cpsPath = '//books[@title="Matilda" or @title="Good Omens"]/@' + leafName
@@ -85,7 +82,6 @@ class QueryServiceIntegrationSpec extends FunctionalSpecBase {
'editions' | List.class || [[1988, 2000], [2006]]
}
- @Ignore
def 'Query data leaf using CPS path with ancestor axis.'() {
given: 'a cps path query that will return the names of the categories of two books'
def cpsPath = '//books[@title="Matilda" or @title="Good Omens"]/ancestor::categories/@name'
@@ -461,4 +457,17 @@ class QueryServiceIntegrationSpec extends FunctionalSpecBase {
and: 'the queried nodes have expected bookstore names'
assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1, BOOKSTORE_ANCHOR_2].toSet()
}
+
+ def 'Query with a limit of #limit.' () {
+ when:
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories', OMIT_DESCENDANTS, limit)
+ then: 'the expected number of nodes is returned'
+ assert countDataNodesInTree(result) == expectedNumberOfResults
+ where: 'the following parameters are used'
+ limit || expectedNumberOfResults
+ 1 || 1
+ 2 || 2
+ 0 || 5
+ -1 || 5
+ }
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/AlternateIdSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/AlternateIdSpec.groovy
index 222b3c0f6f..b1b777c79f 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/AlternateIdSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/AlternateIdSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -30,16 +30,13 @@ class AlternateIdSpec extends CpsIntegrationSpecBase {
def setup() {
dmiDispatcher1.moduleNamesPerCmHandleId['ch-1'] = ['M1', 'M2']
- registerCmHandle(DMI1_URL, 'ch-1', NO_MODULE_SET_TAG, 'alternateId')
}
- def cleanup() {
- deregisterCmHandle(DMI1_URL, 'ch-1')
- }
-
- def 'AlternateId in pass-through data operations should return OK status.'() {
- given: 'the URL for the pass-through data request'
- def url = '/ncmp/v1/ch/alternateId/data/ds/ncmp-datastore:passthrough-running'
+ def 'Pass-through data operations using #scenario as reference.'() {
+ given: 'a cm handle with an alternate id'
+ registerCmHandle(DMI1_URL, 'ch-1', NO_MODULE_SET_TAG, alternateId)
+ and: 'the URL for the pass-through data request'
+ def url = "/ncmp/v1/ch/${cmHandleReference}/data/ds/ncmp-datastore:passthrough-running"
when: 'a pass-through data request is sent to NCMP'
def response = mvc.perform(get(url)
.queryParam('resourceIdentifier', 'my-resource-id')
@@ -47,8 +44,13 @@ class AlternateIdSpec extends CpsIntegrationSpecBase {
.andReturn().response
then: 'response status is Ok'
assert response.status == HttpStatus.OK.value()
+ cleanup: 'remove the test cm handle'
+ deregisterCmHandle(DMI1_URL, 'ch-1')
+ where: 'the following ids are used'
+ scenario | alternateId | cmHandleReference
+ 'standard id' | 'dont care' | 'ch-1'
+ 'alt-id with =' | 'alt=1' | 'alt=1'
+ 'alt-id without =' | 'alt-1' | 'alt-1'
}
-
-
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
index c4946b48b9..41798cb1f1 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
@@ -20,6 +20,7 @@
package org.onap.cps.integration.functional.ncmp
+import java.time.Duration
import org.apache.kafka.clients.consumer.KafkaConsumer
import org.apache.kafka.common.serialization.StringDeserializer
import org.onap.cps.integration.KafkaTestContainer
@@ -32,9 +33,6 @@ import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
import org.onap.cps.ncmp.events.lcm.v1.LcmEvent
import org.onap.cps.ncmp.api.inventory.models.CmHandleState
import org.onap.cps.ncmp.api.inventory.models.LockReasonCategory
-import spock.util.concurrent.PollingConditions
-
-import java.time.Duration
class CmHandleCreateSpec extends CpsIntegrationSpecBase {
@@ -73,9 +71,7 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
then: 'CM-handle goes to READY state after module sync'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(uniqueId).cmHandleState
- })
+ assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(uniqueId).cmHandleState
and: 'the CM-handle has expected modules'
assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(uniqueId).moduleName.sort()
@@ -113,11 +109,9 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
then: 'CM-handle goes to LOCKED state with reason MODULE_SYNC_FAILED'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState('ch-1')
- assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
- assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_SYNC_FAILED
- })
+ def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState('ch-1')
+ assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
+ assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_SYNC_FAILED
and: 'CM-handle has no modules'
assert objectUnderTest.getYangResourcesModuleReferences('ch-1').empty
@@ -141,9 +135,7 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
then: 'the CM-handle goes to READY state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState('ch-3').cmHandleState
- })
+ assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState('ch-3').cmHandleState
and: 'the CM-handle has expected moduleSetTag'
assert objectUnderTest.getNcmpServiceCmHandle('ch-3').moduleSetTag == 'B'
@@ -200,9 +192,7 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
then: 'CM-handles go to LOCKED state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- assert objectUnderTest.getCmHandleCompositeState('ch-1').cmHandleState == CmHandleState.LOCKED
- })
+ assert objectUnderTest.getCmHandleCompositeState('ch-1').cmHandleState == CmHandleState.LOCKED
when: 'DMI is available for retry'
dmiDispatcher1.moduleNamesPerCmHandleId = ['ch-1': ['M1', 'M2'], 'ch-2': ['M1', 'M2']]
@@ -212,11 +202,9 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
then: 'Both CM-handles go to READY state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- ['ch-1', 'ch-2'].each { cmHandleId ->
- assert objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState == CmHandleState.READY
- }
- })
+ ['ch-1', 'ch-2'].each { cmHandleId ->
+ assert objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState == CmHandleState.READY
+ }
and: 'Both CM-handles have expected modules'
['ch-1', 'ch-2'].each { cmHandleId ->
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
index 097a043556..43540a9675 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
@@ -27,7 +27,6 @@ import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration
import org.onap.cps.ncmp.api.inventory.models.LockReasonCategory
import org.onap.cps.ncmp.api.inventory.models.UpgradedCmHandles
import org.onap.cps.ncmp.impl.NetworkCmProxyInventoryFacadeImpl
-import spock.util.concurrent.PollingConditions
class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
@@ -67,9 +66,7 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
then: 'CM-handle goes to READY state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
- })
+ assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
and: 'the CM-handle has expected moduleSetTag'
assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
@@ -111,9 +108,7 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
and: 'CM-handle goes to READY state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
- })
+ assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
and: 'the CM-handle has expected moduleSetTag'
assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
@@ -170,11 +165,9 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
then: 'CM-handle goes to LOCKED state with reason MODULE_UPGRADE_FAILED'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
- assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
- assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
- })
+ def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
+ assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
+ assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
and: 'the CM-handle has same moduleSetTag as before'
assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == 'oldTag'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobStatusServiceSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobStatusServiceSpec.groovy
index 6e5c0e40c2..162b51844c 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobStatusServiceSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobStatusServiceSpec.groovy
@@ -18,6 +18,6 @@ class DataJobStatusServiceSpec extends CpsIntegrationSpecBase {
when: 'the data job status checked'
def result = dataJobStatusService.getDataJobStatus(authorization, dmiServiceName, dataProducerId, dataProducerJobId)
then: 'the status is that defined in the mock service.'
- assert result == 'status details from mock service'
+ assert result == '{"status":"status details from mock service"}'
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
index 81fbc3c4f7..8bbe0ca194 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
@@ -101,7 +101,7 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
})
and: 'log the relevant instrumentation'
def dmiModuleRetrievalTimer = meterRegistry.get('cps.ncmp.inventory.module.references.from.dmi').timer()
- def dbSchemaSetStorageTimer = meterRegistry.get('cps.module.persistence.schemaset.store').timer()
+ def dbSchemaSetStorageTimer = meterRegistry.get('cps.module.persistence.schemaset.createFromNewAndExistingModules').timer()
def dbStateUpdateTimer = meterRegistry.get('cps.ncmp.cmhandle.state.update.batch').timer()
logInstrumentation(dmiModuleRetrievalTimer, 'get modules from DMI ')
logInstrumentation(dbSchemaSetStorageTimer, 'store schema sets ')
@@ -145,10 +145,8 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
when: 'advised cm handles are processed on 2 threads (exactly one batch for each)'
objectUnderTest.moduleSyncAdvisedCmHandles()
executorService.execute(moduleSyncAdvisedCmHandles)
- then: 'wait till all cm handles have been processed'
- new PollingConditions().within(10, () -> {
- assert getNumberOfProcessedCmHandles() == 200
- })
+ then: 'all cm handles have been processed'
+ assert getNumberOfProcessedCmHandles() == 200
then: 'at least 1 cm handle is in state LOCKED'
assert cmHandlesByState.get('lockedCmHandlesCount') >= 1
cleanup: 'remove all test cm handles'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/RestApiSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/RestApiSpec.groovy
index 7ce3cf5e17..77349fe0a5 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/RestApiSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/RestApiSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import org.onap.cps.integration.base.CpsIntegrationSpecBase
import org.springframework.http.MediaType
-import spock.util.concurrent.PollingConditions
class RestApiSpec extends CpsIntegrationSpecBase {
@@ -47,13 +46,11 @@ class RestApiSpec extends CpsIntegrationSpecBase {
and: 'the module sync watchdog is triggered'
moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
then: 'CM-handles go to READY state'
- new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
- (1..3).each {
- mvc.perform(get('/ncmp/v1/ch/ch-'+it))
- .andExpect(status().isOk())
- .andExpect(jsonPath('$.state.cmHandleState').value('READY'))
- }
- })
+ (1..3).each {
+ mvc.perform(get('/ncmp/v1/ch/ch-'+it))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath('$.state.cmHandleState').value('READY'))
+ }
}
def 'Search for CM Handles by module using REST API.'() {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/WriteSubJobSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/WriteSubJobSpec.groovy
index 834e1399e3..46c641cd23 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/WriteSubJobSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/WriteSubJobSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -59,9 +59,9 @@ class WriteSubJobSpec extends CpsIntegrationSpecBase {
then: 'each DMI received the expected sub-jobs and the response has the expected values'
assert response.size() == 2
assert response[0].class == SubJobWriteResponse.class
- assert response[0].subJobId == "some sub job id"
- assert response[0].dmiServiceName == "some dmi service name"
- assert response[0].dataProducerId == "some data producer id"
+ assert response[0].subJobId == 'some sub job id'
+ assert response[0].dmiServiceName.startsWith('http://localhost:') || response[0].dmiServiceName().startsWith('http://kubernetes')
+ assert response[0].dataProducerId == 'some data producer id'
and: 'dmi 1 received the correct job details'
def receivedSubJobsForDispatcher1 = dmiDispatcher1.receivedSubJobs['?destination=d1']['data'].collect()
assert receivedSubJobsForDispatcher1.size() == 2
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy
index a37bb6ad4d..d8553419ce 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy
@@ -47,15 +47,15 @@ class CpsModuleServicePerfTest extends CpsPerfTestBase {
def 'Store new schema set with many modules'() {
when: 'a new schema set with 200 modules is stored'
- def newYangResourcesNameToContentMap = [:]
+ def newYangResourceContentPerName = [:]
(1..200).each {
def year = 2000 + it
def resourceName = "module${it}".toString()
def moduleName = "stores${it}"
def content = NEW_RESOURCE_CONTENT.replace('2020',String.valueOf(year)).replace('stores',moduleName)
- newYangResourcesNameToContentMap.put(resourceName, content)
+ newYangResourceContentPerName.put(resourceName, content)
}
- objectUnderTest.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, 'perfSchemaSet', newYangResourcesNameToContentMap)
+ objectUnderTest.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, 'perfSchemaSet', newYangResourceContentPerName)
then: 'the schema set is persisted correctly'
def result = cpsModuleService.getSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, 'perfSchemaSet')
result.moduleReferences.size() == 200
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy
index 364127f388..acc95cab8d 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy
@@ -103,5 +103,4 @@ class QueryPerfTest extends CpsPerfTestBase {
'direct descendants' | DIRECT_CHILDREN_ONLY || 0.11 | 8 | 1 + OPENROADM_DEVICES_PER_ANCHOR
'all descendants' | INCLUDE_ALL_DESCENDANTS || 1.34 | 400 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
}
-
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/AlternateIdPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/AlternateIdPerfTest.groovy
new file mode 100644
index 0000000000..b9d57cf14d
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/AlternateIdPerfTest.groovy
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2025 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.performance.ncmp
+
+import org.onap.cps.integration.ResourceMeter
+import org.onap.cps.integration.base.CpsIntegrationSpecBase
+
+/**
+ * This test does not depend on common performance test data. Hence it just extends the integration spec base.
+ */
+class AlternateIdPerfTest extends CpsIntegrationSpecBase {
+
+ def resourceMeter = new ResourceMeter()
+
+ def 'Alternate Id Lookup Performance.'() {
+ given: 'register 1,000 cm handles (with alternative ids)'
+ registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(DMI1_URL, 'tagA', 1000, 1)
+ when: 'perform a 1,000 lookups by alternate id'
+ resourceMeter.start()
+ (1..1000).each {
+ networkCmProxyInventoryFacade.getNcmpServiceCmHandle("alt=${it}")
+ }
+ resourceMeter.stop()
+ then: 'record the result. Not asserted, just recorded in See https://lf-onap.atlassian.net/browse/CPS-2605'
+ println "*** CPS-2605 Execution time: ${resourceMeter.totalTimeInSeconds} ms"
+ cleanup: 'deregister test cm handles'
+ deregisterSequenceOfCmHandles(DMI1_URL, 1000, 1)
+ }
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy
index 5389732181..dbf7e71710 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation
+ * Copyright (C) 2023-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ class CmHandleQueryPerfTest extends NcmpPerfTestBase {
cpsDataService.getDataNodes(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR,
'/dmi-registry/cm-handles[@id="cm-' + it + '"]', OMIT_DESCENDANTS)
objectUnderTest.queryDataNodes(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR,
- '/dmi-registry/cm-handles[@alternate-id="alt-' + it + '"]', OMIT_DESCENDANTS)
+ '/dmi-registry/cm-handles[@alternate-id="alt=' + it + '"]', OMIT_DESCENDANTS)
}
resourceMeter.stop()
then: 'resource usage is as expected'
@@ -100,7 +100,7 @@ class CmHandleQueryPerfTest extends NcmpPerfTestBase {
resourceMeter.start()
(1..100).each {
count += cpsQueryService.queryDataNodes(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR,
- '/dmi-registry/cm-handles[@alternate-id="alt-' + it + '"]', OMIT_DESCENDANTS).size()
+ '/dmi-registry/cm-handles[@alternate-id="alt=' + it + '"]', OMIT_DESCENDANTS).size()
}
resourceMeter.stop()
then:
@@ -116,7 +116,7 @@ class CmHandleQueryPerfTest extends NcmpPerfTestBase {
def 'A batch of CM-handles is looked up by alternate-id.'() {
given: 'a CPS Path Query to look up 100 alternate-ids in a single operation'
- def cpsPathQuery = '/dmi-registry/cm-handles[' + (1..100).collect { "@alternate-id='alt-${it}'" }.join(' or ') + ']'
+ def cpsPathQuery = '/dmi-registry/cm-handles[' + (1..100).collect { "@alternate-id='alt=${it}'" }.join(' or ') + ']'
when: 'CM-handles are looked up by alternate-ids in a single query'
resourceMeter.start()
def count = cpsQueryService.queryDataNodes(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, cpsPathQuery, OMIT_DESCENDANTS).size()
diff --git a/integration-test/src/test/java/org/onap/cps/integration/KafkaTestContainer.java b/integration-test/src/test/java/org/onap/cps/integration/KafkaTestContainer.java
index ff4aec4175..60c1637c5a 100644
--- a/integration-test/src/test/java/org/onap/cps/integration/KafkaTestContainer.java
+++ b/integration-test/src/test/java/org/onap/cps/integration/KafkaTestContainer.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation.
+ * Copyright (C) 2024-2025 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
-import org.testcontainers.containers.KafkaContainer;
-import org.testcontainers.utility.DockerImageName;
+import org.testcontainers.kafka.ConfluentKafkaContainer;
/**
* The Apache Kafka test container wrapper.
@@ -35,14 +34,14 @@ import org.testcontainers.utility.DockerImageName;
* Avoid unnecessary resource and time consumption.
*/
@Slf4j
-public class KafkaTestContainer extends KafkaContainer {
+public class KafkaTestContainer extends ConfluentKafkaContainer {
- private static final String IMAGE_NAME_AND_VERSION = "registry.nordix.org/onaptest/confluentinc/cp-kafka:6.2.1";
+ private static final String IMAGE_NAME_AND_VERSION = "confluentinc/cp-kafka:7.8.0";
private static volatile KafkaTestContainer kafkaTestContainer;
private KafkaTestContainer() {
- super(DockerImageName.parse(IMAGE_NAME_AND_VERSION).asCompatibleSubstituteFor("confluentinc/cp-kafka"));
+ super(IMAGE_NAME_AND_VERSION);
}
/**
diff --git a/integration-test/src/test/resources/application.yml b/integration-test/src/test/resources/application.yml
index 30598dfb90..e213a70a59 100644
--- a/integration-test/src/test/resources/application.yml
+++ b/integration-test/src/test/resources/application.yml
@@ -102,6 +102,7 @@ app:
cm-subscription-dmi-out: ${CM_SUBSCRIPTION_DMI_OUT_TOPIC:dmi-ncmp-cm-avc-subscription}
cm-subscription-ncmp-out: ${CM_SUBSCRIPTION_NCMP_OUT_TOPIC:subscription-response}
cm-events-topic: ${NCMP_CM_EVENTS_TOPIC:cm-events}
+ inventory-events-topic: ncmp-inventory-events
lcm:
events:
topic: ${LCM_EVENTS_TOPIC:ncmp-events}
@@ -189,10 +190,6 @@ ncmp:
trust-level:
dmi-availability-watchdog-ms: 30000
- modules-sync-watchdog:
- async-executor:
- parallelism-level: 2
-
model-loader:
maximum-attempt-count: 20
diff --git a/integration-test/src/test/resources/hibernate.cfg.xml b/integration-test/src/test/resources/hibernate.cfg.xml
deleted file mode 100644
index 8d5139b605..0000000000
--- a/integration-test/src/test/resources/hibernate.cfg.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
-
-<hibernate-configuration>
- <session-factory>
- <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
- <property name="hibernate.connection.url">${DB_URL}</property>
- <property name="hibernate.connection.username">${DB_USERNAME}</property>
- <property name="hibernate.connection.password">${DB_PASSWORD}</property>
- <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
- <property name="show_sql">true</property>
- <property name="hibernate.hbm2ddl.auto">none</property>
- </session-factory>
-</hibernate-configuration> \ No newline at end of file