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 'Querying anchors by module name is NOT 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 5, resourceMeter.totalMemoryUsageInMB)
90 where: 'the following parameters are used'
91 scenario | yangModuleName || expectedTimeInSeconds
92 '1 KB module' | 'module0' || 0.05
93 '1000 KB module' | 'module1' || 0.05
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)