85869264031c4c43ed5d4de57a1ec55c9c31f16d
[cps.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2024-2025 OpenInfra Foundation Europe. All rights reserved.
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.integration.performance.cps
22
23 import org.onap.cps.integration.performance.base.CpsPerfTestBase
24 import org.onap.cps.api.model.ModuleReference
25
26 class ModuleQueryPerfTest extends CpsPerfTestBase {
27
28     static final KILOBYTE = 1000
29     static final TOTAL_TEST_ANCHORS = 10_000
30     static final SCHEMA_SET_PREFIX = 'mySchemaSet'
31     static final ANCHOR_PREFIX = 'myAnchor'
32     static final MODULE_REVISION = '2024-04-25'
33     static final MODULE_TEMPLATE = """
34         module <MODULE_NAME> {
35             yang-version 1.1;
36             namespace "org:onap:cps:test:<MODULE_NAME>";
37             prefix tree;
38             revision "<MODULE_REVISION>" {
39                 description "<DESCRIPTION>";
40             }
41             container tree {
42                 list branch {
43                     key "name";
44                     leaf name {
45                         type string;
46                     }
47                 }
48             }
49         }
50     """
51
52     def 'Module query - Preload test data (needed for other tests).'() {
53         given: 'a schema set with different sizes of Yang modules is created'
54             cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, SCHEMA_SET_PREFIX + '0', [
55                     'module0.yang': makeYangModuleOfLength('module0', 1 * KILOBYTE),
56                     'module1.yang': makeYangModuleOfLength('module1', 1000 * KILOBYTE)
57             ])
58         and: 'these modules will be used again to create many schema sets'
59             def allModuleReferences = [
60                     new ModuleReference('module0', MODULE_REVISION),
61                     new ModuleReference('module1', MODULE_REVISION)
62             ]
63         when: 'many schema sets and anchors are created using those modules'
64             resourceMeter.start()
65             (1..TOTAL_TEST_ANCHORS).each {
66                 def schemaSetName = SCHEMA_SET_PREFIX + it
67                 def anchorName = ANCHOR_PREFIX + it
68                 cpsModuleService.createSchemaSetFromModules(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, [:], allModuleReferences)
69                 cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, anchorName)
70             }
71             resourceMeter.stop()
72         then: 'operation takes less than expected duration'
73             recordAndAssertResourceUsage('Module query test setup', 90, resourceMeter.totalTimeInSeconds, 500, resourceMeter.totalMemoryUsageInMB
74             )
75     }
76
77     def 'Querying anchors by module name is NOT dependant on the file size of the module.'() {
78         when: 'we search for anchors with given Yang module name'
79             resourceMeter.start()
80             def result = cpsAnchorService.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, [yangModuleName])
81             resourceMeter.stop()
82         then: 'expected number of anchors is returned'
83             assert result.size() == TOTAL_TEST_ANCHORS
84         and: 'operation completes with expected resource usage'
85             recordAndAssertResourceUsage("Query for anchors with ${scenario}", 0.1, resourceMeter.totalTimeInSeconds, 5, resourceMeter.totalMemoryUsageInMB)
86         where: 'the following parameters are used'
87             scenario         | yangModuleName
88             '1 KB module'    | 'module0'
89             '1000 KB module' | 'module1'
90     }
91
92     def 'Module query - Clean up test data.'() {
93         cleanup:
94             // FIXME this API has extremely high memory usage, therefore external batching must be used
95             for (int i = 1; i <= TOTAL_TEST_ANCHORS; i += 100) {
96                 cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, (i..i+100).collect {SCHEMA_SET_PREFIX + it})
97             }
98             cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, [SCHEMA_SET_PREFIX + '0'])
99             cpsModuleService.deleteAllUnusedYangModuleData(CPS_PERFORMANCE_TEST_DATASPACE)
100     }
101
102     // This makes a Yang module of approximately target length in bytes by padding the description field with many '*'
103     private static def makeYangModuleOfLength(moduleName, targetLength) {
104         def padding = String.valueOf('*').repeat(targetLength - MODULE_TEMPLATE.size()) // not exact
105         return MODULE_TEMPLATE
106                 .replaceAll('<MODULE_NAME>', moduleName)
107                 .replaceAll('<MODULE_REVISION>', MODULE_REVISION)
108                 .replaceAll('<DESCRIPTION>', padding)
109     }
110 }