2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2023 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the 'License');
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an 'AS IS' BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.integration.performance.cps
23 import org.onap.cps.api.CpsQueryService
24 import org.onap.cps.integration.performance.base.CpsPerfTestBase
25 import org.onap.cps.spi.PaginationOption
27 import java.util.concurrent.TimeUnit
29 import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
30 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
31 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
33 class QueryPerfTest extends CpsPerfTestBase {
35 CpsQueryService objectUnderTest
37 def setup() { objectUnderTest = cpsQueryService }
39 def 'Query complete data trees with #scenario.'() {
40 when: 'query data nodes (using a fresh anchor with identical data for each test)'
42 def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm1', cpsPath, INCLUDE_ALL_DESCENDANTS)
44 def durationInMillis = stopWatch.getTotalTimeMillis()
45 then: 'the expected number of nodes is returned'
46 assert countDataNodesInTree(result) == expectedNumberOfDataNodes
47 and: 'all data is read within #durationLimit ms'
48 recordAndAssertPerformance("Query 1 anchor ${scenario}", durationLimit, durationInMillis)
49 where: 'the following parameters are used'
50 scenario | cpsPath || durationLimit | expectedNumberOfDataNodes
51 'top element' | '/openroadm-devices' || TimeUnit.SECONDS.toMillis(2) | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
52 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || TimeUnit.SECONDS.toMillis(3) | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
53 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || TimeUnit.SECONDS.toMillis(2) | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
54 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || TimeUnit.SECONDS.toMillis(2) | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1
55 'non-existing data' | '/path/to/non-existing/node[@id="1"]' || 100 | 0
58 def 'Query complete data trees across all anchors with #scenario.'() {
59 when: 'query data nodes across all anchors'
61 def result = objectUnderTest.queryDataNodesAcrossAnchors(CPS_PERFORMANCE_TEST_DATASPACE, cpspath, INCLUDE_ALL_DESCENDANTS, PaginationOption.NO_PAGINATION)
63 def durationInMillis = stopWatch.getTotalTimeMillis()
64 then: 'the expected number of nodes is returned'
65 assert countDataNodesInTree(result) == expectedNumberOfDataNodes
66 and: 'all data is read within #durationLimit ms'
67 recordAndAssertPerformance("Query across anchors ${scenario}", durationLimit, durationInMillis)
68 where: 'the following parameters are used'
69 scenario | cpspath || durationLimit | expectedNumberOfDataNodes
70 'top element' | '/openroadm-devices' || TimeUnit.SECONDS.toMillis(6) | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
71 'leaf condition' | '//openroadm-device[@ne-state="inservice"]' || TimeUnit.SECONDS.toMillis(6) | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE)
72 'ancestors' | '//openroadm-device/ancestor::openroadm-devices' || TimeUnit.SECONDS.toMillis(6) | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
73 'leaf condition + ancestors' | '//openroadm-device[@status="success"]/ancestor::openroadm-devices' || TimeUnit.SECONDS.toMillis(6) | OPENROADM_ANCHORS * (OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE + 1)
74 'non-existing data' | '/path/to/non-existing/node[@id="1"]' || 100 | 0
77 def 'Query with leaf condition and #scenario.'() {
78 when: 'query data nodes (using a fresh anchor with identical data for each test)'
80 def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm2', '//openroadm-device[@status="success"]', fetchDescendantsOption)
82 def durationInMillis = stopWatch.getTotalTimeMillis()
83 then: 'the expected number of nodes is returned'
84 assert countDataNodesInTree(result) == expectedNumberOfDataNodes
85 and: 'all data is read within #durationLimit ms'
86 recordAndAssertPerformance("Query with ${scenario}", durationLimit, durationInMillis)
87 where: 'the following parameters are used'
88 scenario | fetchDescendantsOption || durationLimit | expectedNumberOfDataNodes
89 'no descendants' | OMIT_DESCENDANTS || 100 | OPENROADM_DEVICES_PER_ANCHOR
90 'direct descendants' | DIRECT_CHILDREN_ONLY || 150 | OPENROADM_DEVICES_PER_ANCHOR * 2
91 'all descendants' | INCLUDE_ALL_DESCENDANTS || TimeUnit.SECONDS.toMillis(2) | OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE
94 def 'Query ancestors with #scenario.'() {
95 when: 'query data nodes (using a fresh anchor with identical data for each test)'
97 def result = objectUnderTest.queryDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm3', '//openroadm-device[@ne-state="inservice"]/ancestor::openroadm-devices', fetchDescendantsOption)
99 def durationInMillis = stopWatch.getTotalTimeMillis()
100 then: 'the expected number of nodes is returned'
101 assert countDataNodesInTree(result) == expectedNumberOfDataNodes
102 and: 'all data is read within #durationLimit ms'
103 recordAndAssertPerformance("Query ancestors with ${scenario}", durationLimit, durationInMillis)
104 where: 'the following parameters are used'
105 scenario | fetchDescendantsOption || durationLimit | expectedNumberOfDataNodes
106 'no descendants' | OMIT_DESCENDANTS || 100 | 1
107 'direct descendants' | DIRECT_CHILDREN_ONLY || 100 | 1 + OPENROADM_DEVICES_PER_ANCHOR
108 'all descendants' | INCLUDE_ALL_DESCENDANTS || TimeUnit.SECONDS.toMillis(2) | 1 + OPENROADM_DEVICES_PER_ANCHOR * OPENROADM_DATANODES_PER_DEVICE