4369b799bd87686365f543e34c2bfc5b0619d388
[cps.git] / integration-test / src / test / groovy / org / onap / cps / integration / functional / NcmpCmHandleCreateSpec.groovy
1 /*
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.integration.functional
22
23 import org.onap.cps.integration.base.CpsIntegrationSpecBase
24 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
25 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
26 import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory
27 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse
28 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
29 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
30 import org.springframework.http.HttpStatus
31 import spock.util.concurrent.PollingConditions
32
33 import static org.springframework.test.web.client.match.MockRestRequestMatchers.anything
34 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
35
36 class NcmpCmHandleCreateSpec extends CpsIntegrationSpecBase {
37
38     NetworkCmProxyDataService objectUnderTest
39
40     static final MODULE_REFERENCES_RESPONSE_A = readResourceDataFile('mock-dmi-responses/bookStoreAWithModules_M1_M2_Response.json')
41     static final MODULE_RESOURCES_RESPONSE_A = readResourceDataFile('mock-dmi-responses/bookStoreAWithModules_M1_M2_ResourcesResponse.json')
42     static final MODULE_REFERENCES_RESPONSE_B = readResourceDataFile('mock-dmi-responses/bookStoreBWithModules_M1_M3_Response.json')
43     static final MODULE_RESOURCES_RESPONSE_B = readResourceDataFile('mock-dmi-responses/bookStoreBWithModules_M1_M3_ResourcesResponse.json')
44
45     def setup() {
46         objectUnderTest = networkCmProxyDataService
47     }
48
49     def 'CM Handle registration is successful.'() {
50         given: 'DMI will return modules when requested'
51             mockDmiResponsesForRegistration(DMI_URL, 'ch-1', MODULE_REFERENCES_RESPONSE_A, MODULE_RESOURCES_RESPONSE_A)
52
53         when: 'a CM-handle is registered for creation'
54             def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: 'ch-1')
55             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI_URL, createdCmHandles: [cmHandleToCreate])
56             def dmiPluginRegistrationResponse = networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
57
58         then: 'registration gives successful response'
59             assert dmiPluginRegistrationResponse.createdCmHandles == [CmHandleRegistrationResponse.createSuccessResponse('ch-1')]
60
61         and: 'CM-handle is initially in ADVISED state'
62             assert CmHandleState.ADVISED == objectUnderTest.getCmHandleCompositeState('ch-1').cmHandleState
63
64         when: 'module sync runs'
65             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
66
67         then: 'CM-handle goes to READY state'
68             new PollingConditions().within(3, () -> {
69                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState('ch-1').cmHandleState
70             })
71
72         and: 'the CM-handle has expected modules'
73             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences('ch-1').moduleName.sort()
74
75         and: 'DMI received expected requests'
76             mockDmiServer.verify()
77
78         cleanup: 'deregister CM handle'
79             deregisterCmHandle(DMI_URL, 'ch-1')
80     }
81
82     def 'CM Handle goes to LOCKED state when DMI gives error during module sync.'() {
83         given: 'DMI is not available to handle requests'
84             mockDmiServer.expect(anything()).andRespond(withStatus(HttpStatus.SERVICE_UNAVAILABLE))
85
86         when: 'a CM-handle is registered for creation'
87             def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: 'ch-1')
88             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI_URL, createdCmHandles: [cmHandleToCreate])
89             networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
90
91         and: 'module sync runs'
92             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
93
94         then: 'CM-handle goes to LOCKED state with reason MODULE_SYNC_FAILED'
95             new PollingConditions().within(3, () -> {
96                 def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState('ch-1')
97                 assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
98                 assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_SYNC_FAILED
99             })
100
101         and: 'CM-handle has no modules'
102             assert objectUnderTest.getYangResourcesModuleReferences('ch-1').empty
103
104         cleanup: 'deregister CM handle'
105             deregisterCmHandle(DMI_URL, 'ch-1')
106     }
107
108     def 'Create a CM-handle with existing moduleSetTag.'() {
109         given: 'existing CM-handles cm-1 with moduleSetTag "A", and cm-2 with moduleSetTag "B"'
110             registerCmHandle(DMI_URL, 'ch-1', 'A', MODULE_REFERENCES_RESPONSE_A, MODULE_RESOURCES_RESPONSE_A)
111             registerCmHandle(DMI_URL, 'ch-2', 'B', MODULE_REFERENCES_RESPONSE_B, MODULE_RESOURCES_RESPONSE_B)
112             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences('ch-1').moduleName.sort()
113             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences('ch-2').moduleName.sort()
114
115         when: 'a CM-handle is registered for creation with moduleSetTag "B"'
116             def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: 'ch-3', moduleSetTag: 'B')
117             networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: DMI_URL, createdCmHandles: [cmHandleToCreate]))
118
119         then: 'the CM-handle goes to READY state after module sync'
120             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
121             new PollingConditions().within(3, () -> {
122                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState('ch-3').cmHandleState
123             })
124
125         and: 'the CM-handle has expected moduleSetTag'
126             assert objectUnderTest.getNcmpServiceCmHandle('ch-3').moduleSetTag == 'B'
127
128         and: 'the CM-handle has expected modules from module set "B": M1 and M3'
129             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences('ch-3').moduleName.sort()
130
131         cleanup: 'deregister CM handles'
132             deregisterCmHandles(DMI_URL, ['ch-1', 'ch-2', 'ch-3'])
133     }
134 }