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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.integration.functional.ncmp
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
32 class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
34 NetworkCmProxyInventoryFacade objectUnderTest
36 def cmHandleId = 'ch-1'
37 def cmHandleIdWithExistingModuleSetTag = 'ch-2'
40 objectUnderTest = networkCmProxyInventoryFacade
41 moduleSyncService.clearPrivateModuleSetCache()
44 def 'Upgrade CM-handle with new moduleSetTag or no moduleSetTag.'() {
45 given: 'a CM-handle is created with expected initial modules: M1 and M2'
46 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
47 registerCmHandle(DMI1_URL, cmHandleId, initialModuleSetTag)
48 assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
50 when: "the CM-handle is upgraded with given moduleSetTag '${updatedModuleSetTag}'"
51 def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: updatedModuleSetTag)
52 def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(
53 new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
55 then: 'registration gives successful response'
56 assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
58 and: 'CM-handle is in LOCKED state due to MODULE_UPGRADE'
59 def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
60 assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
61 assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE
62 assert cmHandleCompositeState.lockReason.details == "Upgrade to ModuleSetTag: ${updatedModuleSetTag}"
64 when: 'DMI will return different modules for upgrade: M1 and M3'
65 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M3']
67 and: 'the module sync watchdog is triggered twice'
68 2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
70 then: 'CM-handle goes to READY state'
71 new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
72 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
75 and: 'the CM-handle has expected moduleSetTag'
76 assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
78 and: 'CM-handle has expected updated modules: M1 and M3'
79 assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
81 cleanup: 'deregister CM-handle'
82 deregisterCmHandle(DMI1_URL, cmHandleId)
84 where: 'following module set tags are used'
85 initialModuleSetTag | updatedModuleSetTag
86 NO_MODULE_SET_TAG | NO_MODULE_SET_TAG
87 NO_MODULE_SET_TAG | 'new'
88 'initial' | NO_MODULE_SET_TAG
92 def 'Upgrade CM-handle with existing moduleSetTag.'() {
93 given: 'DMI will return modules for registration'
94 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
95 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleIdWithExistingModuleSetTag] = ['M1', 'M3']
96 and: "an existing CM-handle handle with moduleSetTag '${updatedModuleSetTag}'"
97 registerCmHandle(DMI1_URL, cmHandleIdWithExistingModuleSetTag, updatedModuleSetTag)
98 assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleIdWithExistingModuleSetTag).moduleName.sort()
99 and: "a CM-handle with moduleSetTag '${initialModuleSetTag}' which will be upgraded"
100 registerCmHandle(DMI1_URL, cmHandleId, initialModuleSetTag)
101 assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
103 when: "CM-handle is upgraded to moduleSetTag '${updatedModuleSetTag}'"
104 def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: updatedModuleSetTag)
105 def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(
106 new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
108 then: 'registration gives successful response'
109 assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
111 and: 'the module sync watchdog is triggered twice'
112 2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
114 and: 'CM-handle goes to READY state'
115 new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
116 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
119 and: 'the CM-handle has expected moduleSetTag'
120 assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
122 and: 'CM-handle has expected updated modules: M1 and M3'
123 assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
125 cleanup: 'deregister CM-handle'
126 deregisterCmHandles(DMI1_URL, [cmHandleId, cmHandleIdWithExistingModuleSetTag])
129 initialModuleSetTag | updatedModuleSetTag
130 NO_MODULE_SET_TAG | 'moduleSet2'
131 'moduleSet1' | 'moduleSet2'
134 def 'Skip upgrade of CM-handle with same moduleSetTag as before.'() {
135 given: 'an existing CM-handle with expected initial modules: M1 and M2'
136 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
137 registerCmHandle(DMI1_URL, cmHandleId, 'same')
138 assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
140 when: 'CM-handle is upgraded with the same moduleSetTag'
141 def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: 'same')
142 objectUnderTest.updateDmiRegistration(
143 new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
145 then: 'CM-handle remains in READY state'
146 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
148 and: 'the CM-handle has same moduleSetTag as before'
149 assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == 'same'
151 then: 'CM-handle has same modules as before: M1 and M2'
152 assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
154 cleanup: 'deregister CM-handle'
155 deregisterCmHandle(DMI1_URL, cmHandleId)
158 def 'Upgrade of CM-handle fails due to DMI error.'() {
159 given: 'a CM-handle exists'
160 dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
161 registerCmHandle(DMI1_URL, cmHandleId, 'oldTag')
162 and: 'DMI is not available for upgrade'
163 dmiDispatcher1.isAvailable = false
165 when: 'the CM-handle is upgraded'
166 def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: 'newTag')
167 objectUnderTest.updateDmiRegistration(
168 new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
170 and: 'the module sync watchdog is triggered twice'
171 2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
173 then: 'CM-handle goes to LOCKED state with reason MODULE_UPGRADE_FAILED'
174 new PollingConditions().within(MODULE_SYNC_WAIT_TIME_IN_SECONDS, () -> {
175 def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
176 assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
177 assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
180 and: 'the CM-handle has same moduleSetTag as before'
181 assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == 'oldTag'
183 cleanup: 'deregister CM-handle'
184 deregisterCmHandle(DMI1_URL, cmHandleId)