summaryrefslogtreecommitdiffstats
path: root/integration-test
diff options
context:
space:
mode:
authordanielhanrahan <daniel.hanrahan@est.tech>2023-05-09 13:33:37 +0100
committerdanielhanrahan <daniel.hanrahan@est.tech>2023-05-09 15:49:46 +0100
commit153c4e856e3c818837efc0c17348c18ccf64821c (patch)
tree14a38d414caa1b4ae0d305f86d6f815984ac27e7 /integration-test
parentf12bf21976894cf8618942a5511efb773cd791f4 (diff)
Migrate cps-ri performance tests to integration-test module
- Migrate update and delete data service tests, using openroadm model - Move module service tests to integration-test module - Update performance test timings - Remove all performance-related files from cps-ri - Remove performance profile from cps-ri pom.xml Issue-ID: CPS-1687 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: Id9d864f8cab0377cb37c7967943d738748e1b6c5
Diffstat (limited to 'integration-test')
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy6
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsModuleServicePerfTest.groovy85
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy170
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/GetPerfTest.groovy16
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/QueryPerfTest.groovy22
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy62
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 d339f6ddc..6b1efe955 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 000000000..ce0ed5c17
--- /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 000000000..db36b8809
--- /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 c072755d3..d20da46cc 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 ecc44ff9d..885f1c203 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 000000000..c28190865
--- /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)
+ }
+
+}