X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=integration-test%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Fintegration%2Fperformance%2Fcps%2FUpdatePerfTest.groovy;h=b3030b1c6ba4eb705fbce32ee6faf5139ac279db;hb=89871c11e9a32ad588fce392872a4be00badd0fe;hp=a02d21c41a51f6e2f28781f783a63f41cf85673a;hpb=4662655882edc48dd66fa83a9adf881362cb52ac;p=cps.git 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 index a02d21c41..b3030b1c6 100644 --- 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation + * Copyright (C) 2023-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. @@ -24,39 +24,132 @@ import java.time.OffsetDateTime import org.onap.cps.api.CpsDataService import org.onap.cps.integration.performance.base.CpsPerfTestBase +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + class UpdatePerfTest extends CpsPerfTestBase { + static final def UPDATE_TEST_ANCHOR = 'updateTestAnchor' + static final def INNER_NODE_JSON = readResourceDataFile('openroadm/innerNode.json') CpsDataService objectUnderTest + def now = OffsetDateTime.now() 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', 600, 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', 4000, updateDurationInMillis) + def 'Test setup for CPS Update API.'() { + given: 'an anchor and empty container node for OpenROADM devices' + cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, UPDATE_TEST_ANCHOR) + cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, + '{ "openroadm-devices": { "openroadm-device": []}}', now) + expect: 'no device nodes exist yet' + assert 0 == countDataNodes('/openroadm-devices/openroadm-device') + } + + def 'JVM warm up for update tests: #scenario.'() { + given: 'replacement JSON for node containing list of device nodes' + def jsonData = '{ "openroadm-devices": ' + generateJsonForOpenRoadmDevices(startId, totalNodes, changeLeaves) + '}' + when: 'the container node is updated' + objectUnderTest.updateDataNodeAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, '/', jsonData, now) + then: 'there are the expected number of total nodes' + assert totalNodes == countDataNodes('/openroadm-devices/openroadm-device') + where: + scenario | totalNodes | startId | changeLeaves + 'Replace 0 nodes with 100' | 100 | 1 | false + 'Replace 100 using same data' | 100 | 1 | false + 'Replace 100 with new leaf values' | 100 | 1 | true + 'Replace 100 with 100 new nodes' | 100 | 101 | false + 'Replace 50 existing and 50 new' | 100 | 151 | true + 'Replace 100 nodes with 0' | 0 | 1 | false + } + + def 'Replace single data node and descendants: #scenario.'() { + given: 'replacement JSON for node containing list of device nodes' + def jsonData = '{ "openroadm-devices": ' + generateJsonForOpenRoadmDevices(startId, totalNodes, changeLeaves) + '}' + when: 'the container node is updated' + resourceMeter.start() + objectUnderTest.updateDataNodeAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, '/', jsonData, now) + resourceMeter.stop() + then: 'there are the expected number of total nodes' + assert totalNodes == countDataNodes('/openroadm-devices/openroadm-device') + and: 'data leaves have expected values' + assert totalNodes == countDataNodes(changeLeaves? '/openroadm-devices/openroadm-device[@status="fail"]' + : '/openroadm-devices/openroadm-device[@status="success"]') + and: 'update completes within expected time and memory used is within limit' + recordAndAssertResourceUsage(scenario, + timeLimit, resourceMeter.getTotalTimeInSeconds(), + memoryLimit, resourceMeter.getTotalMemoryUsageInMB()) + where: + scenario | totalNodes | startId | changeLeaves || timeLimit | memoryLimit + 'Replace 0 nodes with 100' | 100 | 1 | false || 7 | 250 + 'Replace 100 using same data' | 100 | 1 | false || 3 | 250 + 'Replace 100 with new leaf values' | 100 | 1 | true || 3 | 250 + 'Replace 100 with 100 new nodes' | 100 | 101 | false || 12 | 300 + 'Replace 50 existing and 50 new' | 100 | 151 | true || 8 | 250 + 'Replace 100 nodes with 0' | 0 | 1 | false || 5 | 250 + } + + def 'Replace list content: #scenario.'() { + given: 'replacement JSON for list of device nodes' + def jsonListData = generateJsonForOpenRoadmDevices(startId, totalNodes, changeLeaves) + when: 'the container node is updated' + resourceMeter.start() + objectUnderTest.replaceListContent(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, '/openroadm-devices', jsonListData, now) + resourceMeter.stop() + then: 'there are the expected number of total nodes' + assert totalNodes == countDataNodes('/openroadm-devices/openroadm-device') + and: 'data leaves have expected values' + assert totalNodes == countDataNodes(changeLeaves? '/openroadm-devices/openroadm-device[@status="fail"]' + : '/openroadm-devices/openroadm-device[@status="success"]') + and: 'update completes within expected time and memory used is within limit' + recordAndAssertResourceUsage(scenario, + timeLimit, resourceMeter.getTotalTimeInSeconds(), + memoryLimit, resourceMeter.getTotalMemoryUsageInMB()) + where: + scenario | totalNodes | startId | changeLeaves || timeLimit | memoryLimit + 'Replace list of 0 with 100' | 100 | 1 | false || 7 | 250 + 'Replace list of 100 using same data' | 100 | 1 | false || 3 | 250 + 'Replace list of 100 with new leaf values' | 100 | 1 | true || 3 | 250 + 'Replace list with 100 new nodes' | 100 | 101 | false || 12 | 300 + 'Replace list with 50 existing and 50 new' | 100 | 151 | true || 8 | 250 + 'Replace list of 100 nodes with 1' | 1 | 1 | false || 5 | 250 + } + + def 'Update leaves for 100 data nodes.'() { + given: 'there are 200 existing data nodes' + def jsonListData = generateJsonForOpenRoadmDevices(1, 200, false) + objectUnderTest.replaceListContent(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, '/openroadm-devices', jsonListData, now) + and: 'JSON for updated data leaves of 100 nodes' + def jsonDataUpdated = "{'openroadm-device':[" + (1..100).collect {"{'device-id':'C201-7-1A-" + it + "','status':'fail','ne-state':'jeopardy'}" }.join(",") + "]}" + when: 'update is performed for leaves' + resourceMeter.start() + objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR, "/openroadm-devices", jsonDataUpdated, now) + resourceMeter.stop() + then: 'data leaves have expected values' + assert 100 == countDataNodes('/openroadm-devices/openroadm-device[@status="fail"]') + and: 'update completes within expected time and memory used is within limit' + recordAndAssertResourceUsage('Update leaves for 100 data nodes', + 0.5, resourceMeter.getTotalTimeInSeconds(), + 120, resourceMeter.getTotalMemoryUsageInMB()) + } + + def 'Clean up for CPS Update API.'() { + cleanup: 'test anchor and data nodes' + cpsAnchorService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, UPDATE_TEST_ANCHOR) + } + + def generateJsonForOpenRoadmDevices(int startId, int totalNodes, boolean changeLeaves) { + return '{ "openroadm-device": [' + (0..