diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BucketLayout.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BucketLayout.java
index 00118ccad368..a9803e03e4a9 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BucketLayout.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BucketLayout.java
@@ -65,6 +65,10 @@ public boolean isFileSystemOptimized() {
return this.equals(FILE_SYSTEM_OPTIMIZED);
}
+ public boolean isLegacy() {
+ return this.equals(LEGACY);
+ }
+
public boolean shouldNormalizePaths(boolean enableFileSystemPaths) {
switch (this) {
case OBJECT_STORE:
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.2.1-1.3.0/callback.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.2.1-1.3.0/callback.sh
index f414ddf43f7c..d54c9bc89b46 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.2.1-1.3.0/callback.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.2.1-1.3.0/callback.sh
@@ -71,7 +71,7 @@ with_old_version_downgraded() {
with_new_version_finalized() {
_check_hdds_mlvs 3
- _check_om_mlvs 1
+ _check_om_mlvs 2
validate old1
validate new1
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot
index 288f9c01507f..b70f3ca14781 100644
--- a/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot
@@ -19,7 +19,7 @@ Resource ../commonlib.robot
Test Timeout 5 minutes
Test Setup Run Keyword if '${SECURITY_ENABLED}' == 'true' Kinit test user testuser testuser.keytab
-** Test Cases ***
+*** Test Cases ***
Finalize SCM
${result} = Execute ozone admin scm finalizeupgrade
#Wait Until Keyword Succeeds 3min 10sec Should contain ${result} OM Preparation successful!
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/OMUpgradeTestUtils.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/OMUpgradeTestUtils.java
new file mode 100644
index 000000000000..093cc0943f25
--- /dev/null
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/OMUpgradeTestUtils.java
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+ */
+
+package org.apache.hadoop.ozone.om;
+
+import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
+import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer;
+import org.apache.ozone.test.LambdaTestUtils;
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse.PrepareStatus.PREPARE_COMPLETED;
+import static org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.Status.FINALIZATION_DONE;
+import static org.apache.ozone.test.GenericTestUtils.waitFor;
+
+/**
+ * Utility class to help test OM upgrade scenarios.
+ */
+public final class OMUpgradeTestUtils {
+
+ private OMUpgradeTestUtils() {
+ // Utility class.
+ }
+
+ public static void assertClusterPrepared(
+ long preparedIndex, List ozoneManagers) throws Exception {
+ for (OzoneManager om : ozoneManagers) {
+ LambdaTestUtils.await(120000,
+ 1000, () -> {
+ if (!om.isRunning()) {
+ return false;
+ } else {
+ boolean preparedAtIndex = false;
+ OzoneManagerPrepareState.State state =
+ om.getPrepareState().getState();
+
+ if (state.getStatus() == PREPARE_COMPLETED) {
+ if (state.getIndex() == preparedIndex) {
+ preparedAtIndex = true;
+ } else {
+ // State will not change if we are prepared at the wrong
+ // index. Break out of wait.
+ throw new Exception("OM " + om.getOMNodeId() + " prepared " +
+ "but prepare index " + state.getIndex() + " does not " +
+ "match expected prepare index " + preparedIndex);
+ }
+ }
+ return preparedAtIndex;
+ }
+ });
+ }
+ }
+
+ public static void waitForFinalization(OzoneManagerProtocol omClient)
+ throws TimeoutException, InterruptedException {
+ waitFor(() -> {
+ try {
+ UpgradeFinalizer.StatusAndMessages statusAndMessages =
+ omClient.queryUpgradeFinalizationProgress("finalize-test", false,
+ false);
+ System.out.println("Finalization Messages : " +
+ statusAndMessages.msgs());
+ return statusAndMessages.status().equals(FINALIZATION_DONE);
+ } catch (IOException e) {
+ Assert.fail(e.getMessage());
+ }
+ return false;
+ }, 2000, 20000);
+ }
+}
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMBucketLayoutUpgrade.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMBucketLayoutUpgrade.java
new file mode 100644
index 000000000000..a4442f2d2945
--- /dev/null
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMBucketLayoutUpgrade.java
@@ -0,0 +1,272 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *