5f062962dbf0fb4dada88ce8a3fbea3a06fc8903
[cps.git] / integration-test / src / test / groovy / org / onap / cps / integration / functional / NcmpCmHandleUpgradeSpec.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.UpgradedCmHandles
30 import org.springframework.http.HttpStatus
31 import spock.lang.Ignore
32 import spock.util.concurrent.PollingConditions
33
34 import static org.springframework.test.web.client.match.MockRestRequestMatchers.anything
35 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
36
37 class NcmpCmHandleUpgradeSpec extends CpsIntegrationSpecBase {
38
39     NetworkCmProxyDataService objectUnderTest
40
41     static final INITIAL_MODULE_REFERENCES_RESPONSE = readResourceDataFile('mock-dmi-responses/bookStoreAWithModules_M1_M2_Response.json')
42     static final INITIAL_MODULE_RESOURCES_RESPONSE = readResourceDataFile('mock-dmi-responses/bookStoreAWithModules_M1_M2_ResourcesResponse.json')
43     static final UPDATED_MODULE_REFERENCES_RESPONSE = readResourceDataFile('mock-dmi-responses/bookStoreBWithModules_M1_M3_Response.json')
44     static final UPDATED_MODULE_RESOURCES_RESPONSE = readResourceDataFile('mock-dmi-responses/bookStoreBWithModules_M1_M3_ResourcesResponse.json')
45     static final NO_MODULE_SET_TAG = ''
46     static final CM_HANDLE_ID = 'ch-1'
47     static final CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG = 'ch-2'
48
49     def setup() {
50         objectUnderTest = networkCmProxyDataService
51     }
52
53     @Ignore
54     def 'Upgrade CM-handle with new moduleSetTag or no moduleSetTag.'() {
55         given: 'an existing CM-handle with expected initial modules: M1 and M2'
56             registerCmHandle(DMI_URL, CM_HANDLE_ID, initialModuleSetTag, INITIAL_MODULE_REFERENCES_RESPONSE, INITIAL_MODULE_RESOURCES_RESPONSE)
57             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
58
59         and: 'DMI returns different modules for upgrade'
60             mockDmiResponsesForRegistration(DMI_URL, CM_HANDLE_ID, UPDATED_MODULE_REFERENCES_RESPONSE, UPDATED_MODULE_RESOURCES_RESPONSE)
61
62         when: "CM-handle is upgraded with given moduleSetTag '${updatedModuleSetTag}'"
63             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: updatedModuleSetTag)
64             def dmiPluginRegistrationResponse = networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
65                     new DmiPluginRegistration(dmiPlugin: DMI_URL, upgradedCmHandles: cmHandlesToUpgrade))
66
67         then: 'registration gives successful response'
68             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(CM_HANDLE_ID)]
69
70         and: 'CM-handle is in LOCKED state due to MODULE_UPGRADE'
71             def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID)
72             assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
73             assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE
74             assert cmHandleCompositeState.lockReason.details == "Upgrade to ModuleSetTag: ${updatedModuleSetTag}"
75
76         when: 'module sync runs'
77             moduleSyncWatchdog.resetPreviouslyFailedCmHandles()
78             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
79
80         then: 'CM-handle goes to READY state'
81             new PollingConditions().within(3, () -> {
82                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
83             })
84
85         and: 'the CM-handle has expected moduleSetTag'
86             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == updatedModuleSetTag
87
88         and: 'CM-handle has expected updated modules: M1 and M3'
89             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
90
91         and: 'DMI received expected requests'
92             mockDmiServer.verify()
93
94         cleanup: 'deregister CM-handle'
95             deregisterCmHandle(DMI_URL, CM_HANDLE_ID)
96
97         where:
98             initialModuleSetTag | updatedModuleSetTag
99             NO_MODULE_SET_TAG   | NO_MODULE_SET_TAG
100             NO_MODULE_SET_TAG   | 'new'
101             'initial'           | NO_MODULE_SET_TAG
102             'initial'           | 'new'
103     }
104
105     def 'Upgrade CM-handle with existing moduleSetTag.'() {
106         given: "an existing CM-handle handle with moduleSetTag '${updatedModuleSetTag}'"
107             registerCmHandle(DMI_URL, CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG, updatedModuleSetTag, UPDATED_MODULE_REFERENCES_RESPONSE, UPDATED_MODULE_RESOURCES_RESPONSE)
108             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG).moduleName.sort()
109         and: "a CM-handle with moduleSetTag '${initialModuleSetTag}' which will be upgraded"
110             registerCmHandle(DMI_URL, CM_HANDLE_ID, initialModuleSetTag, INITIAL_MODULE_REFERENCES_RESPONSE, INITIAL_MODULE_RESOURCES_RESPONSE)
111             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
112
113         when: "CM-handle is upgraded to moduleSetTag '${updatedModuleSetTag}'"
114             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: updatedModuleSetTag)
115             def dmiPluginRegistrationResponse = networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
116                     new DmiPluginRegistration(dmiPlugin: DMI_URL, upgradedCmHandles: cmHandlesToUpgrade))
117
118         then: 'registration gives successful response'
119             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(CM_HANDLE_ID)]
120
121         when: 'module sync runs'
122             moduleSyncWatchdog.resetPreviouslyFailedCmHandles()
123             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
124
125         then: 'CM-handle goes to READY state'
126             new PollingConditions().within(3, () -> {
127                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
128             })
129
130         and: 'the CM-handle has expected moduleSetTag'
131             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == updatedModuleSetTag
132
133         and: 'CM-handle has expected updated modules: M1 and M3'
134             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
135
136         cleanup: 'deregister CM-handle'
137             deregisterCmHandles(DMI_URL, [CM_HANDLE_ID, CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG])
138
139         where:
140             initialModuleSetTag | updatedModuleSetTag
141             NO_MODULE_SET_TAG   | 'moduleSet2'
142             'moduleSet1'        | 'moduleSet2'
143     }
144
145     @Ignore
146     def 'Skip upgrade of CM-handle with same moduleSetTag as before.'() {
147         given: 'an existing CM-handle with expected initial modules: M1 and M2'
148             registerCmHandle(DMI_URL, CM_HANDLE_ID, 'same', INITIAL_MODULE_REFERENCES_RESPONSE, INITIAL_MODULE_RESOURCES_RESPONSE)
149             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
150
151         when: 'CM-handle is upgraded with the same moduleSetTag'
152             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: 'same')
153             networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
154                     new DmiPluginRegistration(dmiPlugin: DMI_URL, upgradedCmHandles: cmHandlesToUpgrade))
155
156         then: 'CM-handle remains in READY state'
157             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
158
159         and: 'the CM-handle has same moduleSetTag as before'
160             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == 'same'
161
162         then: 'CM-handle has same modules as before: M1 and M2'
163             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
164
165         cleanup: 'deregister CM-handle'
166             deregisterCmHandle(DMI_URL, CM_HANDLE_ID)
167     }
168
169     def 'Upgrade of CM-handle fails due to DMI error.'() {
170         given: 'an existing CM-handle'
171             registerCmHandle(DMI_URL, CM_HANDLE_ID, 'oldTag', INITIAL_MODULE_REFERENCES_RESPONSE, INITIAL_MODULE_RESOURCES_RESPONSE)
172
173         and: 'DMI returns error code'
174             mockDmiServer.expect(anything()).andRespond(withStatus(HttpStatus.SERVICE_UNAVAILABLE))
175
176         when: "CM-handle is upgraded"
177             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: 'newTag')
178             networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
179                     new DmiPluginRegistration(dmiPlugin: DMI_URL, upgradedCmHandles: cmHandlesToUpgrade))
180
181         and: 'module sync runs'
182             moduleSyncWatchdog.resetPreviouslyFailedCmHandles()
183             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
184
185         then: 'CM-handle goes to LOCKED state with reason MODULE_UPGRADE_FAILED'
186             new PollingConditions().within(3, () -> {
187                 def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID)
188                 assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
189                 assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
190             })
191
192         and: 'the CM-handle has same moduleSetTag as before'
193             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == 'oldTag'
194
195         cleanup: 'deregister CM-handle'
196             deregisterCmHandle(DMI_URL, CM_HANDLE_ID)
197     }
198
199 }