summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToineSiebelink <toine.siebelink@est.tech>2022-12-12 17:39:26 +0000
committerToineSiebelink <toine.siebelink@est.tech>2022-12-12 18:15:51 +0000
commitaec2a44c3ad4e9206300fd3494dbd542437678b3 (patch)
tree71102a28c3aec3250c6ed68050ea68f10078fcad
parentc88883a6fcd629669efe490dc43cf5764d5ab00c (diff)
Query Optimization
- Refactor performance tests as multiple separate (data driven) tests - This to improve redability and re-use and amke sure al tets are always ran (makign it easier to test/change thresholds for multiple scenarios at once) - Add new query performance tests (on many descendants) Issue-ID: CPS-475 Signed-off-by: ToineSiebelink <toine.siebelink@est.tech> Change-Id: If5703fcb9e2233ded64d31d2342de2e7f5549687
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy75
1 files changed, 49 insertions, 26 deletions
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
index 387fc1f857..b26cef4de7 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
@@ -27,7 +27,11 @@ import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.jdbc.Sql
+
+import java.util.concurrent.TimeUnit
+
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
class CpsToDataNodePerfTest extends CpsPersistenceSpecBase {
@@ -36,66 +40,85 @@ class CpsToDataNodePerfTest extends CpsPersistenceSpecBase {
@Autowired
CpsDataPersistenceService objectUnderTest
- def PERF_TEST_PARENT = '/perf-parent-1'
+ static def PERF_TEST_PARENT = '/perf-parent-1'
+ static def NUMBER_OF_CHILDREN = 200
+ static def NUMBER_OF_GRAND_CHILDREN = 50
+ static def TOTAL_NUMBER_OF_NODES = 1 + NUMBER_OF_CHILDREN + (NUMBER_OF_CHILDREN * NUMBER_OF_GRAND_CHILDREN) // Parent + Children + Grand-children
+ static def ALLOWED_SETUP_TIME_MS = TimeUnit.SECONDS.toMillis(10)
+ static def ALLOWED_READ_TIME_AL_NODES_MS = 500
- def EXPECTED_NUMBER_OF_NODES = 10051 // 1 Parent + 50 Children + 10000 Grand-children
+ def readStopWatch = new StopWatch()
@Sql([CLEAR_DATA, PERF_TEST_DATA])
- def 'Get data node by xpath with all descendants with many children'() {
- given: 'nodes and grandchildren have been persisted'
+ def 'Create a node with many descendants (please note, subsequent tests depend on this running first).'() {
+ given: 'a node with a large number of descendants is created'
def setupStopWatch = new StopWatch()
setupStopWatch.start()
createLineage()
setupStopWatch.stop()
def setupDurationInMillis = setupStopWatch.getTime()
- and: 'setup duration is under 10000 milliseconds'
- assert setupDurationInMillis < 10000
+ and: 'setup duration is under #ALLOWED_SETUP_TIME_MS milliseconds'
+ assert setupDurationInMillis < ALLOWED_SETUP_TIME_MS
+ }
+
+ def 'Get data node with many descendants by xpath #scenario'() {
when: 'get parent is executed with all descendants'
- def readStopWatch = new StopWatch()
readStopWatch.start()
- def result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', PERF_TEST_PARENT, INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', xpath, INCLUDE_ALL_DESCENDANTS)
readStopWatch.stop()
def readDurationInMillis = readStopWatch.getTime()
then: 'read duration is under 500 milliseconds'
- assert readDurationInMillis < 500
+ assert readDurationInMillis < ALLOWED_READ_TIME_AL_NODES_MS
and: 'data node is returned with all the descendants populated'
- assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
- when: 'get root is executed with all descendants'
+ assert countDataNodes(result) == TOTAL_NUMBER_OF_NODES
+ where: 'the following xPaths are used'
+ scenario || xpath
+ 'parent' || PERF_TEST_PARENT
+ 'root' || ''
+ }
+
+ def 'Query parent data node with many descendants by cps-path'() {
+ when: 'query is executed with all descendants'
readStopWatch.reset()
readStopWatch.start()
- result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', '', INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-parent-1' , INCLUDE_ALL_DESCENDANTS)
readStopWatch.stop()
- readDurationInMillis = readStopWatch.getTime()
+ def readDurationInMillis = readStopWatch.getTime()
then: 'read duration is under 500 milliseconds'
- assert readDurationInMillis < 500
+ assert readDurationInMillis < ALLOWED_READ_TIME_AL_NODES_MS
and: 'data node is returned with all the descendants populated'
- assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
+ assert countDataNodes(result) == TOTAL_NUMBER_OF_NODES
+ }
+
+ def 'Query many descendants by cps-path with #scenario'() {
when: 'query is executed with all descendants'
readStopWatch.reset()
readStopWatch.start()
- result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-parent-1', INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-test-grand-child-1', descendantsOption)
readStopWatch.stop()
- readDurationInMillis = readStopWatch.getTime()
+ def readDurationInMillis = readStopWatch.getTime()
then: 'read duration is under 500 milliseconds'
- assert readDurationInMillis < 500
+ assert readDurationInMillis < alowedDuration
and: 'data node is returned with all the descendants populated'
- assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
+ assert result.size() == NUMBER_OF_CHILDREN
+ where: 'the following options are used'
+ scenario | descendantsOption || alowedDuration
+ 'omit descendants ' | OMIT_DESCENDANTS || 150
+ 'include descendants (although there are none)' | INCLUDE_ALL_DESCENDANTS || 1500
}
def createLineage() {
- def numOfChildren = 50
- def numOfGrandChildren = 200
- (1..numOfChildren).each {
+ (1..NUMBER_OF_CHILDREN).each {
def childName = "perf-test-child-${it}".toString()
- def newChild = goForthAndMultiply(PERF_TEST_PARENT, childName, numOfGrandChildren)
+ def newChild = goForthAndMultiply(PERF_TEST_PARENT, childName)
objectUnderTest.addChildDataNode('PERF-DATASPACE', 'PERF-ANCHOR', PERF_TEST_PARENT, newChild)
}
}
- def goForthAndMultiply(parentXpath, childName, numOfGrandChildren) {
+ def goForthAndMultiply(parentXpath, childName) {
def children = []
- (1..numOfGrandChildren).each {
- def child = new DataNodeBuilder().withXpath("${parentXpath}/${childName}/${it}perf-test-grand-child").build()
+ (1..NUMBER_OF_GRAND_CHILDREN).each {
+ def child = new DataNodeBuilder().withXpath("${parentXpath}/${childName}/perf-test-grand-child-${it}").build()
children.add(child)
}
return new DataNodeBuilder().withXpath("${parentXpath}/${childName}").withChildDataNodes(children).build()