def rollback_test(to_version: str, from_version: str, to_version_image: str):
    """
    Perform a rollback test between two versions of Marqo.
    This function first runs test cases in prepare mode on from_version Marqo container, then upgrades it to to_version Marqo container,
    It then downgrades (rollback) to from_version container again where it runs test cases in test mode. Finally, it triggers rollback endpoint
    to rollback vespa application (this only happens if the Marqo version running is >=2.13.0) and runs the complete test suite again.

    Args:
        to_version (str): The target version of the Marqo container.
        from_version (str): The source version of the Marqo container.
        to_version_image (str): The unique identifier for a to_version image. It can be either be the fully qualified image name with the tag
    """
    logger.info(f"Starting Marqo rollback tests with from_version: {from_version}, to_version: {to_version}, to_version_image: {to_version_image}")
    try:
        load_all_subclasses("tests.compatibility_tests")
        # Step 0: Generate a volume name to be used with the "from_version" Marqo container for state transfer.
        from_version_volume = docker_manager.get_volume_name_from_marqo_version(from_version)
        logger.info(f"Generated volume name: {from_version_volume} for from_version: {from_version}")

        # Step 1: Start a Marqo container using from_version
        docker_manager.start_marqo_container(from_version, from_version_volume)
        logger.info(f"Step 1: Started Marqo container {from_version}")

        # Step 2: Run prepare mode
        logger.info("Step 2: Running prepare mode on initial from_version container")
        run_prepare_mode(from_version)

        # Step 3: Stop Marqo from_version container started in Step #1.
        docker_manager.stop_marqo_container(from_version)
        logger.info("Step 3: Stopped Marqo container from Step #1")

        # Step 4: Upgrade to to_version container by transferring state
        logger.info(f"Step 4: Starting Marqo to_version: {to_version} container by transferring state from version: "
                    f"{from_version} to version: {to_version}")
        docker_manager.start_marqo_container_by_transferring_state(to_version, from_version, from_version_volume,
                                                    to_version_image, "ECR")

        #Step 5: Stop Marqo container from Step #4
        logger.info("Step 5: Stopping Marqo container from Step #4")
        docker_manager.stop_marqo_container(to_version)

        #Step 6: Again start a Marqo container using from_version (i.e Rollback marqo version),
        # transferring state from container in Step 4.
        logger.info(f"Step 6: Going back to marqo from_version."
                    f"Starting Marqo from_version: {from_version} container again, "
                    f"by transferring state from to_version, which was {to_version}")
        # TODO: Check from_version_volume for the case where the two versions are before and after 2.9 since we create a new volume in that case.
        prepare_volume_for_rollback(target_version=from_version, source_volume=from_version_volume, source="docker")
        docker_manager.start_marqo_container_by_transferring_state(target_version=from_version, source_version=to_version,
                                                    source_volume=from_version_volume, source="docker")

        # Step 7: Run test mode
        logger.info(f"Step 7: Running tests in test mode on from_version: {from_version}")
        run_test_mode(from_version) # This will validate results from the older indexes added as part of the PREPARE mode above.

        # Step 8: Run prepare and test mode again, on the from_version container.
        logger.info(f"Step 8: Running prepare and test mode on the same from_version: {from_version} container")
        run_prepare_mode(from_version)
        run_test_mode(from_version) # This will validate results by creating newer indexes and adding documents to them. This is required just so that we know that even after transferring state from an older version, we are able to create new indexes in the older state seamlessly.

        # Only execute the following if Marqo version >= 2.13.0. This is because the rollback endpoint is only
        # available in these versions.

        # Step 9: Trigger rollback Vespa endpoint
        if semver.VersionInfo.parse(from_version) >= semver.VersionInfo.parse("2.13.0"):
            trigger_rollback_endpoint()

            # Step 10: Run full test suite again after Vespa rollback
            try:
                logger.info(f"Running full test suite with from_version: {from_version}")
                run_prepare_mode(from_version)
                run_test_mode(from_version)
            except Exception as e:
                raise RuntimeError(
                    f"Error when running full test suite in rollback tests after rolling back vespa application, "
                    f"with from_version: {from_version}, to_version: {to_version}") from e

    finally:
        # Stop the final container (but don't remove it yet)
        logger.debug("Stopping marqo container")
        docker_manager.stop_marqo_container(from_version)
        # Clean up all containers and volumes at the end
        logger.debug("Cleaning up containers and volumes")
        docker_manager.cleanup_containers()
        docker_manager.cleanup_volumes()

    Perform a rollback test between two versions of Marqo.
    This function first runs test cases in prepare mode on from_version Marqo container, then upgrades it to to_version Marqo container,
    It then downgrades (rollback) to from_version container again where it runs test cases in test mode. Finally, it triggers rollback endpoint
    to rollback vespa application (this only happens if the Marqo version running is >=2.13.0) and runs the complete test suite again.

    Args:
        to_version (str): The target version of the Marqo container.
        from_version (str): The source version of the Marqo container.
        to_version_image (str): The unique identifier for a to_version image. It can be either be the fully qualified image name with the tag
    
tests/compatibility_tests/compatibility_test_runner.py