Introduce Instrumentation
[cps.git] / cps-ri / src / test / groovy / org / onap / cps / spi / performance / CpsDataPersistenceServiceDeletePerfTest.groovy
1 /*
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.spi.performance
22
23 import org.onap.cps.spi.CpsDataPersistenceService
24 import org.onap.cps.spi.impl.CpsPersistencePerfSpecBase
25 import org.springframework.beans.factory.annotation.Autowired
26 import org.springframework.test.context.jdbc.Sql
27 import org.springframework.util.StopWatch
28 import spock.lang.Shared
29
30 import java.util.concurrent.TimeUnit
31
32 class CpsDataPersistenceServiceDeletePerfTest extends CpsPersistencePerfSpecBase {
33
34     @Autowired
35     CpsDataPersistenceService objectUnderTest
36
37     static def NUMBER_OF_CHILDREN = 100
38     static def NUMBER_OF_GRAND_CHILDREN = 50
39     static def NUMBER_OF_LISTS = 100
40     static def NUMBER_OF_LIST_ELEMENTS = 50
41     static def ALLOWED_SETUP_TIME_MS = TimeUnit.SECONDS.toMillis(10)
42
43     def stopWatch = new StopWatch()
44
45     @Sql([CLEAR_DATA, PERF_TEST_DATA])
46     def 'Create a node with many descendants (please note, subsequent tests depend on this running first).'() {
47         when: 'a node with a large number of descendants is created'
48             stopWatch.start()
49             createLineage(objectUnderTest, NUMBER_OF_CHILDREN, NUMBER_OF_GRAND_CHILDREN, false)
50             stopWatch.stop()
51             def setupDurationInMillis = stopWatch.getTotalTimeMillis()
52         then: 'setup duration is under #ALLOWED_SETUP_TIME_MS milliseconds'
53             recordAndAssertPerformance('Setup',ALLOWED_SETUP_TIME_MS, setupDurationInMillis)
54     }
55
56     def 'Delete 5 children with grandchildren'() {
57         when: 'child nodes are deleted'
58             stopWatch.start()
59             (1..5).each {
60                 def childPath = "${PERF_TEST_PARENT}/perf-test-child-${it}".toString();
61                 objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, childPath)
62             }
63             stopWatch.stop()
64             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
65         then: 'delete duration is under 300 milliseconds'
66             recordAndAssertPerformance('Delete 5 children', 300, deleteDurationInMillis)
67     }
68
69     def 'Delete 50 grandchildren (that have no descendants)'() {
70         when: 'target nodes are deleted'
71             stopWatch.start()
72             (1..50).each {
73                 def grandchildPath = "${PERF_TEST_PARENT}/perf-test-child-6/perf-test-grand-child-${it}".toString();
74                 objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, grandchildPath)
75             }
76             stopWatch.stop()
77             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
78         then: 'delete duration is under 350 milliseconds'
79             recordAndAssertPerformance('Delete 50 grandchildren', 350, deleteDurationInMillis)
80     }
81
82     def 'Delete 1 large data node with many descendants'() {
83         when: 'parent node is deleted'
84             stopWatch.start()
85             objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, PERF_TEST_PARENT)
86             stopWatch.stop()
87             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
88         then: 'delete duration is under 250 milliseconds'
89             recordAndAssertPerformance('Delete one large node', 250, deleteDurationInMillis)
90     }
91
92     @Sql([CLEAR_DATA, PERF_TEST_DATA])
93     def 'Create a node with many list elements (please note, subsequent tests depend on this running first).'() {
94         given: 'a node with a large number of descendants is created'
95             stopWatch.start()
96             createLineage(objectUnderTest, NUMBER_OF_LISTS, NUMBER_OF_LIST_ELEMENTS, true)
97             stopWatch.stop()
98             def setupDurationInMillis = stopWatch.getTotalTimeMillis()
99         and: 'setup duration is under #ALLOWED_SETUP_TIME_MS milliseconds'
100             recordAndAssertPerformance('Create node with many list elements', ALLOWED_SETUP_TIME_MS, setupDurationInMillis)
101     }
102
103     def 'Delete 5 whole lists with many elements'() {
104         when: 'list nodes are deleted'
105             stopWatch.start()
106             (1..5).each {
107                 def childPath = "${PERF_TEST_PARENT}/perf-test-list-${it}".toString();
108                 objectUnderTest.deleteListDataNode(PERF_DATASPACE, PERF_ANCHOR, childPath)
109             }
110             stopWatch.stop()
111             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
112         then: 'delete duration is under 1000 milliseconds'
113             recordAndAssertPerformance('Delete 5 whole lists', 1500, deleteDurationInMillis)
114     }
115
116     def 'Delete 10 list elements with keys'() {
117         when: 'list elements are deleted'
118             stopWatch.start()
119             (1..10).each {
120                 def key = it.toString()
121                 def grandchildPath = "${PERF_TEST_PARENT}/perf-test-list-6[@key='${key}']"
122                 objectUnderTest.deleteListDataNode(PERF_DATASPACE, PERF_ANCHOR, grandchildPath)
123             }
124             stopWatch.stop()
125             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
126         then: 'delete duration is under 1200 milliseconds'
127             recordAndAssertPerformance('Delete 10 lists elements', 1500, deleteDurationInMillis)
128     }
129
130     @Sql([CLEAR_DATA, PERF_TEST_DATA])
131     def 'Delete root node with many descendants'() {
132         given: 'a node with a large number of descendants is created'
133             createLineage(objectUnderTest, NUMBER_OF_CHILDREN, NUMBER_OF_GRAND_CHILDREN, false)
134         when: 'root node is deleted'
135             stopWatch.start()
136             objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, '/')
137             stopWatch.stop()
138             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
139         then: 'delete duration is under 250 milliseconds'
140             recordAndAssertPerformance('Delete root node', 250, deleteDurationInMillis)
141     }
142
143     @Sql([CLEAR_DATA, PERF_TEST_DATA])
144     def 'Delete data nodes for an anchor'() {
145         given: 'a node with a large number of descendants is created'
146             createLineage(objectUnderTest, NUMBER_OF_CHILDREN, NUMBER_OF_GRAND_CHILDREN, false)
147         when: 'data nodes are deleted'
148             stopWatch.start()
149             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR)
150             stopWatch.stop()
151             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
152         then: 'delete duration is under 250 milliseconds'
153             recordAndAssertPerformance('Delete data nodes for anchor', 250, deleteDurationInMillis)
154     }
155
156 }