aboutsummaryrefslogtreecommitdiffstats
path: root/integration-test
diff options
context:
space:
mode:
Diffstat (limited to 'integration-test')
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/ResourceMeterPerfTest.groovy83
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy17
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy97
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy4
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy4
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy24
-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.groovy30
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy31
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmDataSubscriptionsPerfTest.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmHandleQueryPerfTest.groovy4
-rw-r--r--integration-test/src/test/java/org/onap/cps/integration/ResourceMeter.java41
-rw-r--r--integration-test/src/test/resources/data/bookstore/bookstore.yang11
-rw-r--r--integration-test/src/test/resources/data/bookstore/bookstoreDataForDeltaReport.json192
16 files changed, 496 insertions, 76 deletions
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/ResourceMeterPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/ResourceMeterPerfTest.groovy
new file mode 100644
index 000000000..c42bfd7be
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/ResourceMeterPerfTest.groovy
@@ -0,0 +1,83 @@
+/*
+ * ============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
+
+import java.util.concurrent.TimeUnit
+import spock.lang.Specification
+
+class ResourceMeterPerfTest extends Specification {
+
+ final int MEGABYTE = 1_000_000
+
+ def resourceMeter = new ResourceMeter()
+
+ def 'ResourceMeter accurately measures duration'() {
+ when: 'we measure how long a known operation takes'
+ resourceMeter.start()
+ TimeUnit.SECONDS.sleep(2)
+ resourceMeter.stop()
+ then: 'ResourceMeter reports a duration within 10ms of the expected duration'
+ assert resourceMeter.getTotalTimeInSeconds() >= 2
+ assert resourceMeter.getTotalTimeInSeconds() <= 2.01
+ }
+
+ def 'ResourceMeter reports memory usage when allocating a large byte array'() {
+ when: 'the resource meter is started'
+ resourceMeter.start()
+ and: 'some memory is allocated'
+ byte[] array = new byte[50 * MEGABYTE]
+ and: 'the resource meter is stopped'
+ resourceMeter.stop()
+ then: 'the reported memory usage is close to the amount of memory allocated'
+ assert resourceMeter.getTotalMemoryUsageInMB() >= 50
+ assert resourceMeter.getTotalMemoryUsageInMB() <= 55
+ }
+
+ def 'ResourceMeter measures PEAK memory usage when garbage collector runs'() {
+ when: 'the resource meter is started'
+ resourceMeter.start()
+ and: 'some memory is allocated'
+ byte[] array = new byte[50 * MEGABYTE]
+ and: 'the memory is garbage collected'
+ array = null
+ ResourceMeter.performGcAndWait()
+ and: 'the resource meter is stopped'
+ resourceMeter.stop()
+ then: 'the reported memory usage is close to the peak amount of memory allocated'
+ assert resourceMeter.getTotalMemoryUsageInMB() >= 50
+ assert resourceMeter.getTotalMemoryUsageInMB() <= 55
+ }
+
+ def 'ResourceMeter measures memory increase only during measurement'() {
+ given: '50 megabytes is allocated before measurement'
+ byte[] arrayBefore = new byte[50 * MEGABYTE]
+ when: 'memory is allocated during measurement'
+ resourceMeter.start()
+ byte[] arrayDuring = new byte[40 * MEGABYTE]
+ resourceMeter.stop()
+ and: '50 megabytes is allocated after measurement'
+ byte[] arrayAfter = new byte[50 * MEGABYTE]
+ then: 'the reported memory usage is close to the amount allocated DURING measurement'
+ assert resourceMeter.getTotalMemoryUsageInMB() >= 40
+ assert resourceMeter.getTotalMemoryUsageInMB() <= 45
+ }
+
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
index 327a39ee4..14612d6c1 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2023 Nordix Foundation
+ * Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,17 +27,24 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
def static FUNCTIONAL_TEST_DATASPACE_1 = 'functionalTestDataspace1'
def static FUNCTIONAL_TEST_DATASPACE_2 = 'functionalTestDataspace2'
+ def static FUNCTIONAL_TEST_DATASPACE_3 = 'functionalTestDataspace3'
def static NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA = 2
+ def static NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DELTA_DATA = 1
def static BOOKSTORE_ANCHOR_1 = 'bookstoreAnchor1'
def static BOOKSTORE_ANCHOR_2 = 'bookstoreAnchor2'
+ def static BOOKSTORE_ANCHOR_3 = 'bookstoreSourceAnchor1'
+ def static BOOKSTORE_ANCHOR_4 = 'copyOfSourceAnchor1'
+ def static BOOKSTORE_ANCHOR_5 = 'bookstoreAnchorForDeltaReport1'
def static initialized = false
def static bookstoreJsonData = readResourceDataFile('bookstore/bookstoreData.json')
+ def static bookstoreJsonDataForDeltaReport = readResourceDataFile('bookstore/bookstoreDataForDeltaReport.json')
def setup() {
if (!initialized) {
setupBookstoreInfraStructure()
addBookstoreData()
+ addDeltaData()
initialized = true
}
}
@@ -44,9 +52,12 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
def setupBookstoreInfraStructure() {
cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1)
cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2)
+ cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_3)
def bookstoreYangModelAsString = readResourceDataFile('bookstore/bookstore.yang')
cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
+ cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
+
}
def addBookstoreData() {
@@ -54,6 +65,12 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DATA, FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchor', bookstoreJsonData)
}
+ def addDeltaData() {
+ addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DELTA_DATA, FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_SCHEMA_SET, 'bookstoreSourceAnchor', bookstoreJsonData)
+ addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DELTA_DATA, FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_SCHEMA_SET, 'copyOfSourceAnchor', bookstoreJsonData)
+ addAnchorsWithData(NUMBER_OF_ANCHORS_PER_DATASPACE_WITH_BOOKSTORE_DELTA_DATA, FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_SCHEMA_SET, 'bookstoreAnchorForDeltaReport', bookstoreJsonDataForDeltaReport)
+ }
+
def restoreBookstoreDataAnchor(anchorNumber) {
def anchorName = 'bookstoreAnchor' + anchorNumber
cpsAdminService.deleteAnchor(FUNCTIONAL_TEST_DATASPACE_1, anchorName)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
index 12c97ed40..017ede7de 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
@@ -32,6 +32,7 @@ import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataNodeNotFoundExceptionBatch
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
+import org.onap.cps.spi.model.DeltaReport
import java.time.OffsetDateTime
@@ -432,6 +433,102 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase {
restoreBookstoreDataAnchor(2)
}
+ def 'Get delta between 2 anchors for when #scenario'() {
+ when: 'attempt to get delta report between anchors'
+ def result = objectUnderTest.getDeltaByDataspaceAndAnchors(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_ANCHOR_3, BOOKSTORE_ANCHOR_5, xpath, fetchDescendantOption)
+ then: 'delta report contains expected number of changes'
+ result.size() == 2
+ and: 'delta report contains expected action'
+ assert result.get(index).getAction() == expectedActions
+ and: 'delta report contains expected xpath'
+ assert result.get(index).getXpath() == expectedXpath
+ where: 'following data was used'
+ scenario | index | xpath || expectedActions || expectedXpath | fetchDescendantOption
+ 'a node is removed' | 0 | '/' || 'remove' || "/bookstore-address[@bookstore-name='Easons-1']" | OMIT_DESCENDANTS
+ 'a node is added' | 1 | '/' || 'add' || "/bookstore-address[@bookstore-name='Crossword Bookstores']" | OMIT_DESCENDANTS
+ }
+
+ def 'Get delta between 2 anchors where child nodes are added/removed but parent node remains unchanged'() {
+ def parentNodeXpath = "/bookstore"
+ when: 'attempt to get delta report between anchors'
+ def result = objectUnderTest.getDeltaByDataspaceAndAnchors(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_ANCHOR_3, BOOKSTORE_ANCHOR_5, parentNodeXpath, INCLUDE_ALL_DESCENDANTS)
+ then: 'delta report contains expected number of changes'
+ result.size() == 11
+ and: 'the delta report does not contain parent node xpath'
+ def xpaths = getDeltaReportEntities(result).get('xpaths')
+ assert !(xpaths.contains(parentNodeXpath))
+ }
+
+ def 'Get delta between 2 anchors returns empty response when #scenario'() {
+ when: 'attempt to get delta report between anchors'
+ def result = objectUnderTest.getDeltaByDataspaceAndAnchors(FUNCTIONAL_TEST_DATASPACE_3, sourceAnchor, targetAnchor, xpath, INCLUDE_ALL_DESCENDANTS)
+ then: 'delta report is empty'
+ assert result.isEmpty()
+ where: 'following data was used'
+ scenario | sourceAnchor | targetAnchor | xpath
+ 'anchors with identical data are queried' | BOOKSTORE_ANCHOR_3 | BOOKSTORE_ANCHOR_4 | '/'
+ 'same anchor name is passed as parameter' | BOOKSTORE_ANCHOR_3 | BOOKSTORE_ANCHOR_3 | '/'
+ 'non existing xpath' | BOOKSTORE_ANCHOR_3 | BOOKSTORE_ANCHOR_5 | '/non-existing-xpath'
+ }
+
+ def 'Get delta between anchors error scenario: #scenario'() {
+ when: 'attempt to get delta between anchors'
+ objectUnderTest.getDeltaByDataspaceAndAnchors(dataspaceName, sourceAnchor, targetAnchor, '/some-xpath', INCLUDE_ALL_DESCENDANTS)
+ then: 'expected exception is thrown'
+ thrown(expectedException)
+ where: 'following data was used'
+ scenario | dataspaceName | sourceAnchor | targetAnchor || expectedException
+ 'invalid dataspace name' | 'Invalid dataspace' | 'not-relevant' | 'not-relevant' || DataValidationException
+ 'invalid anchor 1 name' | FUNCTIONAL_TEST_DATASPACE_3 | 'invalid anchor' | 'not-relevant' || DataValidationException
+ 'invalid anchor 2 name' | FUNCTIONAL_TEST_DATASPACE_3 | BOOKSTORE_ANCHOR_3 | 'invalid anchor' || DataValidationException
+ 'non-existing dataspace' | 'non-existing' | 'not-relevant1' | 'not-relevant2' || DataspaceNotFoundException
+ 'non-existing dataspace with same anchor name' | 'non-existing' | 'not-relevant' | 'not-relevant' || DataspaceNotFoundException
+ 'non-existing anchor 1' | FUNCTIONAL_TEST_DATASPACE_3 | 'non-existing-anchor' | 'not-relevant' || AnchorNotFoundException
+ 'non-existing anchor 2' | FUNCTIONAL_TEST_DATASPACE_3 | BOOKSTORE_ANCHOR_3 | 'non-existing-anchor' || AnchorNotFoundException
+ }
+
+ def 'Get delta between anchors for remove action, where source data node #scenario'() {
+ when: 'attempt to get delta between leaves of data nodes present in 2 anchors'
+ def result = objectUnderTest.getDeltaByDataspaceAndAnchors(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_ANCHOR_5, BOOKSTORE_ANCHOR_3, parentNodeXpath, INCLUDE_ALL_DESCENDANTS)
+ then: 'expected action is present in delta report'
+ assert result.get(0).getAction() == 'remove'
+ where: 'following data was used'
+ scenario | parentNodeXpath
+ 'has leaves and child nodes' | "/bookstore/categories[@code='6']"
+ 'has leaves only' | "/bookstore/categories[@code='5']/books[@title='Book 11']"
+ 'has child data node only' | "/bookstore/support-info/contact-emails"
+ 'is empty' | "/bookstore/container-without-leaves"
+ }
+
+ def 'Get delta between anchors for add action, where target data node #scenario'() {
+ when: 'attempt to get delta between leaves of data nodes present in 2 anchors'
+ def result = objectUnderTest.getDeltaByDataspaceAndAnchors(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_ANCHOR_3, BOOKSTORE_ANCHOR_5, parentNodeXpath, INCLUDE_ALL_DESCENDANTS)
+ then: 'the expected action is present in delta report'
+ result.get(0).getAction() == 'add'
+ and: 'the expected xapth is present in delta report'
+ result.get(0).getXpath() == parentNodeXpath
+ where: 'following data was used'
+ scenario | parentNodeXpath
+ 'has leaves and child nodes' | "/bookstore/categories[@code='6']"
+ 'has leaves only' | "/bookstore/categories[@code='5']/books[@title='Book 11']"
+ 'has child data node only' | "/bookstore/support-info/contact-emails"
+ 'is empty' | "/bookstore/container-without-leaves"
+ }
+
+ def getDeltaReportEntities(List<DeltaReport> deltaReport) {
+ def xpaths = []
+ def action = []
+ def sourcePayload = []
+ def targetPayload = []
+ deltaReport.each {
+ delta -> xpaths.add(delta.getXpath())
+ action.add(delta.getAction())
+ sourcePayload.add(delta.getSourceData())
+ targetPayload.add(delta.getTargetData())
+ }
+ return ['xpaths':xpaths, 'action':action, 'sourcePayload':sourcePayload, 'targetPayload':targetPayload]
+ }
+
def countDataNodesInBookstore() {
return countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', INCLUDE_ALL_DESCENDANTS))
}
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 8cdbdc595..d8012ec6d 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
@@ -67,7 +67,7 @@ class CpsPerfTestBase extends PerfTestBase {
addAnchorsWithData(OPENROADM_ANCHORS, CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'openroadm', data)
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
- recordAndAssertResourceUsage('Creating openroadm anchors with large data tree', 200, durationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Creating openroadm anchors with large data tree', 200, durationInSeconds, 600, resourceMeter.getTotalMemoryUsageInMB())
}
def generateOpenRoadData(numberOfNodes) {
@@ -87,7 +87,7 @@ class CpsPerfTestBase extends PerfTestBase {
then: 'memory used is within #peakMemoryUsage'
assert resourceMeter.getTotalMemoryUsageInMB() <= 30
and: 'all data is read within expected time'
- recordAndAssertResourceUsage("Warming database", 200, durationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Warming database", 200, durationInSeconds, 600, resourceMeter.getTotalMemoryUsageInMB())
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
index b0a105c7f..a96d7f64b 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
@@ -55,7 +55,7 @@ abstract class PerfTestBase extends CpsIntegrationSpecBase {
abstract def createInitialData()
def recordAndAssertResourceUsage(String shortTitle, double thresholdInSec, double recordedTimeInSec, memoryLimit, memoryUsageInMB) {
- def pass = recordedTimeInSec <= thresholdInSec
+ def pass = recordedTimeInSec <= thresholdInSec && memoryUsageInMB <= memoryLimit
if (shortTitle.length() > 40) {
shortTitle = shortTitle.substring(0, 40)
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
index 6a3d4434b..ce66cb08a 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
@@ -47,7 +47,7 @@ class CpsDataServiceLimitsPerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'the operation completes within 25 seconds'
- recordAndAssertResourceUsage("Creating 33,000 books", 25, durationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Creating 33,000 books", 25, durationInSeconds, 150, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Get data nodes from multiple xpaths 32K (2^15) limit exceeded.'() {
@@ -88,7 +88,7 @@ class CpsDataServiceLimitsPerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'test data is deleted in 1 second'
- recordAndAssertResourceUsage("Deleting test data", 1, durationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Deleting test data", 1, durationInSeconds, 3, resourceMeter.getTotalMemoryUsageInMB())
}
def countDataNodes() {
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
index 0dcd995a7..818c300a5 100644
--- 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
@@ -40,7 +40,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def setupDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'setup duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete test setup', 200, setupDurationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete test setup', 200, setupDurationInSeconds, 800, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete 100 container nodes'() {
@@ -56,7 +56,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete 100 containers', 2, deleteDurationInSeconds, 30, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete 100 containers', 2.5, deleteDurationInSeconds, 20, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch delete 100 container nodes'() {
@@ -70,7 +70,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Batch delete 100 containers', 0.5, deleteDurationInSeconds, 5, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Batch delete 100 containers', 0.6, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete 100 list elements'() {
@@ -86,7 +86,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete 100 lists elements', 2, deleteDurationInSeconds, 20, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete 100 lists elements', 2.5, deleteDurationInSeconds, 20, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch delete 100 list elements'() {
@@ -100,7 +100,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Batch delete 100 lists elements', 0.5, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Batch delete 100 lists elements', 0.6, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete 100 whole lists'() {
@@ -116,7 +116,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete 100 whole lists', 5, deleteDurationInSeconds, 30, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete 100 whole lists', 6, deleteDurationInSeconds, 20, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch delete 100 whole lists'() {
@@ -130,7 +130,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Batch delete 100 whole lists', 4, deleteDurationInSeconds, 5, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Batch delete 100 whole lists', 5, deleteDurationInSeconds, 3, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete 1 large data node'() {
@@ -140,7 +140,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete one large node', 2, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete one large node', 2, deleteDurationInSeconds, 1, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete root node with many descendants'() {
@@ -150,7 +150,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete root node', 2, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete root node', 2, deleteDurationInSeconds, 1, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Delete data nodes for an anchor'() {
@@ -160,7 +160,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete data nodes for anchor', 2, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete data nodes for anchor', 2, deleteDurationInSeconds, 1, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch delete 100 non-existing nodes'() {
@@ -174,7 +174,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Batch delete 100 non-existing', 7, deleteDurationInSeconds, 5, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Batch delete 100 non-existing', 7, deleteDurationInSeconds, 3, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Clean up test data'() {
@@ -186,7 +186,7 @@ class DeletePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Delete test cleanup', 10, deleteDurationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Delete test cleanup', 10, deleteDurationInSeconds, 1, resourceMeter.getTotalMemoryUsageInMB())
}
}
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 95cf260f2..8a228a353 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
@@ -44,9 +44,9 @@ class GetPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Read datatrees with ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following parameters are used'
scenario | fetchDescendantsOption || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'no descendants' | OMIT_DESCENDANTS || 0.01 | 5 | 1
- 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.05 | 10 | 1 + OPENROADM_DEVICES_PER_ANCHOR
- 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2 | 200 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'no descendants' | OMIT_DESCENDANTS || 0.02 | 1 | 1
+ 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.06 | 5 | 1 + OPENROADM_DEVICES_PER_ANCHOR
+ 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2.5 | 250 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
}
def 'Read data trees for multiple xpaths'() {
@@ -60,7 +60,7 @@ class GetPerfTest extends CpsPerfTestBase {
then: 'requested nodes and their descendants are returned'
assert countDataNodesInTree(result) == OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
and: 'all data is read within expected time and memory used is within limit'
- recordAndAssertResourceUsage("Read datatrees for multiple xpaths", 3 , durationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Read datatrees for multiple xpaths", 4 , durationInSeconds, 300, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Read for multiple xpaths to non-existing datanodes'() {
@@ -74,7 +74,7 @@ class GetPerfTest extends CpsPerfTestBase {
then: 'no data is returned'
assert result.isEmpty()
and: 'the operation completes within within expected time'
- recordAndAssertResourceUsage("Read non-existing xpaths", 0.01, durationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Read non-existing xpaths", 0.02, durationInSeconds, 2, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Read complete data trees using #scenario.'() {
@@ -88,9 +88,9 @@ class GetPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Read datatrees using ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following xpaths are used'
scenario | xpath || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'openroadm root' | '/' || 2 | 200 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
- 'openroadm top element' | '/openroadm-devices' || 2 | 200 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
- 'openroadm whole list' | '/openroadm-devices/openroadm-device' || 3 | 200 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'openroadm root' | '/' || 2 | 250 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'openroadm top element' | '/openroadm-devices' || 2 | 250 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'openroadm whole list' | '/openroadm-devices/openroadm-device' || 3 | 250 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
}
}
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 5cf495563..0ae018d46 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,11 @@ class QueryPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Query 1 anchor ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following parameters are used'
scenario | cpsPath || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'top element' | '/openroadm-devices' || 2 | 300 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
- 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 3 | 200 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
- 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 2 | 200 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
- 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 2 | 300 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
+ 'top element' | '/openroadm-devices' || 2.5 | 400 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
+ 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 2.5 | 400 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 2.5 | 400 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
+ 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 2.5 | 400 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
+ 'non-existing data' | '/path/to/non-existing/node[@id="1"]' || 0.1 | 1 | 0
}
def 'Query complete data trees across all anchors with #scenario.'() {
@@ -63,11 +64,10 @@ class QueryPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Query across anchors ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following parameters are used'
scenario | cpspath || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'top element' | '/openroadm-devices' || 6 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
- 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 6 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE)
- 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 6 | 800 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
- 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 6 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
- 'non-existing data' | '/path/to/non-existing/node[@id="1"]' || 0.1 | 3 | 0
+ 'top element' | '/openroadm-devices' || 7 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
+ 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || 7 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE)
+ 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || 7 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
+ 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || 7 | 600 | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
}
def 'Query with leaf condition and #scenario.'() {
@@ -82,9 +82,9 @@ class QueryPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Query with ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following parameters are used'
scenario | fetchDescendantsOption || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'no descendants' | OMIT_DESCENDANTS || 0.1 | 30 | OPENROADM_DEVICES_PER_ANCHOR
- 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.15 | 30 | OPENROADM_DEVICES_PER_ANCHOR * 2
- 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2 | 200 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'no descendants' | OMIT_DESCENDANTS || 0.1 | 6 | OPENROADM_DEVICES_PER_ANCHOR
+ 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.2 | 12 | OPENROADM_DEVICES_PER_ANCHOR * 2
+ 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2.5 | 200 | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
}
def 'Query ancestors with #scenario.'() {
@@ -99,9 +99,9 @@ class QueryPerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Query ancestors with ${scenario}", durationLimit, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
where: 'the following parameters are used'
scenario | fetchDescendantsOption || durationLimit | memoryLimit | expectedNumberOfDataNodes
- 'no descendants' | OMIT_DESCENDANTS || 0.1 | 20 | 1
- 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.1 | 20 | 1 + OPENROADM_DEVICES_PER_ANCHOR
- 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2 | 200 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
+ 'no descendants' | OMIT_DESCENDANTS || 0.1 | 3 | 1
+ 'direct descendants' | DIRECT_CHILDREN_ONLY || 0.2 | 8 | 1 + OPENROADM_DEVICES_PER_ANCHOR
+ 'all descendants' | INCLUDE_ALL_DESCENDANTS || 2.5 | 400 | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
}
}
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 151492dc9..8118010b4 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
@@ -41,7 +41,7 @@ class UpdatePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def updateDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'update completes within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Update 1 data node', 0.6, updateDurationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Update 1 data node', 0.6, updateDurationInSeconds, 100, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch update 100 data nodes with descendants'() {
@@ -57,7 +57,7 @@ class UpdatePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def updateDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'update completes within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Update 100 data nodes', 30, updateDurationInSeconds, 800, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Update 100 data nodes', 40, updateDurationInSeconds, 800, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Update leaves for 1 data node (twice)'() {
@@ -71,7 +71,7 @@ class UpdatePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def updateDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'update completes within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Update leaves for 1 data node', 0.5, updateDurationInSeconds, 300, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Update leaves for 1 data node', 0.7, updateDurationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Batch update leaves for 100 data nodes (twice)'() {
@@ -85,7 +85,7 @@ class UpdatePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def updateDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'update completes within expected time and memory used is within limit'
- recordAndAssertResourceUsage('Batch update leaves for 100 data nodes', 1, updateDurationInSeconds, 300, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage('Batch update leaves for 100 data nodes', 1, updateDurationInSeconds, 200, resourceMeter.getTotalMemoryUsageInMB())
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
index 177cd9fc5..0c7107a56 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
@@ -36,19 +36,16 @@ class WritePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'the operation takes less than #expectedDuration and memory used is within limit'
- recordAndAssertResourceUsage("Writing ${totalNodes} devices", expectedDurationInSeconds, durationInSeconds, 400, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Writing ${totalNodes} devices", expectedDuration, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
cleanup:
cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor', OffsetDateTime.now())
cpsAdminService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
where:
- totalNodes || expectedDurationInSeconds
- 50 || 3
- 100 || 5
- 200 || 10
- 400 || 20
-// 800 || 40
-// 1600 || 80
-// 3200 || 160
+ totalNodes || expectedDuration | memoryLimit
+ 50 || 4 | 100
+ 100 || 7 | 200
+ 200 || 14 | 400
+ 400 || 28 | 500
}
def 'Writing bookstore data has exponential time.'() {
@@ -64,20 +61,16 @@ class WritePerfTest extends CpsPerfTestBase {
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'the operation takes less than #expectedDuration and memory used is within limit'
- recordAndAssertResourceUsage("Writing ${totalBooks} books", expectedDuration, durationInSeconds, 400, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Writing ${totalBooks} books", expectedDuration, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
cleanup:
cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor', OffsetDateTime.now())
cpsAdminService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
where:
- totalBooks || expectedDuration
- 400 || 0.2
- 800 || 0.5
- 1600 || 1
- 3200 || 3
- 6400 || 10
-// 12800 || 30
-// 25600 || 120
-// 51200 || 600
+ totalBooks || expectedDuration | memoryLimit
+ 800 || 1 | 50
+ 1600 || 2 | 100
+ 3200 || 6 | 150
+ 6400 || 18 | 200
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmDataSubscriptionsPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmDataSubscriptionsPerfTest.groovy
index 896217a2a..579394be8 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmDataSubscriptionsPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/ncmp/CmDataSubscriptionsPerfTest.groovy
@@ -52,7 +52,7 @@ class CmDataSubscriptionsPerfTest extends NcmpPerfTestBase {
matches.size() == numberOfFiltersPerCmHandle * numberOfCmHandlesPerCmDataSubscription
and: 'query all subscribers within 1 second'
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
- recordAndAssertResourceUsage("Query all subscribers", 1, durationInSeconds, 400, resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Query all subscribers", 1.2, durationInSeconds, 300, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Worst case subscription update (200x10 matching entries).'() {
@@ -94,8 +94,8 @@ class CmDataSubscriptionsPerfTest extends NcmpPerfTestBase {
then: 'a subscriber has been added to each filter entry'
def resultAfter = objectUnderTest.queryDataNodes(NCMP_PERFORMANCE_TEST_DATASPACE, CM_DATA_SUBSCRIPTIONS_ANCHOR, cpsPath, INCLUDE_ALL_DESCENDANTS)
assert resultAfter.collect {it.leaves.subscribers.size()}.sum() == totalNumberOfEntries * (1 + numberOfCmDataSubscribers)
- and: 'update matching subscription within 8 seconds'
- recordAndAssertResourceUsage("Update matching subscription", 8, durationInSeconds, 400, resourceMeter.getTotalMemoryUsageInMB())
+ and: 'update matching subscription within 15 seconds'
+ recordAndAssertResourceUsage("Update matching subscription", 15, durationInSeconds, 1000, resourceMeter.getTotalMemoryUsageInMB())
}
def 'Worst case new subscription (200x10 new entries).'() {
@@ -109,7 +109,7 @@ class CmDataSubscriptionsPerfTest extends NcmpPerfTestBase {
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'insert new subscription with 1 second'
- recordAndAssertResourceUsage("Insert new subscription", 1, durationInSeconds, 400,resourceMeter.getTotalMemoryUsageInMB())
+ recordAndAssertResourceUsage("Insert new subscription", 2, durationInSeconds, 100, resourceMeter.getTotalMemoryUsageInMB())
}
def querySubscriptionsByIteration(Collection<DataNode> allSubscriptionsAsDataNodes, targetSubscriptionSequenceNumber) {
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 becd7e39c..a5a6acb7a 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
@@ -45,8 +45,8 @@ class CmHandleQueryPerfTest extends NcmpPerfTestBase {
def result = cpsDataService.getDataNodesForMultipleXpaths(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, xpaths, INCLUDE_ALL_DESCENDANTS)
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
- then: 'the required operations are performed within 1200 ms'
- recordAndAssertResourceUsage("CpsPath Registry attributes Query", 0.25, durationInSeconds, 150, resourceMeter.getTotalMemoryUsageInMB())
+ then: 'the required operations are performed within required time'
+ recordAndAssertResourceUsage("CpsPath Registry attributes Query", 0.4, durationInSeconds, 50, resourceMeter.getTotalMemoryUsageInMB())
and: 'all but 1 (other node) are returned'
result.size() == 999
and: 'the tree contains all the expected descendants too'
diff --git a/integration-test/src/test/java/org/onap/cps/integration/ResourceMeter.java b/integration-test/src/test/java/org/onap/cps/integration/ResourceMeter.java
index 1e420013d..f8a2ecb4d 100644
--- a/integration-test/src/test/java/org/onap/cps/integration/ResourceMeter.java
+++ b/integration-test/src/test/java/org/onap/cps/integration/ResourceMeter.java
@@ -20,6 +20,10 @@
package org.onap.cps.integration;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
import org.springframework.util.StopWatch;
/**
@@ -34,8 +38,9 @@ public class ResourceMeter {
* Start measurement.
*/
public void start() {
- System.gc();
- memoryUsedBefore = getCurrentMemoryUsage();
+ performGcAndWait();
+ resetPeakHeapUsage();
+ memoryUsedBefore = getPeakHeapUsage();
stopWatch.start();
}
@@ -44,12 +49,12 @@ public class ResourceMeter {
*/
public void stop() {
stopWatch.stop();
- memoryUsedAfter = getCurrentMemoryUsage();
+ memoryUsedAfter = getPeakHeapUsage();
}
/**
- * Get the total time in milliseconds.
- * @return total time in milliseconds
+ * Get the total time in seconds.
+ * @return total time in seconds
*/
public double getTotalTimeInSeconds() {
return stopWatch.getTotalTimeSeconds();
@@ -63,8 +68,30 @@ public class ResourceMeter {
return (memoryUsedAfter - memoryUsedBefore) / 1_000_000.0;
}
- private static long getCurrentMemoryUsage() {
- return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+ static void performGcAndWait() {
+ final long gcCountBefore = getGcCount();
+ System.gc();
+ while (getGcCount() == gcCountBefore) {}
+ }
+
+ private static long getGcCount() {
+ return ManagementFactory.getGarbageCollectorMXBeans().stream()
+ .mapToLong(GarbageCollectorMXBean::getCollectionCount)
+ .filter(gcCount -> gcCount != -1)
+ .sum();
+ }
+
+ private static long getPeakHeapUsage() {
+ return ManagementFactory.getMemoryPoolMXBeans().stream()
+ .filter(pool -> pool.getType() == MemoryType.HEAP)
+ .mapToLong(pool -> pool.getPeakUsage().getUsed())
+ .sum();
+ }
+
+ private static void resetPeakHeapUsage() {
+ ManagementFactory.getMemoryPoolMXBeans().stream()
+ .filter(pool -> pool.getType() == MemoryType.HEAP)
+ .forEach(MemoryPoolMXBean::resetPeakUsage);
}
}
diff --git a/integration-test/src/test/resources/data/bookstore/bookstore.yang b/integration-test/src/test/resources/data/bookstore/bookstore.yang
index 6f60f1981..9c6c42e28 100644
--- a/integration-test/src/test/resources/data/bookstore/bookstore.yang
+++ b/integration-test/src/test/resources/data/bookstore/bookstore.yang
@@ -49,6 +49,17 @@ module stores {
}
}
+ container support-info {
+ leaf support-office {
+ type string;
+ }
+ container contact-emails {
+ leaf email {
+ type string;
+ }
+ }
+ }
+
container container-without-leaves { }
container premises {
diff --git a/integration-test/src/test/resources/data/bookstore/bookstoreDataForDeltaReport.json b/integration-test/src/test/resources/data/bookstore/bookstoreDataForDeltaReport.json
new file mode 100644
index 000000000..73b84fc98
--- /dev/null
+++ b/integration-test/src/test/resources/data/bookstore/bookstoreDataForDeltaReport.json
@@ -0,0 +1,192 @@
+{
+ "bookstore-address": [
+ {
+ "bookstore-name": "Crossword Bookstores",
+ "address": "Bangalore, India",
+ "postal-code": "560062"
+ }
+ ],
+ "bookstore": {
+ "bookstore-name": "Easons",
+ "premises": {
+ "addresses": [
+ {
+ "house-number": 2,
+ "street": "Main Street",
+ "town": "Killarney",
+ "county": "Kerry"
+ },
+ {
+ "house-number": 24,
+ "street": "Grafton Street",
+ "town": "Dublin",
+ "county": "Dublin"
+ }
+ ]
+ },
+ "support-info": {
+ "contact-emails": {
+ }
+ },
+ "container-without-leaves": { },
+ "categories": [
+ {
+ "code": 1,
+ "name": "Kids",
+ "books" : [
+ {
+ "title": "Matilda",
+ "lang": "English",
+ "authors": ["Roald Dahl"],
+ "editions": [1988, 2000, 2023],
+ "price": 200
+ },
+ {
+ "title": "The Gruffalo",
+ "lang": "English/German",
+ "authors": ["Julia Donaldson"],
+ "editions": [1999],
+ "price": 15
+ }
+ ]
+ },
+ {
+ "code": 2,
+ "name": "Suspense"
+ },
+ {
+ "code": 3,
+ "name": "Comedy",
+ "books" : [
+ {
+ "title": "Good Omens",
+ "lang": "English",
+ "authors": ["Neil Gaiman", "Terry Pratchett"],
+ "editions": [2006],
+ "price": 13
+ },
+ {
+ "title": "The Colour of Magic",
+ "lang": "English",
+ "authors": ["Terry Pratchett"],
+ "editions": [1983],
+ "price": 12
+ },
+ {
+ "title": "The Light Fantastic",
+ "lang": "English",
+ "authors": ["Terry Pratchett"],
+ "editions": [1986],
+ "price": 14
+ },
+ {
+ "title": "A Book with No Language",
+ "lang": "",
+ "authors": ["Joe Bloggs"],
+ "editions": [2023],
+ "price": 20
+ }
+ ]
+ },
+ {
+ "code": 5,
+ "name": "Discount books",
+ "books" : [
+ {
+ "title": "Book 1",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 1
+ },
+ {
+ "title": "Book 2",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 2
+ },
+ {
+ "title": "Book 3",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 3
+ },
+ {
+ "title": "Book 4",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 4
+ },
+ {
+ "title": "Book 5",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 5
+ },
+ {
+ "title": "Book 6",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 6
+ },
+ {
+ "title": "Book 7",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 7
+ },
+ {
+ "title": "Book 8",
+ "lang": "blahh",
+ "authors": [],
+ "editions": [],
+ "price": 8
+ },
+ {
+ "title": "Book 9",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 9
+ },
+ {
+ "title": "Book 10",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 10
+ },
+ {
+ "title": "Book 11",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 10
+ }
+ ]
+ },
+ {
+ "code": 6,
+ "name": "Random books",
+ "books": [
+ {
+ "title": "Book 1",
+ "lang": "blah",
+ "authors": [],
+ "editions": [],
+ "price": 1
+ }
+ ]
+ },
+ {
+ "code": 7
+ }
+ ]
+ }
+}