@Test
public void testMixedComponentVersions() throws Exception {

  StackId sourceStack = HDP_21_STACK;
  StackId targetStack = HDP_22_STACK;
  String sourceRepo = HDP_2_1_1_0;
  String targetRepo = HDP_2_2_1_0;
  String clusterName = "c1";
  String hostName = "h1";
  makeCrossStackUpgradeCluster(sourceStack, sourceRepo, targetStack, targetRepo, clusterName, hostName);
  Clusters clusters = m_injector.getInstance(Clusters.class);
  Cluster cluster = clusters.getCluster("c1");
  Service service = installService(cluster, "HDFS");
  addServiceComponent(cluster, service, "NAMENODE");
  addServiceComponent(cluster, service, "DATANODE");
  createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", "h1");
  createNewServiceComponentHost(cluster, "HDFS", "DATANODE", "h1");
  createNewRepoVersion(targetStack, targetRepo, clusterName, hostName);
  // create some configs
  createConfigs(cluster);
  // setup the cluster for the upgrade across stacks
  cluster.setCurrentStackVersion(sourceStack);
  cluster.setDesiredStackVersion(targetStack);
  // set the SCH versions to the new stack so that the finalize action is
  // happy
  cluster.getServiceComponentHosts("HDFS", "NAMENODE").get(0).setVersion(targetRepo);
  // don't update DATANODE - we want to make the action complain
  // inject an unhappy path where the cluster repo version is still UPGRADING
  // even though all of the hosts are UPGRADED
  ClusterVersionEntity upgradingClusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(
      "c1", HDP_22_STACK, targetRepo);
  upgradingClusterVersion.setState(RepositoryVersionState.INSTALLING);
  upgradingClusterVersion = clusterVersionDAO.merge(upgradingClusterVersion);
  // verify the conditions for the test are met properly
  upgradingClusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion("c1", HDP_22_STACK, targetRepo);
  List<HostVersionEntity> hostVersions = hostVersionDAO.findByClusterStackAndVersion("c1", HDP_22_STACK, targetRepo);
  assertEquals(RepositoryVersionState.INSTALLING, upgradingClusterVersion.getState());
  assertTrue(hostVersions.size() > 0);
  for (HostVersionEntity hostVersion : hostVersions) {
    assertEquals(RepositoryVersionState.INSTALLED, hostVersion.getState());
  }
  // now finalize and ensure we can transition from UPGRADING to UPGRADED
  // automatically before CURRENT
  Map<String, String> commandParams = new HashMap<String, String>();
  commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
  commandParams.put(FinalizeUpgradeAction.VERSION_KEY, targetRepo);
  commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, sourceStack.getStackId());
  commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, targetStack.getStackId());
  ExecutionCommand executionCommand = new ExecutionCommand();
  executionCommand.setCommandParams(commandParams);
  executionCommand.setClusterName("c1");
  HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
  hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
  ComponentVersionCheckAction action = m_injector.getInstance(ComponentVersionCheckAction.class);
  action.setExecutionCommand(executionCommand);
  action.setHostRoleCommand(hostRoleCommand);
  CommandReport report = action.execute(null);
  assertNotNull(report);
  assertEquals(HostRoleStatus.FAILED.name(), report.getStatus());
  assertEquals(-1, report.getExitCode());
}