upgrade: fix upgrade from 4.18.1.0 to 4.18.2.0-SNAPSHOT (#7959)

The uprgade from 4.18.1.0 to 4.18.2.0-SNAPSHOT failed with error

```
2023-09-12 16:12:19,003 INFO  [c.c.u.DatabaseUpgradeChecker] (main:null) (logid:) DB version = 4.18.1.0 Code Version = 4.18.2.0
2023-09-12 16:12:19,004 INFO  [c.c.u.DatabaseUpgradeChecker] (main:null) (logid:) Database upgrade must be performed from 4.18.1.0 to 4.18.2.0
2023-09-12 16:12:19,036 DEBUG [c.c.u.DatabaseUpgradeChecker] (main:null) (logid:) Running upgrade Upgrade41800to41810 to upgrade from 4.18.0.0-4.18.1.0 to 4.18.1.0
...
2023-09-12 16:12:19,041 DEBUG [c.c.u.d.ScriptRunner] (main:null) (logid:) -- Schema upgrade from 4.18.0.0 to 4.18.1.0
...
2023-09-12 16:12:21,602 DEBUG [c.c.u.d.DatabaseAccessObject] (main:null) (logid:) Statement: CREATE INDEX i_cluster_details__name on cluster_details (name)
2023-09-12 16:12:21,663 DEBUG [c.c.u.d.DatabaseAccessObject] (main:null) (logid:) Created index i_cluster_details__name
2023-09-12 16:12:21,673 DEBUG [c.c.u.d.T.Transaction] (main:null) (logid:) Rolling back the transaction: Time = 2632 Name =  Upgrade; called by -TransactionLegacy.rollback:888-TransactionLegacy.removeUpTo:831-TransactionLegacy.close:655-TransactionContextInterceptor.invoke:36-ReflectiveMethodInvocation.proceed:175-ExposeInvocationInterceptor.invoke:97-ReflectiveMethodInvocation.proceed:186-JdkDynamicAopProxy.invoke:215-$Proxy30.persist:-1-DatabaseUpgradeChecker.upgrade:319-DatabaseUpgradeChecker.check:403-CloudStackExtendedLifeCycle.checkIntegrity:64
```

It succeeded with this change.

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java
index 7375786..e5b2df7 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java
@@ -504,4 +504,8 @@
             }
         }
     }
+
+    public CloudStackVersion getLatestVersion() {
+        return hierarchy.getLatestVersion();
+    }
 }
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java
index 8f27261..445a593 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java
@@ -88,6 +88,11 @@
             return new DbUpgrade[0];
         }
 
+        // The CloudStack version is latest or higher than latest
+        if (fromVersion.compareTo(getLatestVersion()) >= 0) {
+            return new DbUpgrade[0];
+        }
+
         // we cannot find the version specified, so get the
         // most recent one immediately before this version
         if (!contains(fromVersion)) {
@@ -184,4 +189,8 @@
             return new DatabaseVersionHierarchy(ImmutableList.copyOf(hierarchyBuilder));
         }
     }
+
+    public CloudStackVersion getLatestVersion() {
+        return CloudStackVersion.parse(hierarchy.get(hierarchy.size() - 1).upgrader.getUpgradedVersion());
+    }
 }
diff --git a/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java b/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
index 4f5c62c..d7ef18a 100644
--- a/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
+++ b/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
@@ -167,8 +167,8 @@
         final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
         final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
         assertNotNull(upgrades);
-        assertEquals("We should have 2 upgrade steps", 2, upgrades.length);
-        assertTrue(upgrades[1] instanceof NoopDbUpgrade);
+        assertEquals("We should have 1 upgrade step", 1, upgrades.length);
+        assertTrue(upgrades[0] instanceof NoopDbUpgrade);
 
     }
 
@@ -204,4 +204,23 @@
          assertTrue(upgrades[0] instanceof Upgrade41510to41520);
          assertTrue(upgrades[upgrades.length - 1] instanceof Upgrade41610to41700);
      }
+
+    @Test
+    public void testCalculateUpgradePathFromLatestDbVersion() {
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+
+        final CloudStackVersion dbVersion = checker.getLatestVersion();
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse(dbVersion.getMajorRelease() + "."
+                + dbVersion.getMinorRelease() + "."
+                + dbVersion.getPatchRelease() + "."
+                + (dbVersion.getSecurityRelease() + 1));
+        assertNotNull(currentVersion);
+
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+        assertNotNull(upgrades);
+        assertEquals("We should have 1 upgrade step", 1, upgrades.length);
+        assertTrue(upgrades[0] instanceof NoopDbUpgrade);
+    }
 }