Create Base and Sample Performance Integration Tests
[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
28 class CpsDataPersistenceServiceDeletePerfTest extends CpsPersistencePerfSpecBase {
29
30     @Autowired
31     CpsDataPersistenceService objectUnderTest
32
33     @Sql([CLEAR_DATA, PERF_TEST_DATA])
34     def 'Create a node with many descendants (please note, subsequent tests depend on this running first).'() {
35         when: 'a node with a large number of descendants is created'
36             stopWatch.start()
37             createLineage(objectUnderTest, 150, 50, false)
38             stopWatch.stop()
39             def setupDurationInMillis = stopWatch.getTotalTimeMillis()
40         then: 'setup duration is under 10 seconds'
41             recordAndAssertPerformance('Setup', 10_000, setupDurationInMillis)
42     }
43
44     def 'Delete 5 children with grandchildren'() {
45         when: 'child nodes are deleted'
46             stopWatch.start()
47             (1..5).each {
48                 def childPath = "${PERF_TEST_PARENT}/perf-test-child-${it}".toString()
49                 objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, childPath)
50             }
51             stopWatch.stop()
52             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
53         then: 'delete duration is under 400 milliseconds'
54             recordAndAssertPerformance('Delete 5 children', 400, deleteDurationInMillis)
55     }
56
57     def 'Batch delete 100 children with grandchildren'() {
58         given: 'a list of xpaths to delete'
59             def xpathsToDelete = (6..105).collect {
60                 "${PERF_TEST_PARENT}/perf-test-child-${it}".toString()
61             }
62         when: 'child nodes are deleted'
63             stopWatch.start()
64             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR, xpathsToDelete)
65             stopWatch.stop()
66             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
67         then: 'delete duration is under 250 milliseconds'
68             recordAndAssertPerformance('Batch delete 100 children', 250, deleteDurationInMillis)
69     }
70
71     def 'Delete 50 grandchildren (that have no descendants)'() {
72         when: 'target nodes are deleted'
73             stopWatch.start()
74             (1..50).each {
75                 def grandchildPath = "${PERF_TEST_PARENT}/perf-test-child-106/perf-test-grand-child-${it}".toString()
76                 objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, grandchildPath)
77             }
78             stopWatch.stop()
79             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
80         then: 'delete duration is under 400 milliseconds'
81             recordAndAssertPerformance('Delete 50 grandchildren', 400, deleteDurationInMillis)
82     }
83
84     def 'Batch delete 500 grandchildren (that have no descendants)'() {
85         given: 'a list of xpaths to delete'
86             def xpathsToDelete = []
87             for (int childIndex = 0; childIndex < 10; childIndex++) {
88                 xpathsToDelete.addAll((1..50).collect {
89                     "${PERF_TEST_PARENT}/perf-test-child-${107+childIndex}/perf-test-grand-child-${it}".toString()
90                 })
91             }
92         when: 'target nodes are deleted'
93             stopWatch.start()
94             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR, xpathsToDelete)
95             stopWatch.stop()
96             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
97         then: 'delete duration is under 100 milliseconds'
98             recordAndAssertPerformance('Batch delete 500 grandchildren', 100, deleteDurationInMillis)
99     }
100
101     @Sql([CLEAR_DATA, PERF_TEST_DATA])
102     def 'Create a node with many list elements (please note, subsequent tests depend on this running first).'() {
103         when: 'a node with a large number of lists is created'
104             stopWatch.start()
105             createLineage(objectUnderTest, 150, 50, true)
106             stopWatch.stop()
107             def setupDurationInMillis = stopWatch.getTotalTimeMillis()
108         then: 'setup duration is under 6 seconds'
109             recordAndAssertPerformance('Setup lists', 6_000, setupDurationInMillis)
110     }
111
112     def 'Delete 5 whole lists'() {
113         when: 'lists are deleted'
114             stopWatch.start()
115             (1..5).each {
116                 def childPath = "${PERF_TEST_PARENT}/perf-test-list-${it}".toString()
117                 objectUnderTest.deleteListDataNode(PERF_DATASPACE, PERF_ANCHOR, childPath)
118             }
119             stopWatch.stop()
120             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
121         then: 'delete duration is under 2 seconds'
122             recordAndAssertPerformance('Delete 5 whole lists', 2_000, deleteDurationInMillis)
123     }
124
125     def 'Batch delete 100 whole lists'() {
126         given: 'a list of xpaths to delete'
127             def xpathsToDelete = (6..105).collect {
128                 "${PERF_TEST_PARENT}/perf-test-list-${it}".toString()
129             }
130         when: 'lists are deleted'
131             stopWatch.start()
132             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR, xpathsToDelete)
133             stopWatch.stop()
134             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
135         then: 'delete duration is under 600 milliseconds'
136             recordAndAssertPerformance('Batch delete 100 whole lists', 600, deleteDurationInMillis)
137     }
138
139     def 'Delete 10 list elements'() {
140         when: 'list elements are deleted'
141             stopWatch.start()
142             (1..10).each {
143                 def grandchildPath = "${PERF_TEST_PARENT}/perf-test-list-106[@key='${it}']".toString()
144                 objectUnderTest.deleteListDataNode(PERF_DATASPACE, PERF_ANCHOR, grandchildPath)
145             }
146             stopWatch.stop()
147             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
148         then: 'delete duration is under 700 milliseconds'
149             recordAndAssertPerformance('Delete 10 lists elements', 700, deleteDurationInMillis)
150     }
151
152     def 'Batch delete 500 list elements'() {
153         given: 'a list of xpaths to delete'
154             def xpathsToDelete = []
155             for (int childIndex = 0; childIndex < 10; childIndex++) {
156                 xpathsToDelete.addAll((1..50).collect {
157                     "${PERF_TEST_PARENT}/perf-test-list-${107+childIndex}[@key='${it}']".toString()
158                 })
159             }
160         when: 'list elements are deleted'
161             stopWatch.start()
162             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR, xpathsToDelete)
163             stopWatch.stop()
164             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
165         then: 'delete duration is under 70 milliseconds'
166             recordAndAssertPerformance('Batch delete 500 lists elements', 70, deleteDurationInMillis)
167     }
168
169     @Sql([CLEAR_DATA, PERF_TEST_DATA])
170     def 'Delete 1 large data node'() {
171         given: 'a node with a large number of descendants is created'
172             createLineage(objectUnderTest, 50, 50, false)
173             createLineage(objectUnderTest, 50, 50, true)
174         when: 'parent node is deleted'
175             stopWatch.start()
176             objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, PERF_TEST_PARENT)
177             stopWatch.stop()
178             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
179         then: 'delete duration is under 400 milliseconds'
180             recordAndAssertPerformance('Delete one large node', 400, deleteDurationInMillis)
181     }
182
183     @Sql([CLEAR_DATA, PERF_TEST_DATA])
184     def 'Batch delete 1 large data node'() {
185         given: 'a node with a large number of descendants is created'
186             createLineage(objectUnderTest, 50, 50, false)
187             createLineage(objectUnderTest, 50, 50, true)
188         when: 'parent node is batch deleted'
189             stopWatch.start()
190             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR, [PERF_TEST_PARENT])
191             stopWatch.stop()
192             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
193         then: 'delete duration is under 300 milliseconds'
194             recordAndAssertPerformance('Batch delete one large node', 300, deleteDurationInMillis)
195     }
196
197     @Sql([CLEAR_DATA, PERF_TEST_DATA])
198     def 'Delete root node with many descendants'() {
199         given: 'a node with a large number of descendants is created'
200             createLineage(objectUnderTest, 50, 50, false)
201             createLineage(objectUnderTest, 50, 50, true)
202         when: 'root node is deleted'
203             stopWatch.start()
204             objectUnderTest.deleteDataNode(PERF_DATASPACE, PERF_ANCHOR, '/')
205             stopWatch.stop()
206             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
207         then: 'delete duration is under 300 milliseconds'
208             recordAndAssertPerformance('Delete root node', 300, deleteDurationInMillis)
209     }
210
211     @Sql([CLEAR_DATA, PERF_TEST_DATA])
212     def 'Delete data nodes for an anchor'() {
213         given: 'a node with a large number of descendants is created'
214             createLineage(objectUnderTest, 50, 50, false)
215             createLineage(objectUnderTest, 50, 50, true)
216         when: 'data nodes are deleted'
217             stopWatch.start()
218             objectUnderTest.deleteDataNodes(PERF_DATASPACE, PERF_ANCHOR)
219             stopWatch.stop()
220             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
221         then: 'delete duration is under 300 milliseconds'
222             recordAndAssertPerformance('Delete data nodes for anchor', 300, deleteDurationInMillis)
223     }
224
225     @Sql([CLEAR_DATA, PERF_TEST_DATA])
226     def 'Delete data nodes for multiple anchors'() {
227         given: 'a node with a large number of descendants is created'
228             createLineage(objectUnderTest, 50, 50, false)
229             createLineage(objectUnderTest, 50, 50, true)
230         when: 'data nodes are deleted'
231             stopWatch.start()
232             objectUnderTest.deleteDataNodes(PERF_DATASPACE, [PERF_ANCHOR])
233             stopWatch.stop()
234             def deleteDurationInMillis = stopWatch.getTotalTimeMillis()
235         then: 'delete duration is under 300 milliseconds'
236             recordAndAssertPerformance('Delete data nodes for anchors', 300, deleteDurationInMillis)
237     }
238
239 }