Integration test for state migration job 23/142623/4
authoregernug <gerard.nugent@est.tech>
Tue, 2 Dec 2025 11:40:45 +0000 (11:40 +0000)
committeregernug <gerard.nugent@est.tech>
Wed, 3 Dec 2025 13:09:08 +0000 (13:09 +0000)
- Added DataMigrationIntegrationSpec test class
- Changed migrateInventoryToModelRelease20250722 signature to take in batch size
- Changed InventoryModelLoaderSpec to call upgradeAndMigrateInventoryModel() directly
- Added schemaSetExists() check in ModuleUpgradeServiceIntegrationSpec to allow for suite and isolated execution

Issue-ID: CPS-3061

Change-Id: I2a51a5e3fae91155396357500f5e2d2cec70f8df
Signed-off-by: egernug <gerard.nugent@est.tech>
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/DataMigration.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/DataMigrationSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/DataMigrationIntegrationSpec.groovy [new file with mode: 0644]
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/ModuleUpgradeServiceIntegrationSpec.groovy

index 82a1175..45e8125 100644 (file)
@@ -38,7 +38,6 @@ import org.springframework.stereotype.Component;
 public class DataMigration {
 
     public final InventoryPersistence inventoryPersistence;
-    protected int batchSize = 300;
     private final CmHandleQueryService cmHandleQueryService;
     private final NetworkCmProxyInventoryFacade networkCmProxyInventoryFacade;
 
@@ -47,7 +46,7 @@ public class DataMigration {
      * Migration of CompositeState CmHandleState into a new top level attribute.
      * One off migration job.
      */
-    public void migrateInventoryToModelRelease20250722() {
+    public void migrateInventoryToModelRelease20250722(final int batchSize) {
         log.info("Inventory data migration started");
         final List<String> cmHandleIds = new ArrayList<>(cmHandleQueryService.getAllCmHandleReferences(false));
         log.info("Number of cm handles to process {}", cmHandleIds.size());
index 139fbb7..6d08e2c 100644 (file)
@@ -46,6 +46,7 @@ public class InventoryModelLoader extends AbstractModelLoader {
     private static final String PREVIOUS_SCHEMA_SET_NAME = "dmi-registry-2024-02-23";
     private static final String NEW_INVENTORY_SCHEMA_SET_NAME = "dmi-registry-2025-07-22";
     private static final String INVENTORY_YANG_MODULE_NAME = "dmi-registry";
+    private static final int MIGRATION_BATCH_SIZE = 300;
 
     @Value("${ncmp.inventory.model.upgrade.r20250722.enabled:false}")
     private boolean newRevisionEnabled;
@@ -130,6 +131,6 @@ public class InventoryModelLoader extends AbstractModelLoader {
 
     private void upgradeAndMigrateInventoryModel() {
         upgradeInventoryModel();
-        dataMigration.migrateInventoryToModelRelease20250722();
+        dataMigration.migrateInventoryToModelRelease20250722(MIGRATION_BATCH_SIZE);
     }
 }
index 21e752d..45fb482 100644 (file)
@@ -67,7 +67,7 @@ class DataMigrationSpec extends Specification{
             def cmHandleIds = ['ch-1', 'ch-2', 'ch-3']
             mockCmHandleQueryService.getAllCmHandleReferences(false) >> cmHandleIds
         when:   'migration is performed'
-            objectUnderTest.migrateInventoryToModelRelease20250722()
+            objectUnderTest.migrateInventoryToModelRelease20250722(3)
         then:   'handles are processed in bulk'
             1 * mockInventoryPersistence.bulkUpdateCmHandleStates({ cmHandleStateUpdates ->
                 def actualData = cmHandleStateUpdates.collect { [id: it.cmHandleId, state: it.state] }
@@ -87,7 +87,7 @@ class DataMigrationSpec extends Specification{
         and: 'an exception is thrown when getting cm handle'
             mockNetworkCmProxyInventoryFacade.getNcmpServiceCmHandle('faultyCmHandle') >> { throw new RuntimeException('Simulated failure') }
         when: 'migration is performed'
-            objectUnderTest.migrateInventoryToModelRelease20250722()
+            objectUnderTest.migrateInventoryToModelRelease20250722(2)
         then: 'migration processes no batches'
             1 * mockInventoryPersistence.bulkUpdateCmHandleStates([])
     }
@@ -101,7 +101,7 @@ class DataMigrationSpec extends Specification{
                 throw new RuntimeException('Simulated failure')
             }
         when: 'migration is performed'
-            objectUnderTest.migrateInventoryToModelRelease20250722()
+            objectUnderTest.migrateInventoryToModelRelease20250722(2)
         then: 'exception is caught and logged'
             def loggingEvent = logger.list[0]
             assert loggingEvent.level == Level.ERROR
index 9f68934..bddb52d 100644 (file)
@@ -85,13 +85,6 @@ class InventoryModelLoaderSpec extends Specification {
         applicationContext.close()
     }
 
-    def callPrivatePerformInventoryDataMigration() {
-        def method = objectUnderTest.class.getDeclaredMethod('upgradeAndMigrateInventoryModel')
-        method.accessible = true
-        method.invoke(objectUnderTest)
-    }
-
-
     def 'Onboard subscription model via application ready event.'() {
         given: 'dataspace is ready for use with default newRevisionEnabled flag'
             objectUnderTest.newRevisionEnabled = false
@@ -156,9 +149,9 @@ class InventoryModelLoaderSpec extends Specification {
 
     def "Perform inventory data migration to Release20250722"() {
         when: 'the migration is performed'
-            callPrivatePerformInventoryDataMigration()
+            objectUnderTest.upgradeAndMigrateInventoryModel()
         then: 'the call is delegated to the Data Migration service'
-            1 * mockDataMigration.migrateInventoryToModelRelease20250722()
+            1 * mockDataMigration.migrateInventoryToModelRelease20250722(_)
     }
 
 
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/DataMigrationIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/DataMigrationIntegrationSpec.groovy
new file mode 100644 (file)
index 0000000..07d3b44
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the 'License');
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an 'AS IS' BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration.functional.ncmp.inventory
+
+import org.onap.cps.integration.base.CpsIntegrationSpecBase
+import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
+import org.onap.cps.ncmp.init.DataMigration
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.TestPropertySource
+
+@TestPropertySource(properties = ["ncmp.inventory.model.upgrade.r20250722.enabled=true"])
+class DataMigrationIntegrationSpec extends CpsIntegrationSpecBase {
+
+    @Autowired
+    DataMigration objectUnderTest
+
+    def 'Migrate inventory with batch processing.'() {
+        given: 'DMI will return modules when requested'
+            dmiDispatcher1.moduleNamesPerCmHandleId = (1..2).collectEntries{ ['ch-'+it, ['M1']] }
+        and: 'multiple CM handles registered, (top level) status is null'
+            (1..2).each {
+                registerCmHandle(DMI1_URL, 'ch-'+it, NO_MODULE_SET_TAG)
+                def someCmHandle = networkCmProxyInventoryFacade.getNcmpServiceCmHandle('ch-'+it)
+                assert someCmHandle.getCmHandleStatus() == null
+                assert someCmHandle.getCompositeState().getCmHandleState().name() == 'READY'
+            }
+        when: 'migration is executed'
+            objectUnderTest.migrateInventoryToModelRelease20250722(1)
+        then: 'all CM handles are processed successfully,' +
+                'the (top level) status is set to the same value as the name of the complex state value'
+            (1..2).each {
+                def someCmHandle = networkCmProxyInventoryFacade.getNcmpServiceCmHandle('ch-'+it)
+                assert someCmHandle.getCmHandleStatus() == 'READY'
+                assert someCmHandle.getCompositeState().getCmHandleState().name() == 'READY'
+            }
+        cleanup: 'deregister CM handles'
+            deregisterCmHandles(DMI1_URL, (1..2).collect{ 'ch-'+it })
+    }
+}
\ No newline at end of file
index 104166d..f762c38 100644 (file)
@@ -59,8 +59,10 @@ class ModuleUpgradeServiceIntegrationSpec extends FunctionalSpecBase {
         when: 'A new version of the dmi-registry module (upgrade) is available'
             def newYangContent = readResourceDataFile('inventory/dmi-registry@2025-07-22.yang')
             def newYangResourceContentPerName = ["dmi-registry@2025-07-22.yang": newYangContent]
-        then: 'The schema set is upgraded with the new module revision'
-            cpsModulePersistenceService.createSchemaSet('NCMP-Admin', 'dmi-registry-2025-07-22', newYangResourceContentPerName)
+        then: 'Install the latest version of inventory model dmi-registry-2025-07-22'
+            if (!cpsModulePersistenceService.schemaSetExists('NCMP-Admin', 'dmi-registry-2025-07-22')) {
+                    cpsModulePersistenceService.createSchemaSet('NCMP-Admin', 'dmi-registry-2025-07-22', newYangResourceContentPerName)
+            }
             cpsAnchorService.updateAnchorSchemaSet('NCMP-Admin','ncmp-dmi-registry','dmi-registry-2025-07-22')
         when: 'that state gets updated to a different value'
             final Collection<DataNode> cmHandleDataNodes = inventoryPersistence.getCmHandleDataNodeByCmHandleId('ch-1', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)