1750264257665990a827eca190db0d0755d89c8d
[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('CPS:Module query test setup', 'Module query test setup', 150, resourceMeter.totalTimeInSeconds, 500, resourceMeter.totalMemoryUsageInMB)
74     }
75
76     def 'Querying anchors by module name is NOT dependant on the file size of the module.'() {
77         when: 'we search for anchors with given Yang module name'
78             resourceMeter.start()
79             def result = cpsAnchorService.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, [yangModuleName])
80             resourceMeter.stop()
81         then: 'expected number of anchors is returned'
82             assert result.size() == TOTAL_TEST_ANCHORS
83         and: 'operation completes with expected resource usage'
84             recordAndAssertResourceUsage("CPS:Query for anchors with ${scenario}", "Query for anchors with ${scenario}", 0.1, resourceMeter.totalTimeInSeconds, 5, resourceMeter.totalMemoryUsageInMB, REFERENCE_GRAPH)
85         where: 'the following parameters are used'
86             scenario         | yangModuleName
87             '1 KB module'    | 'module0'
88             '1000 KB module' | 'module1'
89     }
90
91     def 'Module query - Clean up test data.'() {
92         cleanup:
93             // FIXME this API has extremely high memory usage, therefore external batching must be used
94             for (int i = 1; i <= TOTAL_TEST_ANCHORS; i += 100) {
95                 cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, (i..i+100).collect {SCHEMA_SET_PREFIX + it})
96             }
97             cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, [SCHEMA_SET_PREFIX + '0'])
98             cpsModuleService.deleteAllUnusedYangModuleData(CPS_PERFORMANCE_TEST_DATASPACE)
99     }
100
101     // This makes a Yang module of approximately target length in bytes by padding the description field with many '*'
102     private static def makeYangModuleOfLength(moduleName, targetLength) {
103         def padding = String.valueOf('*').repeat(targetLength - MODULE_TEMPLATE.size()) // not exact
104         return MODULE_TEMPLATE
105                 .replaceAll('<MODULE_NAME>', moduleName)
106                 .replaceAll('<MODULE_REVISION>', MODULE_REVISION)
107                 .replaceAll('<DESCRIPTION>', padding)
108     }
109 }