@Test
  public void testHostVersionsOutOfSyncAfterRevert() throws Exception {
    String hostName = "h1";
    Cluster cluster = createUpgradeCluster(repositoryVersion2110, hostName);
    createHostVersions(repositoryVersion2111, hostName);

    // Install ZK with some components (HBase is installed later to test the
    // logic of revert)
    Service zk = installService(cluster, "ZOOKEEPER", repositoryVersion2110);
    addServiceComponent(cluster, zk, "ZOOKEEPER_SERVER");
    addServiceComponent(cluster, zk, "ZOOKEEPER_CLIENT");
    createNewServiceComponentHost(cluster, "ZOOKEEPER", "ZOOKEEPER_SERVER", hostName);
    createNewServiceComponentHost(cluster, "ZOOKEEPER", "ZOOKEEPER_CLIENT", hostName);

    List<HostVersionEntity> hostVersions = hostVersionDAO.findAll();
    assertEquals(2, hostVersions.size());

    // repo 2110 - CURRENT
    // repo 2111 - CURRENT (PATCH)
    for (HostVersionEntity hostVersion : hostVersions) {
      hostVersion.setState(RepositoryVersionState.CURRENT);

      hostVersionDAO.merge(hostVersion);
    }

    // convert the repository into a PATCH repo (which should have ZK and HBase
    // as available services)
    repositoryVersion2111.setParent(repositoryVersion2110);
    repositoryVersion2111.setType(RepositoryType.PATCH);
    repositoryVersion2111.setVersionXml(hostName);
    repositoryVersion2111.setVersionXsd("version_definition.xsd");

    File patchVdfFile = new File("src/test/resources/hbase_version_test.xml");
    repositoryVersion2111.setVersionXml(
        IOUtils.toString(new FileInputStream(patchVdfFile), Charset.defaultCharset()));

    repositoryVersion2111 = repositoryVersionDAO.merge(repositoryVersion2111);

    // pretend like we patched
    UpgradeEntity upgrade = createUpgrade(cluster, repositoryVersion2111);
    upgrade.setOrchestration(RepositoryType.PATCH);
    upgrade.setRevertAllowed(true);
    upgrade = upgradeDAO.merge(upgrade);

    // add a service on the parent repo to cause the OUT_OF_SYNC on revert
    Service hbase = installService(cluster, "HBASE", repositoryVersion2110);
    addServiceComponent(cluster, hbase, "HBASE_MASTER");
    createNewServiceComponentHost(cluster, "HBASE", "HBASE_MASTER", hostName);

    // revert the patch
    UpgradeEntity revert = createRevert(cluster, upgrade);
    assertEquals(RepositoryType.PATCH, revert.getOrchestration());

    // push all services to the revert repo version for finalize
    Map<String, Service> services = cluster.getServices();
    assertTrue(services.size() > 0);
    for (Service service : services.values()) {
      service.setDesiredRepositoryVersion(repositoryVersion2110);
    }

    // push all components to the revert version
    List<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findByHost(hostName);
    for (HostComponentStateEntity hostComponentState : hostComponentStates) {
      hostComponentState.setVersion(repositoryVersion2110.getVersion());
      hostComponentStateDAO.merge(hostComponentState);
    }

    Map<String, String> commandParams = new HashMap<>();
    ExecutionCommand executionCommand = new ExecutionCommand();
    executionCommand.setCommandParams(commandParams);
    executionCommand.setClusterName(clusterName);

    HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
    hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));

    finalizeUpgradeAction.setExecutionCommand(executionCommand);
    finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand);

    // finalize
    CommandReport report = finalizeUpgradeAction.execute(null);
    assertNotNull(report);
    assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus());

    for (HostVersionEntity hostVersion : hostVersions) {
      RepositoryVersionEntity hostRepoVersion = hostVersion.getRepositoryVersion();
      if (repositoryVersion2110.equals(hostRepoVersion)) {
        assertEquals(RepositoryVersionState.CURRENT, hostVersion.getState());
      } else {
        assertEquals(RepositoryVersionState.OUT_OF_SYNC, hostVersion.getState());
      }
    }
  }
Tests the case where a revert happens on a patch upgrade and a new service
has been added which causes the repository to go OUT_OF_SYNC.

@throws Exception
ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java