You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by av...@apache.org on 2021/04/13 15:56:15 UTC

[ozone] branch HDDS-3698-nonrolling-upgrade updated: HDDS-4181. Add acceptance tests for upgrade, finalization and downgrade. (#2056)

This is an automated email from the ASF dual-hosted git repository.

avijayan pushed a commit to branch HDDS-3698-nonrolling-upgrade
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-3698-nonrolling-upgrade by this push:
     new 5c6c858  HDDS-4181. Add acceptance tests for upgrade, finalization and downgrade. (#2056)
5c6c858 is described below

commit 5c6c8589a81856a399b68fb5d02e4137eaf62986
Author: Ethan Rose <33...@users.noreply.github.com>
AuthorDate: Tue Apr 13 11:55:50 2021 -0400

    HDDS-4181. Add acceptance tests for upgrade, finalization and downgrade. (#2056)
---
 hadoop-ozone/dist/src/main/compose/testlib.sh      |  22 ++--
 .../dist/src/main/compose/upgrade/README.md        |  95 +++++++++++++--
 .../src/main/compose/upgrade/{ => compose/ha}/.env |   7 +-
 .../upgrade/{ => compose/ha}/docker-compose.yaml   | 120 +++++++++++-------
 .../compose/upgrade/{ => compose/ha}/docker-config |  29 +++--
 .../upgrade/{1.0.0/test.sh => compose/ha/load.sh}  |  14 ++-
 .../main/compose/upgrade/{ => compose/non-ha}/.env |   2 +-
 .../{ => compose/non-ha}/docker-compose.yaml       |  99 +++++++--------
 .../upgrade/{ => compose/non-ha}/docker-config     |  16 ++-
 .../{0.5.0/test.sh => compose/non-ha/load.sh}      |  13 +-
 hadoop-ozone/dist/src/main/compose/upgrade/test.sh |  31 +++--
 .../dist/src/main/compose/upgrade/testlib.sh       | 135 ++++++++++++++++-----
 .../src/main/compose/upgrade/upgrade_to_current.sh |  51 --------
 .../manual-upgrade/0.5.0-1.1.0/callback.sh}        |  26 ++--
 .../manual-upgrade/driver.sh}                      |  63 +++++-----
 .../non-rolling-upgrade/1.0.0-1.1.0/callback.sh    |  79 ++++++++++++
 .../upgrade/upgrades/non-rolling-upgrade/driver.sh | 101 +++++++++++++++
 .../dist/src/main/compose/versions/0.5.0.sh        |   4 -
 .../dist/src/main/compose/versions/1.0.0.sh        |   4 -
 .../dist/src/main/compose/versions/1.1.0.sh        |   4 -
 .../dist/src/main/compose/versions/README.md       |   3 -
 .../src/main/smoketest/upgrade/check-mlv.robot     |  41 +++++++
 .../dist/src/main/smoketest/upgrade/finalize.robot |  31 +++++
 .../dist/src/main/smoketest/upgrade/generate.robot |  33 +++++
 .../dist/src/main/smoketest/upgrade/prepare.robot  |  26 ++++
 .../dist/src/main/smoketest/upgrade/validate.robot |  30 +++++
 .../dist/src/shell/upgrade/{v1.sh => 1.0.0.sh}     |   2 +-
 .../upgrade/{v1 => 1.0.0}/01-migrate-scm-db.sh     |   0
 28 files changed, 785 insertions(+), 296 deletions(-)

diff --git a/hadoop-ozone/dist/src/main/compose/testlib.sh b/hadoop-ozone/dist/src/main/compose/testlib.sh
index 40ff2a2..c1b95a5 100755
--- a/hadoop-ozone/dist/src/main/compose/testlib.sh
+++ b/hadoop-ozone/dist/src/main/compose/testlib.sh
@@ -110,7 +110,7 @@ wait_for_om_leader() {
 
   #Don't give it up until 120 seconds
   while [[ $SECONDS -lt 120 ]]; do
-    local command="ozone admin om roles --service-id '${OM_SERVICE_ID}'"
+    local command="ozone admin om getserviceroles --service-id '${OM_SERVICE_ID}'"
     if [[ "${SECURITY_ENABLED}" == 'true' ]]; then
       status=$(docker-compose exec -T ${SCM} bash -c "kinit -k scm/${SCM}@EXAMPLE.COM -t /etc/security/keytabs/scm.keytab && $command" | grep LEADER)
     else
@@ -144,7 +144,7 @@ start_docker_env(){
   if ! { docker-compose --no-ansi up -d --scale datanode="${datanode_count}" \
       && wait_for_safemode_exit \
       && wait_for_om_leader ; }; then
-    OUTPUT_NAME="$COMPOSE_ENV_NAME"
+    [[ -n "$OUTPUT_NAME" ]] || OUTPUT_NAME="$COMPOSE_ENV_NAME"
     stop_docker_env
     return 1
   fi
@@ -163,7 +163,7 @@ execute_robot_test(){
   TEST_NAME=$(basename "$TEST")
   TEST_NAME="$(basename "$COMPOSE_DIR")-${TEST_NAME%.*}"
   set +e
-  OUTPUT_NAME="$COMPOSE_ENV_NAME-$TEST_NAME-$CONTAINER"
+  [[ -n "$OUTPUT_NAME" ]] || OUTPUT_NAME="$COMPOSE_ENV_NAME-$TEST_NAME-$CONTAINER"
 
   # find unique filename
   declare -i i=0
@@ -319,6 +319,11 @@ copy_results() {
 
 run_test_script() {
   local d="$1"
+  local test_script="$2"
+
+  if [[ -z "$test_script" ]]; then
+    test_script=./test.sh
+  fi
 
   echo "Executing test in ${d}"
 
@@ -326,7 +331,7 @@ run_test_script() {
   cd "${d}" || return
 
   ret=0
-  if ! ./test.sh; then
+  if ! "$test_script"; then
     ret=1
     echo "ERROR: Test execution of ${d} is FAILED!!!!"
   fi
@@ -390,15 +395,6 @@ prepare_for_runner_image() {
   export OZONE_IMAGE="apache/ozone-runner:${v}"
 }
 
-## @description Print the logical version for a specific release
-## @param the release for which logical version should be printed
-get_logical_version() {
-  local v="$1"
-
-  # shellcheck source=/dev/null
-  echo $(source "${_testlib_dir}/versions/${v}.sh" && ozone_logical_version)
-}
-
 ## @description Activate the version-specific behavior for a given release
 ## @param the release for which definitions should be loaded
 load_version_specifics() {
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/README.md b/hadoop-ozone/dist/src/main/compose/upgrade/README.md
index 5d844e0..e63bf71 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/README.md
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/README.md
@@ -12,18 +12,91 @@
   limitations under the License. See accompanying LICENSE file.
 -->
 
-# Compose file for upgrade
+# Ozone Upgrade Acceptance Tests
 
-This directory contains a sample cluster definition and script for
-testing upgrade from previous version to the current one.
+This directory contains cluster definitions and scripts for testing upgrades from any previous version to another
+previous version, or to the local build of the code. It is designed to catch backwards incompatible changes made between
+an older release of Ozone and a later release (which may be the local build).
 
-Data for each container is persisted in mounted volume (by default it's
-`data` under the `compose/upgrade` directory, but can be overridden via
-`OZONE_VOLUME` environment variable).
+## IMPORTANT NOTES
 
-Prior version is run using an official `apache/ozone` image, while the
-current version is run with the `ozone-runner` image using locally built
-source code.
+1. Backwards Incompatibility
+    - These tests will not catch backwards incompatible changes against commits in between releases.
+        - Example:
+            1. After 1.0.0, a change *c1* is made that is backwards compatible with *1.0.0*.
+            2. After *c1*, a new change *c2* is made that is also backwards compatible with 1.0.0 but backwards *incompatible* with *c1*.
 
-Currently the test script only supports a single version upgrade (eg.
-from 0.5.0 to 1.0.0).
+            - This test suite will not raise an error for *c2*, because it only tests against the last release
+            (1.0.0), and not the last commit (*c1*).
+
+2. Downgrade Support
+    - Downgrades will not be supported until upgrading from 1.1.0 to 1.2.0
+
+    - Until 1.1.0 is released, downgrades cannot be tested, so they are commented out of the current non-rolling upgrade tests.
+
+## Directory Layout
+
+### upgrades
+
+Each type of upgrade has a subdirectory under the *upgrades* directory. Each upgrade's steps are controlled by a *test.sh* script in its *upgrades/\<upgrade-type>* directory. Callbacks to execute throughout the upgrade are called by this script and should be placed in a file called *callback.sh* in the *upgrades/\<upgrade-type>/\<upgrade-from>-\<upgrade-to>* directory. After the test is run, results and docker volume data for the upgrade for these versions will also be placed in this dir [...]
+
+#### manual-upgrade
+
+- Any necessary conversion of on disk structures from the old version to the new version must be done explicitly.
+
+- This is primarily for testing upgrades from versions before the non-rolling upgrade framework was introduced.
+
+- Supported Callbacks:
+    1. `setup_with_old_version`: Run before ozone is started in the old version.
+    3. `with_old_version`: Run while ozone is running in the old version.
+    3. `setup_with_new_version`: Run after ozone is stopped in the old version, but before it is restarted in the new version.
+    4. `with_new_version`: Run while ozone is running in the new version.
+
+#### non-rolling-upgrade
+
+- Any necessary conversion of on disk structures from the old version to the new version are handled by Ozone's non-rolling upgrade framework.
+
+- Supported Callbacks:
+    1. `setup`: Run before ozone is started in the old version.
+    3. `with_old_version`: Run while ozone is running in the old version.
+    3. `with_new_version_pre_finalized`: Run after ozone is stopped in the old version, and brought back up and running in the new version pre-finalized.
+    4. `with_old_version_downgraded`: Run after ozone is stopped in the new version pre-finalized, and restarted in the old version again.
+    5. `with_new_version_finalized`: Run after ozone is stopped in the old version after donwgrade, started again in the new version pre-finalized, and then finalized.
+        - The upgrade is complete when this callback runs.
+
+- Note that on the first upgrade after the non-rolling upgrade framework is added, the old version does not have the non-rolling upgrade framework, but the new version does.
+    - The non-rolling upgrade framework can still be used, the only difference is that OMs cannot be prepared before moving from the old version to the new version.
+    - Set the variable `OZONE_PREPARE_OMS` to `false` in `callback.sh` setup function to disable OM preparation as part of the upgrade.
+
+### compose
+
+Docker compose cluster definitions to be used in upgrade testing are defined in the *compose* directory. A compose cluster can be selected by sourcing the *load.sh* script in the compose cluster's directory on the setup callback for the upgrade test.
+
+## Persisting Data
+
+- Data for each container is persisted in a mounted volume.
+
+- By default it's `data` under the *compose/upgrade/\<versions>* directory, but can be overridden with the `OZONE_VOLUME` environment variable.
+
+- This allows data to be persisted in the cluster throughout container restarts, meaning that tests can check that data written in older versions is still readable in newer versions.
+
+- Data will be available after the tests finish for debugging purposes. It will be erased on a following run of the test.
+
+## Extending
+
+### Adding New Tests
+
+- To add tests to an existing upgrade type, edit its *compose/upgrade/\<upgrade-type>/\<versions>/callback.sh* file and add commands in the callback function when they should be run.
+
+- Each callback file will have access to the following environment variables:
+    - `OZONE_UPGRADE_FROM`: The version of ozone being upgraded from.
+    - `OZONE_UPGRADE_TO`: The version of ozone being upgraded to.
+    - `TEST_DIR`: The top level *upgrade* directory containing all files for upgrade testing.
+
+### Testing New Versions
+
+- To test upgrade between different versions, add a line `run_test <upgrade-type> <old-version> <new-version>` to the top level *test.sh* file.
+    -  The `run_test` function will execute *\<upgrade-type>/test.sh* with the callbacks defined in *\<upgrade-type>/\<old-version>-\<new-version>/callback.sh*.
+
+- If one of the specified versions does not match the current version defined by `OZONE_CURRENT_VERSION`, it will be pulled from the corresponding *apache/ozone* docker image.
+    - Else, the current version will be used, which will run the locally built source code in the `apache/ozone-runner` image.
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/.env b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/.env
similarity index 79%
copy from hadoop-ozone/dist/src/main/compose/upgrade/.env
copy to hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/.env
index 6f757c5..68f4302 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/.env
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/.env
@@ -18,4 +18,9 @@ HDDS_VERSION=${hdds.version}
 OZONE_RUNNER_VERSION=${docker.ozone-runner.version}
 OZONE_IMAGE=apache/ozone-runner:${docker.ozone-runner.version}
 OZONE_DIR=/opt/hadoop
-OZONE_VOLUME=.
+OZONE_VOLUME=./data
+OM_SERVICE_ID=omservice
+# Indicates no arguments to the OM.
+# This variable must be set to some non-empty value, or docker compose will
+# expand it to an empty string and pass that to the OM as an argument.
+OM_HA_ARGS=--
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-compose.yaml
similarity index 71%
copy from hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml
copy to hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-compose.yaml
index a15c2f9..24ff9d7 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-compose.yaml
@@ -25,7 +25,7 @@ x-common-config:
 
 x-replication:
   &replication
-  OZONE-SITE.XML_ozone.replication: ${OZONE_REPLICATION_FACTOR:-1}
+  OZONE-SITE.XML_ozone.replication: ${OZONE_REPLICATION_FACTOR:-3}
 
 x-datanode:
   &datanode
@@ -37,50 +37,93 @@ x-datanode:
     - 9864
     - 9882
 
+x-om:
+  &om
+  command: ["ozone","om","${OM_HA_ARGS}"]
+  <<: *common-config
+  environment:
+    ENSURE_OM_INITIALIZED: /data/metadata/om/current/VERSION
+    <<: *replication
+  ports:
+    - 9862
+    - 9872
+
+x-volumes:
+    - &ozone-dir ../../../..:${OZONE_DIR}
+    - &transformation ../../../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+
 services:
-  dn1:
-    <<: *datanode
+  om1:
+    <<: *om
     networks:
       net:
         ipv4_address: 10.9.0.11
     volumes:
-      - ${OZONE_VOLUME}/dn1:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  dn2:
-    <<: *datanode
+      - ${OZONE_VOLUME}/om1:/data
+      - *ozone-dir
+      - *transformation
+  om2:
+    <<: *om
     networks:
       net:
         ipv4_address: 10.9.0.12
     volumes:
-      - ${OZONE_VOLUME}/dn2:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  dn3:
-    <<: *datanode
+      - ${OZONE_VOLUME}/om2:/data
+      - *ozone-dir
+      - *transformation
+  om3:
+    <<: *om
     networks:
       net:
         ipv4_address: 10.9.0.13
     volumes:
-      - ${OZONE_VOLUME}/dn3:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  om:
-    command: ["ozone","om"]
+      - ${OZONE_VOLUME}/om3:/data
+      - *ozone-dir
+      - *transformation
+
+  scm:
+    command: ["ozone","scm"]
     <<: *common-config
     environment:
-      ENSURE_OM_INITIALIZED: /data/metadata/om/current/VERSION
+      ENSURE_SCM_INITIALIZED: /data/metadata/scm/current/VERSION
+      OZONE-SITE.XML_hdds.scm.safemode.min.datanode: ${OZONE_SAFEMODE_MIN_DATANODES:-1}
       <<: *replication
     networks:
       net:
         ipv4_address: 10.9.0.14
     ports:
-      - 9874:9874
-      - 9862:9862
+      - 9876:9876
+    volumes:
+      - ${OZONE_VOLUME}/scm:/data
+      - *ozone-dir
+      - *transformation
+  dn1:
+    <<: *datanode
+    networks:
+      net:
+        ipv4_address: 10.9.0.15
+    volumes:
+      - ${OZONE_VOLUME}/dn1:/data
+      - *ozone-dir
+      - *transformation
+  dn2:
+    <<: *datanode
+    networks:
+      net:
+        ipv4_address: 10.9.0.16
     volumes:
-      - ${OZONE_VOLUME}/om:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - ${OZONE_VOLUME}/dn2:/data
+      - *ozone-dir
+      - *transformation
+  dn3:
+    <<: *datanode
+    networks:
+      net:
+        ipv4_address: 10.9.0.17
+    volumes:
+      - ${OZONE_VOLUME}/dn3:/data
+      - *ozone-dir
+      - *transformation
   recon:
     command: ["ozone","recon"]
     <<: *common-config
@@ -88,13 +131,13 @@ services:
       <<: *replication
     networks:
       net:
-        ipv4_address: 10.9.0.15
+        ipv4_address: 10.9.0.18
     ports:
       - 9888:9888
     volumes:
       - ${OZONE_VOLUME}/recon:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - *ozone-dir
+      - *transformation
   s3g:
     command: ["ozone","s3g"]
     <<: *common-config
@@ -102,30 +145,13 @@ services:
       <<: *replication
     networks:
       net:
-        ipv4_address: 10.9.0.16
+        ipv4_address: 10.9.0.19
     ports:
       - 9878:9878
     volumes:
       - ${OZONE_VOLUME}/s3g:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  scm:
-    command: ["ozone","scm"]
-    <<: *common-config
-    environment:
-      ENSURE_SCM_INITIALIZED: /data/metadata/scm/current/VERSION
-      OZONE-SITE.XML_hdds.scm.safemode.min.datanode: ${OZONE_SAFEMODE_MIN_DATANODES:-1}
-      <<: *replication
-    networks:
-      net:
-        ipv4_address: 10.9.0.17
-    ports:
-      - 9876:9876
-    volumes:
-      - ${OZONE_VOLUME}/scm:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-
+      - *ozone-dir
+      - *transformation
 networks:
   net:
     driver: bridge
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/docker-config b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-config
similarity index 73%
copy from hadoop-ozone/dist/src/main/compose/upgrade/docker-config
copy to hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-config
index 0a489ae..325c139 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/docker-config
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/docker-config
@@ -14,24 +14,31 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-CORE-SITE.XML_fs.ofs.impl=org.apache.hadoop.fs.ozone.RootedOzoneFileSystem
-CORE-SITE.XML_fs.o3fs.impl=org.apache.hadoop.fs.ozone.OzoneFileSystem
-OZONE-SITE.XML_ozone.om.address=om
-OZONE-SITE.XML_ozone.om.http-address=om:9874
-OZONE-SITE.XML_ozone.scm.container.size=1GB
+OZONE-SITE.XML_ozone.metadata.dirs=/data/metadata
+
+OZONE-SITE.XML_ozone.client.failover.max.attempts=6
+
+OZONE-SITE.XML_ozone.om.service.ids=omservice
+OZONE-SITE.XML_ozone.om.nodes.omservice=om1,om2,om3
+OZONE-SITE.XML_ozone.om.address.omservice.om1=om1
+OZONE-SITE.XML_ozone.om.address.omservice.om2=om2
+OZONE-SITE.XML_ozone.om.address.omservice.om3=om3
+OZONE-SITE.XML_ozone.om.ratis.enable=true
+
 OZONE-SITE.XML_ozone.scm.pipeline.creation.interval=30s
 OZONE-SITE.XML_ozone.scm.pipeline.owner.container.count=1
 OZONE-SITE.XML_ozone.scm.names=scm
 OZONE-SITE.XML_ozone.scm.datanode.id.dir=/data
 OZONE-SITE.XML_ozone.scm.block.client.address=scm
-OZONE-SITE.XML_ozone.metadata.dirs=/data/metadata
-OZONE-SITE.XML_ozone.recon.db.dir=/data/metadata/recon
+OZONE-SITE.XML_ozone.scm.container.size=1GB
 OZONE-SITE.XML_ozone.scm.client.address=scm
+
 OZONE-SITE.XML_hdds.datanode.dir=/data/hdds
-OZONE-SITE.XML_ozone.recon.address=recon:9891
+
+OZONE-SITE.XML_ozone.recon.address=recon:9888
+OZONE-SITE.XML_ozone.recon.db.dir=/data/metadata/recon
 OZONE-SITE.XML_ozone.recon.om.snapshot.task.interval.delay=1m
 
-OZONE_CONF_DIR=/etc/hadoop
-OZONE_LOG_DIR=/var/log/hadoop
+no_proxy=om1,om2,om3,scm,s3g,kdc,localhost,127.0.0.1
 
-no_proxy=om,scm,s3g,kdc,localhost,127.0.0.1
+OM_SERVICE_ID=omservice
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/1.0.0/test.sh b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/load.sh
similarity index 73%
rename from hadoop-ozone/dist/src/main/compose/upgrade/1.0.0/test.sh
rename to hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/load.sh
index 11530c7..902eb12 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/1.0.0/test.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/ha/load.sh
@@ -15,10 +15,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-_mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+# Fail if required variables are not set.
+set -u
+: "${OZONE_VOLUME}"
+: "${TEST_DIR}"
+set +u
 
-export OZONE_UPGRADE_FROM="$(basename ${_mydir})"
-export RESULT_DIR="${_mydir}/result"
+source "$TEST_DIR/testlib.sh"
 
-cd "${_mydir}/.."
-source upgrade_to_current.sh
+export COMPOSE_FILE="$TEST_DIR/compose/ha/docker-compose.yaml"
+export OM_SERVICE_ID=omservice
+create_data_dirs "${OZONE_VOLUME}"/{om1,om2,om3,dn1,dn2,dn3,recon,s3g,scm}
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/.env b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/.env
similarity index 97%
rename from hadoop-ozone/dist/src/main/compose/upgrade/.env
rename to hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/.env
index 6f757c5..0699724 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/.env
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/.env
@@ -18,4 +18,4 @@ HDDS_VERSION=${hdds.version}
 OZONE_RUNNER_VERSION=${docker.ozone-runner.version}
 OZONE_IMAGE=apache/ozone-runner:${docker.ozone-runner.version}
 OZONE_DIR=/opt/hadoop
-OZONE_VOLUME=.
+OZONE_VOLUME=./data
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-compose.yaml
similarity index 78%
rename from hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml
rename to hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-compose.yaml
index a15c2f9..4b1d64e 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/docker-compose.yaml
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-compose.yaml
@@ -37,50 +37,70 @@ x-datanode:
     - 9864
     - 9882
 
+x-volumes:
+    - &ozone-dir ${TEST_DIR}/../..:${OZONE_DIR}
+    - &transformation ${TEST_DIR}/../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+
 services:
+  om:
+    command: ["ozone","om"]
+    <<: *common-config
+    environment:
+      ENSURE_OM_INITIALIZED: /data/metadata/om/current/VERSION
+      <<: *replication
+    ports:
+      - 9862
+      - 9874
+    networks:
+      net:
+        ipv4_address: 10.9.0.11
+    volumes:
+      - ${OZONE_VOLUME}/om:/data
+      - *ozone-dir
+      - *transformation
+  scm:
+    command: ["ozone","scm"]
+    <<: *common-config
+    environment:
+      ENSURE_SCM_INITIALIZED: /data/metadata/scm/current/VERSION
+      OZONE-SITE.XML_hdds.scm.safemode.min.datanode: ${OZONE_SAFEMODE_MIN_DATANODES:-1}
+      <<: *replication
+    networks:
+      net:
+        ipv4_address: 10.9.0.12
+    ports:
+      - 9876:9876
+    volumes:
+      - ${OZONE_VOLUME}/scm:/data
+      - *ozone-dir
+      - *transformation
   dn1:
     <<: *datanode
     networks:
       net:
-        ipv4_address: 10.9.0.11
+        ipv4_address: 10.9.0.13
     volumes:
       - ${OZONE_VOLUME}/dn1:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - *ozone-dir
+      - *transformation
   dn2:
     <<: *datanode
     networks:
       net:
-        ipv4_address: 10.9.0.12
+        ipv4_address: 10.9.0.14
     volumes:
       - ${OZONE_VOLUME}/dn2:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - *ozone-dir
+      - *transformation
   dn3:
     <<: *datanode
     networks:
       net:
-        ipv4_address: 10.9.0.13
+        ipv4_address: 10.9.0.15
     volumes:
       - ${OZONE_VOLUME}/dn3:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  om:
-    command: ["ozone","om"]
-    <<: *common-config
-    environment:
-      ENSURE_OM_INITIALIZED: /data/metadata/om/current/VERSION
-      <<: *replication
-    networks:
-      net:
-        ipv4_address: 10.9.0.14
-    ports:
-      - 9874:9874
-      - 9862:9862
-    volumes:
-      - ${OZONE_VOLUME}/om:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - *ozone-dir
+      - *transformation
   recon:
     command: ["ozone","recon"]
     <<: *common-config
@@ -88,13 +108,13 @@ services:
       <<: *replication
     networks:
       net:
-        ipv4_address: 10.9.0.15
+        ipv4_address: 10.9.0.16
     ports:
       - 9888:9888
     volumes:
       - ${OZONE_VOLUME}/recon:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
+      - *ozone-dir
+      - *transformation
   s3g:
     command: ["ozone","s3g"]
     <<: *common-config
@@ -102,30 +122,13 @@ services:
       <<: *replication
     networks:
       net:
-        ipv4_address: 10.9.0.16
+        ipv4_address: 10.9.0.17
     ports:
       - 9878:9878
     volumes:
       - ${OZONE_VOLUME}/s3g:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-  scm:
-    command: ["ozone","scm"]
-    <<: *common-config
-    environment:
-      ENSURE_SCM_INITIALIZED: /data/metadata/scm/current/VERSION
-      OZONE-SITE.XML_hdds.scm.safemode.min.datanode: ${OZONE_SAFEMODE_MIN_DATANODES:-1}
-      <<: *replication
-    networks:
-      net:
-        ipv4_address: 10.9.0.17
-    ports:
-      - 9876:9876
-    volumes:
-      - ${OZONE_VOLUME}/scm:/data
-      - ../..:${OZONE_DIR}
-      - ../../libexec/transformation.py:/opt/hadoop/libexec/transformation.py
-
+      - *ozone-dir
+      - *transformation
 networks:
   net:
     driver: bridge
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/docker-config b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-config
similarity index 88%
rename from hadoop-ozone/dist/src/main/compose/upgrade/docker-config
rename to hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-config
index 0a489ae..71a7aac 100644
--- a/hadoop-ozone/dist/src/main/compose/upgrade/docker-config
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/docker-config
@@ -14,21 +14,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-CORE-SITE.XML_fs.ofs.impl=org.apache.hadoop.fs.ozone.RootedOzoneFileSystem
-CORE-SITE.XML_fs.o3fs.impl=org.apache.hadoop.fs.ozone.OzoneFileSystem
+OZONE-SITE.XML_ozone.metadata.dirs=/data/metadata
+
+OZONE-SITE.XML_ozone.client.failover.max.attempts=6
+
 OZONE-SITE.XML_ozone.om.address=om
 OZONE-SITE.XML_ozone.om.http-address=om:9874
-OZONE-SITE.XML_ozone.scm.container.size=1GB
+
 OZONE-SITE.XML_ozone.scm.pipeline.creation.interval=30s
 OZONE-SITE.XML_ozone.scm.pipeline.owner.container.count=1
 OZONE-SITE.XML_ozone.scm.names=scm
 OZONE-SITE.XML_ozone.scm.datanode.id.dir=/data
 OZONE-SITE.XML_ozone.scm.block.client.address=scm
-OZONE-SITE.XML_ozone.metadata.dirs=/data/metadata
-OZONE-SITE.XML_ozone.recon.db.dir=/data/metadata/recon
+OZONE-SITE.XML_ozone.scm.container.size=1GB
 OZONE-SITE.XML_ozone.scm.client.address=scm
+
 OZONE-SITE.XML_hdds.datanode.dir=/data/hdds
-OZONE-SITE.XML_ozone.recon.address=recon:9891
+
+OZONE-SITE.XML_ozone.recon.address=recon:9888
+OZONE-SITE.XML_ozone.recon.db.dir=/data/metadata/recon
 OZONE-SITE.XML_ozone.recon.om.snapshot.task.interval.delay=1m
 
 OZONE_CONF_DIR=/etc/hadoop
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/0.5.0/test.sh b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/load.sh
similarity index 75%
rename from hadoop-ozone/dist/src/main/compose/upgrade/0.5.0/test.sh
rename to hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/load.sh
index 11530c7..a8980e7 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/0.5.0/test.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/compose/non-ha/load.sh
@@ -15,10 +15,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-_mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+# Fail if required variables are not set.
+set -u
+: "${OZONE_VOLUME}"
+: "${TEST_DIR}"
+set +u
 
-export OZONE_UPGRADE_FROM="$(basename ${_mydir})"
-export RESULT_DIR="${_mydir}/result"
+source "$TEST_DIR/testlib.sh"
 
-cd "${_mydir}/.."
-source upgrade_to_current.sh
+export COMPOSE_FILE="$TEST_DIR/compose/non-ha/docker-compose.yaml"
+create_data_dirs "${OZONE_VOLUME}"/{om,dn1,dn2,dn3,recon,s3g,scm}
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/test.sh b/hadoop-ozone/dist/src/main/compose/upgrade/test.sh
index 0c63a67..2857c1a 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/test.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/test.sh
@@ -15,18 +15,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
-ALL_RESULT_DIR="$SCRIPT_DIR/result"
-mkdir -p "$ALL_RESULT_DIR"
-rm "$ALL_RESULT_DIR"/* || true
-source "$SCRIPT_DIR/../testlib.sh"
+# Version that will be run using the local build.
+: "${OZONE_CURRENT_VERSION:=1.1.0}"
+export OZONE_CURRENT_VERSION
 
-tests=$(find_tests)
-cd "$SCRIPT_DIR"
+TEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
+source "$TEST_DIR/testlib.sh"
 
-run_test_scripts ${tests}
-RESULT=$?
+# Export variables needed by tests and ../testlib.sh.
+export TEST_DIR
+export COMPOSE_DIR="$TEST_DIR"
 
-generate_report "upgrade" "${ALL_RESULT_DIR}"
+RESULT_DIR="$ALL_RESULT_DIR" create_results_dir
 
-exit ${RESULT}
+# Upgrade tests to be run.
+# Run all upgrades even if one fails.
+# Any failure will save a failing return code to $RESULT.
+set +e
+run_test manual-upgrade 0.5.0 1.1.0
+run_test non-rolling-upgrade 1.0.0 1.1.0
+set -e
+
+generate_report "upgrade" "$ALL_RESULT_DIR"
+
+exit "$RESULT"
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/testlib.sh b/hadoop-ozone/dist/src/main/compose/upgrade/testlib.sh
index 1c6cfe6..ab64e95 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/testlib.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/testlib.sh
@@ -17,64 +17,133 @@
 
 set -e -o pipefail
 
+# Fail if required variables are not set.
+set -u
+: "${OZONE_CURRENT_VERSION}"
+set +u
+
 _upgrade_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 
+# Cumulative result of all tests run with run_test function.
+# 0 if all passed, 1 if any failed.
+: "${RESULT:=0}"
 : "${OZONE_REPLICATION_FACTOR:=3}"
-: "${OZONE_VOLUME:="${COMPOSE_DIR}/data"}"
 : "${OZONE_VOLUME_OWNER:=}"
+: "${OZONE_CURRENT_VERSION:=}"
+: "${ALL_RESULT_DIR:="$_upgrade_dir"/result}"
+
+# export for docker-compose
+export OZONE_REPLICATION_FACTOR
 
 source "${_upgrade_dir}/../testlib.sh"
 
 ## @description Create the directory tree required for persisting data between
 ##   compose cluster restarts
-create_data_dir() {
+create_data_dirs() {
+  local dirs_to_create="$@"
+
   if [[ -z "${OZONE_VOLUME}" ]]; then
     return 1
   fi
 
   rm -fr "${OZONE_VOLUME}" 2> /dev/null || sudo rm -fr "${OZONE_VOLUME}"
-  mkdir -p "${OZONE_VOLUME}"/{dn1,dn2,dn3,om,recon,s3g,scm}
+  mkdir -p $dirs_to_create
   fix_data_dir_permissions
 }
 
-## @description Run upgrade steps required for going from one logical version to another.
-## @param Starting logical version
-## @param Target logical version
-execute_upgrade_steps() {
-  local -i from=$1
-  local -i to=$2
+## @description Prepares to run an image with `start_docker_env`.
+## @param the version of Ozone to be run.
+##   If this is equal to `OZONE_CURRENT_VERSION`, then the ozone runner image wil be used.
+##   Else, a binary image will be used.
+prepare_for_image() {
+  local image_version="$1"
 
-  if [[ ${from} -ge ${to} ]]; then
-    return
+  if [[ "$image_version" = "$OZONE_CURRENT_VERSION" ]]; then
+      prepare_for_runner_image
+  else
+      prepare_for_binary_image "$image_version"
   fi
+}
 
-  pushd ${_testlib_dir}/../libexec/upgrade
+## @description Runs a callback function only if it exists.
+## @param The name of the function to run.
+callback() {
+  local func="$1"
+  if [[ "$(type -t "$func")" = function ]]; then
+    "$func"
+  else
+    echo "Skipping callback $func. No function implementation found."
+  fi
+}
+
+## @description Sets up and runs the test defined by "$1"/test.sh.
+## @param The directory for the upgrade type whose test.sh file will be run.
+## @param The version of Ozone to upgrade from.
+## @param The version of Ozone to upgrade to.
+run_test() {
+  # Export variables needed by test, since it is run in a subshell.
+  local test_dir="$_upgrade_dir/upgrades/$1"
+  export OZONE_UPGRADE_FROM="$2"
+  export OZONE_UPGRADE_TO="$3"
+  local test_subdir="$test_dir"/"$OZONE_UPGRADE_FROM"-"$OZONE_UPGRADE_TO"
+  export OZONE_UPGRADE_CALLBACK="$test_subdir"/callback.sh
+  export OZONE_VOLUME="$test_subdir"/data
+  export RESULT_DIR="$test_subdir"/result
+
+  if ! run_test_script "$test_dir" ./driver.sh; then
+    RESULT=1
+  fi
 
-  local v
-  for v in $(seq ${from} $((to-1))); do
-    if [[ -e "v$v.sh" ]]; then
-      source "v$v.sh"
+  generate_report 'upgrade' "$RESULT_DIR"
+  copy_results "$test_subdir" "$ALL_RESULT_DIR"
+}
+
+## @description Generates data on the cluster.
+## @param The prefix to use for data generated.
+generate() {
+    execute_robot_test scm -v PREFIX:"$1" upgrade/generate.robot
+}
+
+## @description Validates that data exists on the cluster.
+## @param The prefix of the data to be validated.
+validate() {
+    execute_robot_test scm -v PREFIX:"$1" upgrade/validate.robot
+}
+
+## @description Checks that the metadata layout version of the provided node matches what is expected.
+## @param The name of the docker-compose service to run the check on.
+## @param The path to the VERSION file in the container.
+## @param The metadata layout version expected for that service.
+check_mlv() {
+    service="$1"
+    container_id="$(docker container ps --quiet --filter "name=$service")"
+
+    # If some containers go down during the test run due to resources issues,
+    # just print a message instead of failing the test.
+    if  [[ -n "$container_id" ]]; then
+      execute_robot_test "$service" -v VERSION_FILE:"$2" -v VERSION:"$3" upgrade/check-mlv.robot
+    else
+      echo "No matching containers for docker-compose service $service found. Skipping MLV check."
     fi
-  done
+}
 
-  popd
+## @description Checks that the metadata layout version of a datanode matches what is expected.
+## @param The name of the docker-compose service to run the check on.
+## @param The metadata layout version expected for that service.
+check_dn_mlv() {
+  check_mlv "$1" /data/metadata/dnlayoutversion/VERSION "$2"
 }
 
-## @description Pre-upgrade test steps
-first_run() {
-  start_docker_env
-  execute_robot_test scm -v PREFIX:pre freon/generate.robot
-  execute_robot_test scm -v PREFIX:pre freon/validate.robot
-  KEEP_RUNNING=false stop_docker_env
+## @description Checks that the metadata layout version of an OM matches what is expected.
+## @param The name of the docker-compose service to run the check on.
+## @param The metadata layout version expected for that service.
+check_om_mlv() {
+  check_mlv "$1" /data/metadata/om/current/VERSION "$2"
 }
 
-## @description Post-upgrade test steps
-second_run() {
-  export OZONE_KEEP_RESULTS=true
-  start_docker_env
-  execute_robot_test scm -v PREFIX:pre freon/validate.robot
-  # test write key to old bucket after upgrade
-  execute_robot_test scm -v PREFIX:post freon/generate.robot
-  execute_robot_test scm -v PREFIX:post freon/validate.robot
-  stop_docker_env
+## @description Checks that the metadata layout version of an SCM matches what is expected.
+## @param The name of the docker-compose service to run the check on.
+## @param The metadata layout version expected for that service.
+check_scm_mlv() {
+  check_mlv "$1" /data/metadata/scm/current/VERSION "$2"
 }
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_current.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_current.sh
deleted file mode 100755
index 8728851..0000000
--- a/hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_current.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env bash
-# 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
-#
-#     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.
-
-# This script tests upgrade from a previous release to the current
-# binaries.  Docker image with Ozone binaries is required for the
-# initial version, while the snapshot version uses Ozone runner image.
-
-set -e -o pipefail
-
-COMPOSE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-export COMPOSE_DIR
-
-: "${OZONE_REPLICATION_FACTOR:=3}"
-: "${OZONE_UPGRADE_FROM:="0.5.0"}"
-: "${OZONE_VOLUME:="${COMPOSE_DIR}/data"}"
-
-export OZONE_REPLICATION_FACTOR OZONE_UPGRADE_FROM OZONE_VOLUME
-
-current_version=1.1.0
-
-source "${COMPOSE_DIR}/testlib.sh"
-
-create_data_dir
-
-prepare_for_binary_image "${OZONE_UPGRADE_FROM}"
-load_version_specifics "${OZONE_UPGRADE_FROM}"
-first_run
-unload_version_specifics
-
-from=$(get_logical_version "${OZONE_UPGRADE_FROM}")
-to=$(get_logical_version "${current_version}")
-execute_upgrade_steps "$from" "$to"
-
-prepare_for_runner_image
-second_run
-
-generate_report
diff --git a/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/0.5.0-1.1.0/callback.sh
old mode 100644
new mode 100755
similarity index 64%
copy from hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh
copy to hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/0.5.0-1.1.0/callback.sh
index f973a04..d2f43de
--- a/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/0.5.0-1.1.0/callback.sh
@@ -15,16 +15,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ozone_logical_version() {
-  echo 1
+source "$TEST_DIR"/testlib.sh
+
+setup_old_version() {
+  load_version_specifics "$OZONE_UPGRADE_FROM"
+}
+
+with_old_version() {
+  generate old
+  validate old
 }
 
-ozone_version_load() {
-  export OZONE_ADMIN_COMMAND=scmcli
-  export OZONE_SAFEMODE_STATUS_COMMAND='ozone scmcli safemode status'
+setup_new_version() {
+  unload_version_specifics "$OZONE_UPGRADE_FROM"
+  # Reformat SCM DB from 0.5.0 to format for versions after 1.0.0.
+  "$TEST_DIR"/../../libexec/upgrade/1.0.0.sh
+  load_version_specifics "$OZONE_UPGRADE_TO"
 }
 
-ozone_version_unload() {
-  unset OZONE_ADMIN_COMMAND
-  unset OZONE_SAFEMODE_STATUS_COMMAND
+with_new_version() {
+  validate old
+  generate new
+  validate new
 }
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_release.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/driver.sh
similarity index 50%
rename from hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_release.sh
rename to hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/driver.sh
index 5a9b402..de016bf 100755
--- a/hadoop-ozone/dist/src/main/compose/upgrade/upgrade_to_release.sh
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/manual-upgrade/driver.sh
@@ -20,32 +20,37 @@
 
 set -e -o pipefail
 
-COMPOSE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-export COMPOSE_DIR
-
-: "${OZONE_REPLICATION_FACTOR:=3}"
-: "${OZONE_UPGRADE_FROM:="0.5.0"}"
-: "${OZONE_UPGRADE_TO:="1.0.0"}"
-: "${OZONE_VOLUME:="${COMPOSE_DIR}/data"}"
-
-export OZONE_REPLICATION_FACTOR OZONE_UPGRADE_FROM OZONE_UPGRADE_TO OZONE_VOLUME
-
-source "${COMPOSE_DIR}/testlib.sh"
-
-create_data_dir
-
-prepare_for_binary_image "${OZONE_UPGRADE_FROM}"
-load_version_specifics "${OZONE_UPGRADE_FROM}"
-first_run
-unload_version_specifics
-
-from=$(get_logical_version "${OZONE_UPGRADE_FROM}")
-to=$(get_logical_version "${OZONE_UPGRADE_TO}")
-execute_upgrade_steps "$from" "$to"
-
-prepare_for_binary_image "${OZONE_UPGRADE_TO}"
-load_version_specifics "${OZONE_UPGRADE_TO}"
-second_run
-unload_version_specifics
-
-generate_report
+# Fail if required vars are not set.
+set -u
+: "${OZONE_UPGRADE_FROM}"
+: "${OZONE_UPGRADE_TO}"
+: "${TEST_DIR}"
+: "${OZONE_UPGRADE_CALLBACK}"
+set +u
+
+source "$TEST_DIR"/compose/non-ha/load.sh
+source "$TEST_DIR"/testlib.sh
+[[ -f "$OZONE_UPGRADE_CALLBACK" ]] && source "$OZONE_UPGRADE_CALLBACK"
+
+echo "--- RUNNING MANUAL UPGRADE TEST FROM $OZONE_UPGRADE_FROM TO $OZONE_UPGRADE_TO ---"
+
+echo "--- SETTING UP OLD VERSION $OZONE_UPGRADE_FROM ---"
+OUTPUT_NAME="$OZONE_UPGRADE_FROM"
+prepare_for_image "$OZONE_UPGRADE_FROM"
+callback setup_old_version
+
+echo "--- RUNNING WITH OLD VERSION $OZONE_UPGRADE_FROM ---"
+start_docker_env
+callback with_old_version
+stop_docker_env
+
+echo "--- SETTING UP NEW VERSION $OZONE_UPGRADE_TO ---"
+OUTPUT_NAME="$OZONE_UPGRADE_TO"
+prepare_for_image "$OZONE_UPGRADE_TO"
+callback setup_new_version
+
+echo "--- RUNNING WITH NEW VERSION $OZONE_UPGRADE_TO ---"
+OZONE_KEEP_RESULTS=true start_docker_env
+callback with_new_version
+
+stop_docker_env
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.0.0-1.1.0/callback.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.0.0-1.1.0/callback.sh
new file mode 100755
index 0000000..dae4953
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/1.0.0-1.1.0/callback.sh
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+# 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
+#
+#     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.
+
+source "$TEST_DIR"/testlib.sh
+
+# Helper function, not a callback.
+_check_hdds_mlvs() {
+  mlv="$1"
+  check_scm_mlv scm "$mlv"
+  check_dn_mlv dn1 "$mlv"
+  check_dn_mlv dn2 "$mlv"
+  check_dn_mlv dn3 "$mlv"
+}
+
+# Helper function, not a callback.
+_check_om_mlvs() {
+  mlv="$1"
+  check_om_mlv om1 "$mlv"
+  check_om_mlv om2 "$mlv"
+  check_om_mlv om3 "$mlv"
+}
+
+setup() {
+  # OM preparation is not implemented until 1.2.0.
+  export OZONE_OM_PREPARE='false'
+  load_version_specifics "$OZONE_UPGRADE_FROM"
+}
+
+with_old_version() {
+  generate old1
+  validate old1
+}
+
+with_new_version_pre_finalized() {
+  _check_hdds_mlvs 0
+  _check_om_mlvs 0
+
+  validate old1
+
+  generate new1
+  validate new1
+}
+
+# TODO: Run when 1.1.0 is released.
+# with_old_version_downgraded() {
+#   validate old1
+#   validate new1
+
+#   generate old2
+#   validate old2
+# }
+
+with_new_version_finalized() {
+  _check_hdds_mlvs 2
+  # OM currently only has one layout version.
+  _check_om_mlvs 0
+
+  validate old1
+  validate new1
+  # TODO: Run when 1.1.0 is released.
+  #validate old2
+
+  generate new2
+  validate new2
+}
diff --git a/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/driver.sh b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/driver.sh
new file mode 100755
index 0000000..1fcb904
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/compose/upgrade/upgrades/non-rolling-upgrade/driver.sh
@@ -0,0 +1,101 @@
+#!/usr/bin/env bash
+# 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
+#
+#     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.
+
+# This script tests upgrade from a previous release to the current
+# binaries.  Docker image with Ozone binaries is required for the
+# initial version, while the snapshot version uses Ozone runner image.
+
+set -e -o pipefail
+
+# Fail if required vars are not set.
+set -u
+: "${OZONE_UPGRADE_FROM}"
+: "${OZONE_UPGRADE_TO}"
+: "${TEST_DIR}"
+: "${OZONE_UPGRADE_CALLBACK}"
+set +u
+
+echo "--- RUNNING NON-ROLLING UPGRADE TEST FROM $OZONE_UPGRADE_FROM TO $OZONE_UPGRADE_TO ---"
+
+# Prepare OMs before upgrade unless this variable is not 'true'.
+: "${OZONE_PREPARE_OMS:='true'}"
+
+# Default compose cluster to use. May be overridden by callback.sh.
+source "$TEST_DIR"/compose/ha/load.sh
+source "$TEST_DIR"/testlib.sh
+[[ -f "$OZONE_UPGRADE_CALLBACK" ]] && source "$OZONE_UPGRADE_CALLBACK"
+
+prepare_oms() {
+  if [[ "$OZONE_PREPARE_OMS" = 'true' ]]; then
+    execute_robot_test scm upgrade/prepare.robot
+  fi
+}
+
+set_downgrade_om_args() {
+  if [[ "$OZONE_PREPARE_OMS" = 'true' ]]; then
+    export OM_HA_ARGS='--downgrade'
+  else
+    export OM_HA_ARGS='--'
+  fi
+}
+
+echo "--- SETTING UP OLD VERSION $OZONE_UPGRADE_FROM ---"
+OUTPUT_NAME="$OZONE_UPGRADE_FROM"
+callback setup
+export OM_HA_ARGS='--'
+prepare_for_image "$OZONE_UPGRADE_FROM"
+
+echo "--- RUNNING WITH OLD VERSION $OZONE_UPGRADE_FROM ---"
+start_docker_env
+callback with_old_version
+
+prepare_oms
+stop_docker_env
+prepare_for_image "$OZONE_UPGRADE_TO"
+export OM_HA_ARGS='--upgrade'
+
+echo "--- RUNNING WITH NEW VERSION $OZONE_UPGRADE_TO PRE-FINALIZED ---"
+OUTPUT_NAME="$OZONE_UPGRADE_TO"
+OZONE_KEEP_RESULTS=true start_docker_env
+callback with_new_version_pre_finalized
+
+# TODO: Start testing downgrades when 1.1.0 is released.
+# prepare_oms
+# stop_docker_env
+# prepare_for_image "$OZONE_UPGRADE_FROM"
+# set_downgrade_om_args
+
+# echo "--- RUNNING WITH OLD VERSION $OZONE_UPGRADE_FROM AFTER DOWNGRADE ---"
+# OUTPUT_NAME="$OZONE_UPGRADE_FROM"-downgraded
+# OZONE_KEEP_RESULTS=true start_docker_env
+# callback with_old_version_downgraded
+
+# prepare_oms
+# stop_docker_env
+# prepare_for_image "$OZONE_UPGRADE_TO"
+# export OM_HA_ARGS='--upgrade'
+
+echo "--- RUNNING WITH NEW VERSION $OZONE_UPGRADE_TO FINALIZED ---"
+# OUTPUT_NAME="$OZONE_UPGRADE_TO"-finalized
+# OZONE_KEEP_RESULTS=true start_docker_env
+
+# Sends commands to finalize OM and SCM.
+execute_robot_test scm upgrade/finalize.robot
+callback with_new_version_finalized
+
+stop_docker_env
+generate_report
diff --git a/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh b/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh
index f973a04..3c76415 100644
--- a/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh
+++ b/hadoop-ozone/dist/src/main/compose/versions/0.5.0.sh
@@ -15,10 +15,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ozone_logical_version() {
-  echo 1
-}
-
 ozone_version_load() {
   export OZONE_ADMIN_COMMAND=scmcli
   export OZONE_SAFEMODE_STATUS_COMMAND='ozone scmcli safemode status'
diff --git a/hadoop-ozone/dist/src/main/compose/versions/1.0.0.sh b/hadoop-ozone/dist/src/main/compose/versions/1.0.0.sh
index c56aa33..9565b95 100644
--- a/hadoop-ozone/dist/src/main/compose/versions/1.0.0.sh
+++ b/hadoop-ozone/dist/src/main/compose/versions/1.0.0.sh
@@ -15,10 +15,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ozone_logical_version() {
-  echo 2
-}
-
 ozone_version_load() {
   export OZONE_ADMIN_COMMAND=admin
   export OZONE_SAFEMODE_STATUS_COMMAND='ozone admin safemode status --verbose'
diff --git a/hadoop-ozone/dist/src/main/compose/versions/1.1.0.sh b/hadoop-ozone/dist/src/main/compose/versions/1.1.0.sh
index c56aa33..9565b95 100644
--- a/hadoop-ozone/dist/src/main/compose/versions/1.1.0.sh
+++ b/hadoop-ozone/dist/src/main/compose/versions/1.1.0.sh
@@ -15,10 +15,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ozone_logical_version() {
-  echo 2
-}
-
 ozone_version_load() {
   export OZONE_ADMIN_COMMAND=admin
   export OZONE_SAFEMODE_STATUS_COMMAND='ozone admin safemode status --verbose'
diff --git a/hadoop-ozone/dist/src/main/compose/versions/README.md b/hadoop-ozone/dist/src/main/compose/versions/README.md
index f6dc62c..c974adc 100644
--- a/hadoop-ozone/dist/src/main/compose/versions/README.md
+++ b/hadoop-ozone/dist/src/main/compose/versions/README.md
@@ -14,10 +14,7 @@
 
 The scripts in this directory define version-specific behavior required for [`testlib.sh`](../testlib.sh).  For example the `ozone admin` command was renamed from `ozone scmcli` in 1.0.0.
 
-For each release a logical version is defined, starting from 1.  It is incremented only if the new version needs to execute some scripts to handle some (unintended) incompatibility.  For example 1.0.0 or later need to rename some RocksDB column-families when upgrading from 0.5.0.
-
 Interface:
 
- * `ozone_logical_version`: print the logical version
  * `ozone_version_load`: define version-specific variables for the test library
  * `ozone_version_unload`: unset version-specific variables; this reverts test library behavior to the "current" one.
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/check-mlv.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/check-mlv.robot
new file mode 100644
index 0000000..271b6dd
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/check-mlv.robot
@@ -0,0 +1,41 @@
+# 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
+#
+#     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.
+
+*** Settings ***
+Documentation       Check Metadata layout version present in a version file.
+Library             OperatingSystem
+Library             BuiltIn
+Resource            ../commonlib.robot
+Test Timeout        5 minutes
+
+*** Variables ***
+${version_prefix}    layoutVersion=
+
+*** Keywords ***
+Check version
+    ${version_file_contents} =    Get file    ${VERSION_FILE}
+    ${version_line} =    Catenate    SEPARATOR=   ${version_prefix}    ${VERSION}
+    Should contain    ${version_file_contents}    ${version_line}
+
+*** Test Cases ***
+Check MLV
+    # Fail if required variables are not set.
+    Should not be empty    ${VERSION_FILE}
+    Should not be empty    ${VERSION}
+
+    File should exist    ${VERSION_FILE}
+    File should not be empty    ${VERSION_FILE}
+
+    Wait until keyword succeeds    3min    10sec    Check version
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot
new file mode 100644
index 0000000..288f9c0
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/finalize.robot
@@ -0,0 +1,31 @@
+# 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
+#
+#     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.
+
+*** Settings ***
+Documentation       Finalize Upgrade of OMs and SCM
+Resource            ../commonlib.robot
+Test Timeout        5 minutes
+Test Setup          Run Keyword if    '${SECURITY_ENABLED}' == 'true'    Kinit test user     testuser     testuser.keytab
+
+** Test Cases ***
+Finalize SCM
+    ${result} =        Execute      ozone admin scm finalizeupgrade
+                       #Wait Until Keyword Succeeds      3min       10sec     Should contain   ${result}   OM Preparation successful!
+                       Log    ${result}
+
+Finalize OMs
+    ${result} =        Execute      ozone admin om finalizeupgrade -id %{OM_SERVICE_ID}
+                       #Wait Until Keyword Succeeds      3min       10sec     Should contain   ${result}   OM Preparation successful!
+                       Log    ${result}
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/generate.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/generate.robot
new file mode 100644
index 0000000..0a14604
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/generate.robot
@@ -0,0 +1,33 @@
+# 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
+#
+#     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.
+
+*** Settings ***
+Documentation       Generate data
+Library             OperatingSystem
+Library             BuiltIn
+Resource            ../commonlib.robot
+Test Timeout        5 minutes
+
+*** Variables ***
+
+
+*** Test Cases ***
+Create a volume, bucket and key
+    ${output} =         Execute          ozone sh volume create ${PREFIX}-volume
+                        Should not contain  ${output}       Failed
+    ${output} =         Execute          ozone sh bucket create /${PREFIX}-volume/${PREFIX}-bucket
+                        Should not contain  ${output}       Failed
+    ${output} =         Execute          ozone sh key put /${PREFIX}-volume/${PREFIX}-bucket/${PREFIX}-key /opt/hadoop/NOTICE.txt
+                        Should not contain  ${output}       Failed
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/prepare.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/prepare.robot
new file mode 100644
index 0000000..0f6d7a0
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/prepare.robot
@@ -0,0 +1,26 @@
+# 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
+#
+#     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.
+
+*** Settings ***
+Documentation       Prepares OMs
+Resource            ../commonlib.robot
+Test Timeout        5 minutes
+Test Setup          Run Keyword if    '${SECURITY_ENABLED}' == 'true'    Kinit test user     testuser     testuser.keytab
+
+** Test Cases ***
+Prepare Ozone Manager
+    ${result} =        Execute      ozone admin om prepare -id %{OM_SERVICE_ID}
+                       Wait Until Keyword Succeeds      3min       10sec     Should contain   ${result}   OM Preparation successful!
+
diff --git a/hadoop-ozone/dist/src/main/smoketest/upgrade/validate.robot b/hadoop-ozone/dist/src/main/smoketest/upgrade/validate.robot
new file mode 100644
index 0000000..4461ddf
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/upgrade/validate.robot
@@ -0,0 +1,30 @@
+# 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
+#
+#     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.
+
+*** Settings ***
+Documentation       Smoketest ozone cluster startup
+Library             OperatingSystem
+Library             BuiltIn
+Resource            ../commonlib.robot
+Test Timeout        5 minutes
+
+*** Variables ***
+
+
+*** Test Cases ***
+Read data from previously created key
+    ${random} =         Generate Random String  5  [NUMBERS]
+    ${output} =         Execute          ozone sh key get /${PREFIX}-volume/${PREFIX}-bucket/${PREFIX}-key /tmp/key-${random}
+                        Should not contain  ${output}       Failed
diff --git a/hadoop-ozone/dist/src/shell/upgrade/v1.sh b/hadoop-ozone/dist/src/shell/upgrade/1.0.0.sh
similarity index 85%
rename from hadoop-ozone/dist/src/shell/upgrade/v1.sh
rename to hadoop-ozone/dist/src/shell/upgrade/1.0.0.sh
index 1442ffd..6573978 100755
--- a/hadoop-ozone/dist/src/shell/upgrade/v1.sh
+++ b/hadoop-ozone/dist/src/shell/upgrade/1.0.0.sh
@@ -20,4 +20,4 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 : "${SCM_DIR:="${OZONE_VOLUME}/scm"}"
 : "${OZONE_RUNNER_VERSION:="20200625-1"}"
 
-docker run --rm -v "${SCM_DIR}":/scm -v "${SCRIPT_DIR}/v1":/upgrade -w /scm/metadata apache/ozone-runner:"${OZONE_RUNNER_VERSION}" /upgrade/01-migrate-scm-db.sh
+docker run --rm -v "${SCM_DIR}":/scm -v "${SCRIPT_DIR}/1.0.0":/upgrade -w /scm/metadata apache/ozone-runner:"${OZONE_RUNNER_VERSION}" /upgrade/01-migrate-scm-db.sh
diff --git a/hadoop-ozone/dist/src/shell/upgrade/v1/01-migrate-scm-db.sh b/hadoop-ozone/dist/src/shell/upgrade/1.0.0/01-migrate-scm-db.sh
similarity index 100%
rename from hadoop-ozone/dist/src/shell/upgrade/v1/01-migrate-scm-db.sh
rename to hadoop-ozone/dist/src/shell/upgrade/1.0.0/01-migrate-scm-db.sh

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org