f93f58ce20dde5acb6e07445eab154b10deaf91e
[cps.git] /
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.ncmp
22
23 import org.onap.cps.integration.base.CpsIntegrationSpecBase
24 import org.onap.cps.ncmp.api.inventory.NetworkCmProxyInventoryFacade
25 import org.onap.cps.ncmp.api.inventory.models.CmHandleRegistrationResponse
26 import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration
27 import org.onap.cps.ncmp.api.inventory.models.UpgradedCmHandles
28 import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
29 import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory
30 import spock.util.concurrent.PollingConditions
31
32 class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
33
34     NetworkCmProxyInventoryFacade objectUnderTest
35
36     static final CM_HANDLE_ID = 'ch-1'
37     static final CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG = 'ch-2'
38
39     def setup() {
40         objectUnderTest = networkCmProxyInventoryFacade
41     }
42
43     def 'Upgrade CM-handle with new moduleSetTag or no moduleSetTag.'() {
44         given: 'a CM-handle is created with expected initial modules: M1 and M2'
45             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID] = ['M1', 'M2']
46             registerCmHandle(DMI1_URL, CM_HANDLE_ID, initialModuleSetTag)
47             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
48
49         when: "the CM-handle is upgraded with given moduleSetTag '${updatedModuleSetTag}'"
50             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: updatedModuleSetTag)
51             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistrationAndSyncModule(
52                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
53
54         then: 'registration gives successful response'
55             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(CM_HANDLE_ID)]
56
57         and: 'CM-handle is in LOCKED state due to MODULE_UPGRADE'
58             def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID)
59             assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
60             assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE
61             assert cmHandleCompositeState.lockReason.details == "Upgrade to ModuleSetTag: ${updatedModuleSetTag}"
62
63         when: 'DMI will return different modules for upgrade: M1 and M3'
64             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID] = ['M1', 'M3']
65
66         then: 'CM-handle goes to READY state'
67             new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
68                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
69             })
70
71         and: 'the CM-handle has expected moduleSetTag'
72             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == updatedModuleSetTag
73
74         and: 'CM-handle has expected updated modules: M1 and M3'
75             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
76
77         cleanup: 'deregister CM-handle'
78             deregisterCmHandle(DMI1_URL, CM_HANDLE_ID)
79
80         where:
81             initialModuleSetTag | updatedModuleSetTag
82             NO_MODULE_SET_TAG   | NO_MODULE_SET_TAG
83             NO_MODULE_SET_TAG   | 'new'
84             'initial'           | NO_MODULE_SET_TAG
85             'initial'           | 'new'
86     }
87
88     def 'Upgrade CM-handle with existing moduleSetTag.'() {
89         given: 'DMI will return modules for registration'
90             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID] = ['M1', 'M2']
91             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG] = ['M1', 'M3']
92         and: "an existing CM-handle handle with moduleSetTag '${updatedModuleSetTag}'"
93             registerCmHandle(DMI1_URL, CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG, updatedModuleSetTag)
94             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG).moduleName.sort()
95         and: "a CM-handle with moduleSetTag '${initialModuleSetTag}' which will be upgraded"
96             registerCmHandle(DMI1_URL, CM_HANDLE_ID, initialModuleSetTag)
97             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
98
99         when: "CM-handle is upgraded to moduleSetTag '${updatedModuleSetTag}'"
100             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: updatedModuleSetTag)
101             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistrationAndSyncModule(
102                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
103
104         then: 'registration gives successful response'
105             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(CM_HANDLE_ID)]
106
107         and: 'CM-handle goes to READY state'
108             new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
109                 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
110             })
111
112         and: 'the CM-handle has expected moduleSetTag'
113             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == updatedModuleSetTag
114
115         and: 'CM-handle has expected updated modules: M1 and M3'
116             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
117
118         cleanup: 'deregister CM-handle'
119             deregisterCmHandles(DMI1_URL, [CM_HANDLE_ID, CM_HANDLE_ID_WITH_EXISTING_MODULE_SET_TAG])
120
121         where:
122             initialModuleSetTag | updatedModuleSetTag
123             NO_MODULE_SET_TAG   | 'moduleSet2'
124             'moduleSet1'        | 'moduleSet2'
125     }
126
127     def 'Skip upgrade of CM-handle with same moduleSetTag as before.'() {
128         given: 'an existing CM-handle with expected initial modules: M1 and M2'
129             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID] = ['M1', 'M2']
130             registerCmHandle(DMI1_URL, CM_HANDLE_ID, 'same')
131             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
132
133         when: 'CM-handle is upgraded with the same moduleSetTag'
134             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: 'same')
135             objectUnderTest.updateDmiRegistrationAndSyncModule(
136                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
137
138         then: 'CM-handle remains in READY state'
139             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID).cmHandleState
140
141         and: 'the CM-handle has same moduleSetTag as before'
142             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == 'same'
143
144         then: 'CM-handle has same modules as before: M1 and M2'
145             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(CM_HANDLE_ID).moduleName.sort()
146
147         cleanup: 'deregister CM-handle'
148             deregisterCmHandle(DMI1_URL, CM_HANDLE_ID)
149     }
150
151     def 'Upgrade of CM-handle fails due to DMI error.'() {
152         given: 'a CM-handle exists'
153             dmiDispatcher1.moduleNamesPerCmHandleId[CM_HANDLE_ID] = ['M1', 'M2']
154             registerCmHandle(DMI1_URL, CM_HANDLE_ID, 'oldTag')
155         and: 'DMI is not available for upgrade'
156             dmiDispatcher1.isAvailable = false
157
158         when: 'the CM-handle is upgraded'
159             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [CM_HANDLE_ID], moduleSetTag: 'newTag')
160             objectUnderTest.updateDmiRegistrationAndSyncModule(
161                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
162
163         then: 'CM-handle goes to LOCKED state with reason MODULE_UPGRADE_FAILED'
164             new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
165                 def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(CM_HANDLE_ID)
166                 assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
167                 assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
168             })
169
170         and: 'the CM-handle has same moduleSetTag as before'
171             assert objectUnderTest.getNcmpServiceCmHandle(CM_HANDLE_ID).moduleSetTag == 'oldTag'
172
173         cleanup: 'deregister CM-handle'
174             deregisterCmHandle(DMI1_URL, CM_HANDLE_ID)
175     }
176
177 }