2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 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.integration.performance.base.CpsPerfTestBase
24 import org.onap.cps.spi.model.ModuleReference
26 class ModuleQueryPerfTest extends CpsPerfTestBase {
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> {
36 namespace "org:onap:cps:test:<MODULE_NAME>";
38 revision "<MODULE_REVISION>" {
39 description "<DESCRIPTION>";
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)
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)
63 when: 'many schema sets and anchors are created using those modules'
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)
72 then: 'operation takes less than expected duration'
73 recordAndAssertResourceUsage('Module query test setup',
74 45, resourceMeter.totalTimeInSeconds,
75 500, resourceMeter.totalMemoryUsageInMB
79 def 'Bug CPS-2190: Querying anchors by module name IS dependant on the file size of the module.'() {
80 when: 'we search for anchors with given Yang module name'
82 def result = cpsAnchorService.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, [yangModuleName])
84 then: 'expected number of anchors is returned'
85 assert result.size() == TOTAL_TEST_ANCHORS
86 and: 'operation completes with expected resource usage'
87 recordAndAssertResourceUsage("Query for anchors with ${scenario}",
88 expectedTimeInSeconds, resourceMeter.totalTimeInSeconds,
89 300, resourceMeter.totalMemoryUsageInMB)
90 where: 'the following parameters are used'
91 scenario | yangModuleName || expectedTimeInSeconds
92 '1 KB module' | 'module0' || 3
93 '1000 KB module' | 'module1' || 12
96 def 'Module query - Clean up test data.'() {
98 // FIXME this API has extremely high memory usage, therefore external batching must be used
99 for (int i = 1; i <= TOTAL_TEST_ANCHORS; i += 100) {
100 cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, (i..i+100).collect {SCHEMA_SET_PREFIX + it})
102 cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, [SCHEMA_SET_PREFIX + '0'])
105 // This makes a Yang module of approximately target length in bytes by padding the description field with many '*'
106 private static def makeYangModuleOfLength(moduleName, targetLength) {
107 def padding = String.valueOf('*').repeat(targetLength - MODULE_TEMPLATE.size()) // not exact
108 return MODULE_TEMPLATE
109 .replaceAll('<MODULE_NAME>', moduleName)
110 .replaceAll('<MODULE_REVISION>', MODULE_REVISION)
111 .replaceAll('<DESCRIPTION>', padding)