Merge "CM SUBSCRIPTION: add new subscription for non existing xpath"
[cps.git] / cps-ri / src / test / groovy / org / onap / cps / spi / impl / CpsModulePersistenceServiceConcurrencySpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2022 Bell Canada.
4  *  Modifications Copyright (C) 2021-2023 Nordix Foundation.
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the 'License');
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an 'AS IS' BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21 package org.onap.cps.spi.impl
22
23 import org.hibernate.exception.ConstraintViolationException
24 import org.onap.cps.spi.CpsAdminPersistenceService
25 import org.onap.cps.spi.CpsModulePersistenceService
26 import org.onap.cps.spi.entities.DataspaceEntity
27 import org.onap.cps.spi.entities.SchemaSetEntity
28 import org.onap.cps.spi.exceptions.DuplicatedYangResourceException
29 import org.onap.cps.spi.model.ModuleReference
30 import org.onap.cps.spi.repository.DataspaceRepository
31 import org.onap.cps.spi.repository.ModuleReferenceRepository
32 import org.onap.cps.spi.repository.SchemaSetRepository
33 import org.onap.cps.spi.repository.YangResourceRepository
34 import org.spockframework.spring.SpringBean
35 import org.springframework.beans.factory.annotation.Autowired
36 import org.springframework.boot.test.context.SpringBootTest
37 import org.springframework.dao.DataIntegrityViolationException
38 import org.springframework.retry.annotation.EnableRetry
39 import spock.lang.Specification
40
41 import java.sql.SQLException
42
43 @SpringBootTest(classes=[CpsModulePersistenceServiceImpl])
44 @EnableRetry
45 class CpsModulePersistenceServiceConcurrencySpec extends Specification {
46
47     @Autowired
48     CpsModulePersistenceService objectUnderTest
49
50     @SpringBean
51     DataspaceRepository dataspaceRepository = Mock()
52
53     @SpringBean
54     YangResourceRepository yangResourceRepository = Mock()
55
56     @SpringBean
57     SchemaSetRepository schemaSetRepository = Mock()
58
59     @SpringBean
60     CpsAdminPersistenceService cpsAdminPersistenceService = Mock()
61
62     @SpringBean
63     ModuleReferenceRepository moduleReferenceRepository = Mock()
64
65     def NEW_RESOURCE_NAME = 'some new resource'
66     def NEW_RESOURCE_CONTENT = 'module stores {\n' +
67             '    yang-version 1.1;\n' +
68             '    namespace "org:onap:ccsdk:sample";\n' +
69             '}'
70
71     def newYangResourcesNameToContentMap = [(NEW_RESOURCE_NAME):NEW_RESOURCE_CONTENT]
72
73     def yangResourceChecksum = 'b13faef573ed1374139d02c40d8ce09c80ea1dc70e63e464c1ed61568d48d539'
74
75     def yangResourceChecksumDbConstraint = 'yang_resource_checksum_key'
76
77     def sqlExceptionMessage = String.format('(checksum)=(%s)', yangResourceChecksum)
78
79     def checksumIntegrityException = new DataIntegrityViolationException("checksum integrity exception",
80                  new ConstraintViolationException('', new SQLException(sqlExceptionMessage), yangResourceChecksumDbConstraint))
81
82     def 'Store new schema set, maximum retries.'() {
83         given: 'no pre-existing schemaset in database'
84             dataspaceRepository.getByName(_) >> new DataspaceEntity()
85             yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
86         when: 'a new schemaset is stored'
87             objectUnderTest.storeSchemaSet('some dataspace', 'some new schema set', newYangResourcesNameToContentMap)
88         then: 'a duplicated yang resource exception is thrown '
89             thrown(DuplicatedYangResourceException)
90         and: 'the system will attempt to save the data 5 times (because checksum integrity exception is thrown each time)'
91             5 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
92     }
93
94     def 'Store new schema set, succeed on third attempt.'() {
95         given: 'no pre-existing schemaset in database'
96             dataspaceRepository.getByName(_) >> new DataspaceEntity()
97             yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
98         when: 'a new schemaset is stored'
99             objectUnderTest.storeSchemaSet('some dataspace', 'some new schema set', newYangResourcesNameToContentMap)
100         then: 'no exception is thrown '
101             noExceptionThrown()
102         and: 'the system will attempt to save the data 2 times with checksum integrity exception but then succeed'
103             2 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
104             1 * yangResourceRepository.saveAll(_) >> []
105     }
106
107     def 'Store schema set using modules, maximum retries.'() {
108         given: 'map of new modules, a list of existing modules, module reference'
109             def mapOfNewModules = [newModule1: 'module newmodule { yang-version 1.1; revision "2021-10-12" { } }']
110             def moduleReferenceForExistingModule = new ModuleReference("test","2021-10-12")
111             def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule]
112         and: 'no pre-existing schemaset in database'
113             dataspaceRepository.getByName(_) >> new DataspaceEntity()
114             yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
115         when: 'a new schemaset is stored from a module'
116             objectUnderTest.storeSchemaSetFromModules('some dataspace', 'some new schema set' , mapOfNewModules, listOfExistingModulesModuleReference)
117         then: 'a duplicated yang resource exception is thrown '
118             thrown(DuplicatedYangResourceException)
119         and: 'the system will attempt to save the data 5 times (because checksum integrity exception is thrown each time)'
120             5 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
121     }
122
123     def 'Store schema set using modules, succeed on third attempt.'() {
124         given: 'map of new modules, a list of existing modules, module reference'
125             def mapOfNewModules = [newModule1: 'module newmodule { yang-version 1.1; revision "2021-10-12" { } }']
126             def moduleReferenceForExistingModule = new ModuleReference("test","2021-10-12")
127             def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule]
128         and: 'no pre-existing schemaset in database'
129             def dataspaceEntity = new DataspaceEntity()
130             dataspaceRepository.getByName(_) >> new DataspaceEntity()
131             yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
132             yangResourceRepository.getResourceIdsByModuleReferences(_) >> []
133         and: 'can retrieve schemaset details after storing it'
134             def schemaSetEntity = new SchemaSetEntity()
135             schemaSetRepository.getByDataspaceAndName(dataspaceEntity, 'new schema set') >> schemaSetEntity
136         when: 'a new schemaset is stored from a module'
137             objectUnderTest.storeSchemaSetFromModules('some dataspace', 'new schema set' , mapOfNewModules, listOfExistingModulesModuleReference)
138         then: 'no exception is thrown '
139             noExceptionThrown()
140         and: 'the system will attempt to save the data 2 times with checksum integrity exception but then succeed'
141             2 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
142             1 * yangResourceRepository.saveAll(_) >> []
143     }
144
145 }