aboutsummaryrefslogtreecommitdiffstats
path: root/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy
blob: 8609dd560d4f83fa8292d0afe17992a7b5b612ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 *  ============LICENSE_START=======================================================
 *  Copyright (C) 2024 Nordix Foundation
 *  ================================================================================
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  SPDX-License-Identifier: Apache-2.0
 *  ============LICENSE_END=========================================================
 */

package org.onap.cps.integration.performance.cps

import org.onap.cps.integration.performance.base.CpsPerfTestBase
import org.onap.cps.spi.model.ModuleReference

class ModuleQueryPerfTest extends CpsPerfTestBase {

    static final KILOBYTE = 1000
    static final TOTAL_TEST_ANCHORS = 10_000
    static final SCHEMA_SET_PREFIX = 'mySchemaSet'
    static final ANCHOR_PREFIX = 'myAnchor'
    static final MODULE_REVISION = '2024-04-25'
    static final MODULE_TEMPLATE = """
        module <MODULE_NAME> {
            yang-version 1.1;
            namespace "org:onap:cps:test:<MODULE_NAME>";
            prefix tree;
            revision "<MODULE_REVISION>" {
                description "<DESCRIPTION>";
            }
            container tree {
                list branch {
                    key "name";
                    leaf name {
                        type string;
                    }
                }
            }
        }
    """

    def 'Module query - Preload test data (needed for other tests).'() {
        given: 'a schema set with different sizes of Yang modules is created'
            cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, SCHEMA_SET_PREFIX + '0', [
                    'module0.yang': makeYangModuleOfLength('module0', 1 * KILOBYTE),
                    'module1.yang': makeYangModuleOfLength('module1', 1000 * KILOBYTE)
            ])
        and: 'these modules will be used again to create many schema sets'
            def allModuleReferences = [
                    new ModuleReference('module0', MODULE_REVISION),
                    new ModuleReference('module1', MODULE_REVISION)
            ]
        when: 'many schema sets and anchors are created using those modules'
            resourceMeter.start()
            (1..TOTAL_TEST_ANCHORS).each {
                def schemaSetName = SCHEMA_SET_PREFIX + it
                def anchorName = ANCHOR_PREFIX + it
                cpsModuleService.createSchemaSetFromModules(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, [:], allModuleReferences)
                cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, schemaSetName, anchorName)
            }
            resourceMeter.stop()
        then: 'operation takes less than expected duration'
            recordAndAssertResourceUsage('Module query test setup',
                    45, resourceMeter.totalTimeInSeconds,
                    500, resourceMeter.totalMemoryUsageInMB
            )
    }

    def 'Bug CPS-2190: Querying anchors by module name IS dependant on the file size of the module.'() {
        when: 'we search for anchors with given Yang module name'
            resourceMeter.start()
            def result = cpsAnchorService.queryAnchorNames(CPS_PERFORMANCE_TEST_DATASPACE, [yangModuleName])
            resourceMeter.stop()
        then: 'expected number of anchors is returned'
            assert result.size() == TOTAL_TEST_ANCHORS
        and: 'operation completes with expected resource usage'
            recordAndAssertResourceUsage("Query for anchors with ${scenario}",
                    expectedTimeInSeconds, resourceMeter.totalTimeInSeconds,
                    300, resourceMeter.totalMemoryUsageInMB)
        where: 'the following parameters are used'
            scenario         | yangModuleName || expectedTimeInSeconds
            '1 KB module'    | 'module0'      || 3
            '1000 KB module' | 'module1'      || 12
    }

    def 'Module query - Clean up test data.'() {
        cleanup:
            // FIXME this API has extremely high memory usage, therefore external batching must be used
            for (int i = 1; i <= TOTAL_TEST_ANCHORS; i += 100) {
                cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, (i..i+100).collect {SCHEMA_SET_PREFIX + it})
            }
            cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, [SCHEMA_SET_PREFIX + '0'])
    }

    // This makes a Yang module of approximately target length in bytes by padding the description field with many '*'
    private static def makeYangModuleOfLength(moduleName, targetLength) {
        def padding = String.valueOf('*').repeat(targetLength - MODULE_TEMPLATE.size()) // not exact
        return MODULE_TEMPLATE
                .replaceAll('<MODULE_NAME>', moduleName)
                .replaceAll('<MODULE_REVISION>', MODULE_REVISION)
                .replaceAll('<DESCRIPTION>', padding)
    }
}