From ded9f06f42bbe751bdec3d763ae5216d76df82c4 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Thu, 22 Dec 2022 14:47:07 +0000 Subject: Temp Table Creation improvements - extracted methods for more generic temp table creation - optimized - added perf test on use case that depends on temp table creation - had some doubts about stopwatch use in recent tests, but was all OK, just renamed some Issue-ID: CPS-1422 Signed-off-by: ToineSiebelink Change-Id: I22cabb9b0ba1b0aa8576a2d756d77af46eebc1b0 --- ...sModulePersistenceServiceIntegrationSpec.groovy | 7 +- .../CpsModuleReferenceRepositoryPerfTest.groovy | 103 +++++++++++++++++++++ .../spi/performance/CpsToDataNodePerfTest.groovy | 27 +++--- 3 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsModuleReferenceRepositoryPerfTest.groovy (limited to 'cps-ri/src/test/groovy') diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy index bcb080726..4c67f7e97 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy @@ -230,8 +230,9 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase def 'Identifying new module references where #scenario'() { when: 'identifyNewModuleReferences is called' def result = objectUnderTest.identifyNewModuleReferences(moduleReferences) - then: 'the correct module reference collection is returned' - assert result == expectedResult + then: 'the correct module references are returned' + assert result.size() == expectedResult.size() + assert result.containsAll(expectedResult) where: 'the following data is used' scenario | moduleReferences || expectedResult 'new module references exist' | toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']]) || toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']]) @@ -304,7 +305,7 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase def moduleReferences = [].withDefault { [:] } moduleReferenceAsMap.forEach(property -> property.forEach((moduleName, revision) -> { - moduleReferences.add(new ModuleReference('moduleName' : moduleName, 'revision' : revision)) + moduleReferences.add(new ModuleReference(moduleName, revision)) })) return moduleReferences } diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsModuleReferenceRepositoryPerfTest.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsModuleReferenceRepositoryPerfTest.groovy new file mode 100644 index 000000000..8da6c3a0b --- /dev/null +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsModuleReferenceRepositoryPerfTest.groovy @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.spi.performance + +import org.onap.cps.spi.CpsModulePersistenceService +import org.onap.cps.spi.entities.SchemaSetEntity +import org.onap.cps.spi.impl.CpsPersistenceSpecBase +import org.onap.cps.spi.model.ModuleReference +import org.onap.cps.spi.repository.DataspaceRepository +import org.onap.cps.spi.repository.ModuleReferenceRepository +import org.onap.cps.spi.repository.SchemaSetRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.context.jdbc.Sql +import org.springframework.util.StopWatch + +import java.util.concurrent.ThreadLocalRandom + +class CpsModuleReferenceRepositoryPerfTest extends CpsPersistenceSpecBase { + + static final String PERF_TEST_DATA = '/data/perf-test.sql' + + def NEW_RESOURCE_CONTENT = 'module stores {\n' + + ' yang-version 1.1;\n' + + ' namespace "org:onap:ccsdk:sample";\n' + + '\n' + + ' prefix book-store;\n' + + '\n' + + ' revision "2020-09-15" {\n' + + ' description\n' + + ' "Sample Model";\n' + + ' }' + + '}' + + @Autowired + CpsModulePersistenceService objectUnderTest + + @Autowired + DataspaceRepository dataspaceRepository + + @Autowired + SchemaSetRepository schemaSetRepository + + @Autowired + ModuleReferenceRepository moduleReferenceRepository + + @Sql([CLEAR_DATA, PERF_TEST_DATA]) + def 'Store new schema set with many modules'() { + when: 'a new schema set with 200 modules is stored' + def newYangResourcesNameToContentMap = [:] + (1..200).each { + def year = 2000 + it + def resourceName = "module${it}".toString() + def moduleName = "stores${it}" + def content = NEW_RESOURCE_CONTENT.replace('2020',String.valueOf(year)).replace('stores',moduleName) + newYangResourcesNameToContentMap.put(resourceName, content) + } + objectUnderTest.storeSchemaSet('PERF-DATASPACE', 'perfSchemaSet', newYangResourcesNameToContentMap) + then: 'the schema set is persisted correctly' + def dataspaceEntity = dataspaceRepository.getByName('PERF-DATASPACE') + SchemaSetEntity result = schemaSetRepository.getByDataspaceAndName(dataspaceEntity, 'perfSchemaSet') + result.yangResources.size() == 200 + and: 'identification of new module resources is fast enough (1,000 executions less then 5,000 milliseconds)' + def stopWatch = new StopWatch() + 1000.times() { + def moduleReferencesToCheck = createModuleReferencesWithRandomMatchingExistingModuleReferences() + stopWatch.start() + def newModuleReferences = moduleReferenceRepository.identifyNewModuleReferences(moduleReferencesToCheck) + stopWatch.stop() + assert newModuleReferences.size() > 0 && newModuleReferences.size() < 300 + } + assert stopWatch.getTotalTimeMillis() < 5000 + } + + def createModuleReferencesWithRandomMatchingExistingModuleReferences() { + def moduleReferences = [] + (1..250).each { + def randomNumber = ThreadLocalRandom.current().nextInt(1, 300) + def year = 2000 + randomNumber + def moduleName = "stores${randomNumber}" + moduleReferences.add(new ModuleReference(moduleName, "${year}-09-15")) + } + return moduleReferences + } + +} diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy index 33e83f101..265c5fc5f 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy @@ -47,26 +47,25 @@ class CpsToDataNodePerfTest extends CpsPersistenceSpecBase { static def ALLOWED_SETUP_TIME_MS = TimeUnit.SECONDS.toMillis(10) static def ALLOWED_READ_TIME_AL_NODES_MS = 500 - def readStopWatch = new StopWatch() + def stopWatch = new StopWatch() @Sql([CLEAR_DATA, PERF_TEST_DATA]) def 'Create a node with many descendants (please note, subsequent tests depend on this running first).'() { given: 'a node with a large number of descendants is created' - def setupStopWatch = new StopWatch() - setupStopWatch.start() + stopWatch.start() createLineage() - setupStopWatch.stop() - def setupDurationInMillis = setupStopWatch.getTotalTimeMillis() + stopWatch.stop() + def setupDurationInMillis = stopWatch.getTotalTimeMillis() and: 'setup duration is under #ALLOWED_SETUP_TIME_MS milliseconds' assert setupDurationInMillis < ALLOWED_SETUP_TIME_MS } def 'Get data node with many descendants by xpath #scenario'() { when: 'get parent is executed with all descendants' - readStopWatch.start() + stopWatch.start() def result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', xpath, INCLUDE_ALL_DESCENDANTS) - readStopWatch.stop() - def readDurationInMillis = readStopWatch.getTotalTimeMillis() + stopWatch.stop() + def readDurationInMillis = stopWatch.getTotalTimeMillis() then: 'read duration is under 500 milliseconds' assert readDurationInMillis < ALLOWED_READ_TIME_AL_NODES_MS and: 'data node is returned with all the descendants populated' @@ -79,10 +78,10 @@ class CpsToDataNodePerfTest extends CpsPersistenceSpecBase { def 'Query parent data node with many descendants by cps-path'() { when: 'query is executed with all descendants' - readStopWatch.start() + stopWatch.start() def result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-parent-1' , INCLUDE_ALL_DESCENDANTS) - readStopWatch.stop() - def readDurationInMillis = readStopWatch.getTotalTimeMillis() + stopWatch.stop() + def readDurationInMillis = stopWatch.getTotalTimeMillis() then: 'read duration is under 500 milliseconds' assert readDurationInMillis < ALLOWED_READ_TIME_AL_NODES_MS and: 'data node is returned with all the descendants populated' @@ -91,10 +90,10 @@ class CpsToDataNodePerfTest extends CpsPersistenceSpecBase { def 'Query many descendants by cps-path with #scenario'() { when: 'query is executed with all descendants' - readStopWatch.start() + stopWatch.start() def result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-test-grand-child-1', descendantsOption) - readStopWatch.stop() - def readDurationInMillis = readStopWatch.getTotalTimeMillis() + stopWatch.stop() + def readDurationInMillis = stopWatch.getTotalTimeMillis() then: 'read duration is under 500 milliseconds' assert readDurationInMillis < alowedDuration and: 'data node is returned with all the descendants populated' -- cgit 1.2.3-korg