diff options
Diffstat (limited to 'integration-test/src/test')
6 files changed, 339 insertions, 22 deletions
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy index d339f6ddcf..6b1efe955f 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy @@ -81,7 +81,7 @@ class CpsPerfTestBase extends PerfTestBase { addAnchorsWithData(5, CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'openroadm', data) stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() - recordAndAssertPerformance('Creating openroadm anchors with large data tree', 25_000, durationInMillis) + recordAndAssertPerformance('Creating openroadm anchors with large data tree', 30_000, durationInMillis) } def generateOpenRoadData(numberOfNodes) { @@ -98,8 +98,8 @@ class CpsPerfTestBase extends PerfTestBase { assert countDataNodesInTree(result) == 1 stopWatch.stop() def durationInMillis = stopWatch.getTotalTimeMillis() - then: 'all data is read within 25 seconds (warm up not critical)' - recordAndAssertPerformance("Warming database", 25_000, durationInMillis) + then: 'all data is read within 30 seconds (warm up not critical)' + recordAndAssertPerformance("Warming database", 30_000, durationInMillis) } } 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 new file mode 100644 index 0000000000..ce0ed5c171 --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy @@ -0,0 +1,85 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.integration.performance.cps + +import org.onap.cps.api.CpsModuleService +import org.onap.cps.integration.performance.base.CpsPerfTestBase +import org.onap.cps.spi.model.ModuleReference +import org.springframework.util.StopWatch + +import java.util.concurrent.ThreadLocalRandom + +class CpsModuleServicePerfTest extends CpsPerfTestBase { + + def NEW_RESOURCE_CONTENT = 'module stores {\n' + + ' yang-version 1.1;\n' + + ' namespace "org:onap:ccsdk:sample";\n' + + '\n' + + ' prefix book-store;\n' + + '\n' + + ' revision "2020-09-15" {\n' + + ' description\n' + + ' "Sample Model";\n' + + ' }' + + '}' + + CpsModuleService objectUnderTest + + def setup() { objectUnderTest = cpsModuleService } + + def 'Store new schema set with many modules'() { + when: 'a new schema set with 200 modules is stored' + def newYangResourcesNameToContentMap = [:] + (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) + } + objectUnderTest.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, 'perfSchemaSet', newYangResourcesNameToContentMap) + then: 'the schema set is persisted correctly' + def result = cpsModuleService.getSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, 'perfSchemaSet') + result.moduleReferences.size() == 200 + and: 'identification of new module resources is fast enough (1,000 executions less then 6,000 milliseconds)' + def stopWatch = new StopWatch() + 1000.times() { + def moduleReferencesToCheck = createModuleReferencesWithRandomMatchingExistingModuleReferences() + stopWatch.start() + def newModuleReferences = objectUnderTest.identifyNewModuleReferences(moduleReferencesToCheck) + stopWatch.stop() + assert newModuleReferences.size() > 0 && newModuleReferences.size() < 300 + } + assert stopWatch.getTotalTimeMillis() < 6000 + } + + def createModuleReferencesWithRandomMatchingExistingModuleReferences() { + def moduleReferences = [] + (1..250).each { + def randomNumber = ThreadLocalRandom.current().nextInt(1, 300) + def year = 2000 + randomNumber + def moduleName = "stores${randomNumber}" + moduleReferences.add(new ModuleReference(moduleName, "${year}-09-15")) + } + return moduleReferences + } + +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy new file mode 100644 index 0000000000..db36b8809b --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy @@ -0,0 +1,170 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.integration.performance.cps + +import java.time.OffsetDateTime +import org.onap.cps.api.CpsDataService +import org.onap.cps.integration.performance.base.CpsPerfTestBase + +class DeletePerfTest extends CpsPerfTestBase { + + CpsDataService objectUnderTest + + def setup() { objectUnderTest = cpsDataService } + + def 'Create test data (please note, subsequent tests depend on this running first).'() { + when: 'multiple anchors with a node with a large number of descendants is created' + stopWatch.start() + def data = generateOpenRoadData(50) + addAnchorsWithData(9, CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'delete', data) + stopWatch.stop() + def setupDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'setup duration is under 40 seconds' + recordAndAssertPerformance('Delete test setup', 40_000, setupDurationInMillis) + } + + def 'Delete 10 container nodes'() { + when: 'child nodes are deleted' + stopWatch.start() + (1..10).each { + def childPath = "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']/org-openroadm-device" + objectUnderTest.deleteDataNode(CPS_PERFORMANCE_TEST_DATASPACE, 'delete1', childPath, OffsetDateTime.now()) + } + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete 10 containers', 300, deleteDurationInMillis) + } + + def 'Batch delete 50 container nodes'() { + given: 'a list of xpaths to delete' + def xpathsToDelete = (1..50).collect { + "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']/org-openroadm-device" + } + when: 'child nodes are deleted' + stopWatch.start() + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'delete2', xpathsToDelete, OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Batch delete 50 containers', 300, deleteDurationInMillis) + } + + def 'Delete 20 list elements'() { + when: 'list elements are deleted' + stopWatch.start() + (1..20).each { + def listElementXpath = "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-1']/org-openroadm-device/degree[@degree-number=" + it + "]" + objectUnderTest.deleteDataNode(CPS_PERFORMANCE_TEST_DATASPACE, 'delete3', listElementXpath, OffsetDateTime.now()) + } + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete 20 lists elements', 300, deleteDurationInMillis) + } + + def 'Batch delete 1000 list elements'() { + given: 'a list of xpaths to delete' + def xpathsToDelete = [] + for (int childIndex = 1; childIndex <= 50; childIndex++) { + xpathsToDelete.addAll((1..20).collect { + "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-${childIndex}']/org-openroadm-device/degree[@degree-number=${it}]".toString() + }) + } + when: 'list elements are deleted' + stopWatch.start() + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'delete4', xpathsToDelete, OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Batch delete 1000 lists elements', 300, deleteDurationInMillis) + } + + def 'Delete 10 whole lists'() { + when: 'lists are deleted' + stopWatch.start() + (1..10).each { + def childPath = "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']/org-openroadm-device/degree" + objectUnderTest.deleteDataNode(CPS_PERFORMANCE_TEST_DATASPACE, 'delete5', childPath, OffsetDateTime.now()) + } + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete 10 whole lists', 300, deleteDurationInMillis) + } + + def 'Batch delete 30 whole lists'() { + given: 'a list of xpaths to delete' + def xpathsToDelete = (1..30).collect { + "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']/org-openroadm-device/degree" + } + when: 'lists are deleted' + stopWatch.start() + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'delete6', xpathsToDelete, OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Batch delete 30 whole lists', 300, deleteDurationInMillis) + } + + def 'Delete 1 large data node'() { + when: 'parent node is deleted' + stopWatch.start() + objectUnderTest.deleteDataNode(CPS_PERFORMANCE_TEST_DATASPACE, 'delete7', '/openroadm-devices', OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete one large node', 300, deleteDurationInMillis) + } + + def 'Delete root node with many descendants'() { + when: 'root node is deleted' + stopWatch.start() + objectUnderTest.deleteDataNode(CPS_PERFORMANCE_TEST_DATASPACE, 'delete8', '/', OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete root node', 300, deleteDurationInMillis) + } + + def 'Delete data nodes for an anchor'() { + when: 'data nodes are deleted' + stopWatch.start() + objectUnderTest.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'delete9', OffsetDateTime.now()) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 300 milliseconds' + recordAndAssertPerformance('Delete data nodes for anchor', 300, deleteDurationInMillis) + } + + def 'Clean up test data'() { + given: 'a list of anchors to delete' + def anchorNames = (1..9).collect {'delete' + it} + when: 'data nodes are deleted' + stopWatch.start() + cpsAdminService.deleteAnchors(CPS_PERFORMANCE_TEST_DATASPACE, anchorNames) + stopWatch.stop() + def deleteDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'delete duration is under 1000 milliseconds' + recordAndAssertPerformance('Delete test cleanup', 1000, deleteDurationInMillis) + } + +} diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy index c072755d31..d20da46cc5 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy @@ -45,8 +45,8 @@ class GetPerfTest extends CpsPerfTestBase { where: 'the following parameters are used' scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 1 - 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 100 | 1 + 50 - 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 350 | 1 + 50 * 86 + 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 150 | 1 + 50 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 600 | 1 + 50 * 86 } def 'Read data trees for multiple xpaths'() { @@ -58,8 +58,8 @@ class GetPerfTest extends CpsPerfTestBase { stopWatch.stop() assert countDataNodesInTree(result) == 50 * 86 def durationInMillis = stopWatch.getTotalTimeMillis() - then: 'all data is read within 350 ms' - recordAndAssertPerformance("Read datatrees for multiple xpaths", 350, durationInMillis) + then: 'all data is read within 500 ms' + recordAndAssertPerformance("Read datatrees for multiple xpaths", 500, durationInMillis) } def 'Read complete data trees using #scenario.'() { @@ -75,10 +75,10 @@ class GetPerfTest extends CpsPerfTestBase { recordAndAssertPerformance("Read datatrees using ${scenario}", durationLimit, durationInMillis) where: 'the following xpaths are used' scenario | anchorPrefix | xpath || durationLimit | expectedNumberOfDataNodes - 'bookstore root' | 'bookstore' | '/' || 250 | 78 - 'bookstore top element' | 'bookstore' | '/bookstore' || 250 | 78 - 'openroadm root' | 'openroadm' | '/' || 1000 | 1 + 50 * 86 - 'openroadm top element' | 'openroadm' | '/openroadm-devices' || 1000 | 1 + 50 * 86 + 'bookstore root' | 'bookstore' | '/' || 300 | 78 + 'bookstore top element' | 'bookstore' | '/bookstore' || 300 | 78 + 'openroadm root' | 'openroadm' | '/' || 1200 | 1 + 50 * 86 + 'openroadm top element' | 'openroadm' | '/openroadm-devices' || 1200 | 1 + 50 * 86 } } 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 ecc44ff9d3..885f1c2038 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 @@ -45,10 +45,10 @@ class QueryPerfTest extends CpsPerfTestBase { recordAndAssertPerformance("Query 1 anchor ${scenario}", durationLimit, durationInMillis) where: 'the following parameters are used' scenario | anchor | cpsPath || durationLimit | expectedNumberOfDataNodes - 'top element' | 'openroadm1' | '/openroadm-devices' || 250 | 50 * 86 + 1 - 'leaf condition' | 'openroadm2' | '//openroadm-device[@ne-state="inservice"]' || 250 | 50 * 86 - 'ancestors' | 'openroadm3' | '//openroadm-device/ancestor::openroadm-devices' || 250 | 50 * 86 + 1 - 'leaf condition + ancestors' | 'openroadm4' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 250 | 50 * 86 + 1 + 'top element' | 'openroadm1' | '/openroadm-devices' || 500 | 50 * 86 + 1 + 'leaf condition' | 'openroadm2' | '//openroadm-device[@ne-state="inservice"]' || 500 | 50 * 86 + 'ancestors' | 'openroadm3' | '//openroadm-device/ancestor::openroadm-devices' || 500 | 50 * 86 + 1 + 'leaf condition + ancestors' | 'openroadm4' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 500 | 50 * 86 + 1 } def 'Query complete data trees across all anchors with #scenario.'() { @@ -63,10 +63,10 @@ class QueryPerfTest extends CpsPerfTestBase { recordAndAssertPerformance("Query across anchors ${scenario}", durationLimit, durationInMillis) where: 'the following parameters are used' scenario | cpspath || durationLimit | expectedNumberOfDataNodes - 'top element' | '/openroadm-devices' || 1000 | 5 * (50 * 86 + 1) - 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 1000 | 5 * (50 * 86) - 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 1000 | 5 * (50 * 86 + 1) - 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 1000 | 5 * (50 * 86 + 1) + 'top element' | '/openroadm-devices' || 2000 | 5 * (50 * 86 + 1) + 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 2000 | 5 * (50 * 86) + 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 2000 | 5 * (50 * 86 + 1) + 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 2000 | 5 * (50 * 86 + 1) } def 'Query with leaf condition and #scenario.'() { @@ -82,8 +82,8 @@ class QueryPerfTest extends CpsPerfTestBase { where: 'the following parameters are used' scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 50 - 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 150 | 50 * 2 - 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 200 | 50 * 86 + 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 200 | 50 * 2 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 500 | 50 * 86 } def 'Query ancestors with #scenario.'() { @@ -100,7 +100,7 @@ class QueryPerfTest extends CpsPerfTestBase { scenario | fetchDescendantsOption | anchor || durationLimit | expectedNumberOfDataNodes 'no descendants' | OMIT_DESCENDANTS | 'openroadm1' || 100 | 1 'direct descendants' | DIRECT_CHILDREN_ONLY | 'openroadm2' || 200 | 1 + 50 - 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 300 | 1 + 50 * 86 + 'all descendants' | INCLUDE_ALL_DESCENDANTS | 'openroadm3' || 500 | 1 + 50 * 86 } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy new file mode 100644 index 0000000000..c281908653 --- /dev/null +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.integration.performance.cps + +import java.time.OffsetDateTime +import org.onap.cps.api.CpsDataService +import org.onap.cps.integration.performance.base.CpsPerfTestBase + +class UpdatePerfTest extends CpsPerfTestBase { + + CpsDataService objectUnderTest + + def setup() { objectUnderTest = cpsDataService } + + def 'Update 1 data node with descendants'() { + given: 'a list of data nodes to update as JSON' + def parentNodeXpath = "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-10']" + def jsonData = readResourceDataFile('openroadm/innerNode.json').replace('NODE_ID_HERE', '10') + when: 'the fragment entities are updated by the data nodes' + stopWatch.start() + objectUnderTest.updateDataNodeAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm1', parentNodeXpath, jsonData, OffsetDateTime.now()) + stopWatch.stop() + def updateDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'update duration is under 1000 milliseconds' + recordAndAssertPerformance('Update 1 data node', 1000, updateDurationInMillis) + } + + def 'Batch update 10 data nodes with descendants'() { + given: 'a list of data nodes to update as JSON' + def innerNodeJson = readResourceDataFile('openroadm/innerNode.json') + def nodesJsonData = (20..30).collectEntries {[ + "/openroadm-devices/openroadm-device[@device-id='C201-7-1A-" + it + "']", + innerNodeJson.replace('NODE_ID_HERE', it.toString()) + ]} + when: 'the fragment entities are updated by the data nodes' + stopWatch.start() + objectUnderTest.updateDataNodesAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm2', nodesJsonData, OffsetDateTime.now()) + stopWatch.stop() + def updateDurationInMillis = stopWatch.getTotalTimeMillis() + then: 'update duration is under 5000 milliseconds' + recordAndAssertPerformance('Update 10 data nodes', 5000, updateDurationInMillis) + } + +} |