@Test
  public void testPartialErrorScenarioInSystemStatus() throws Throwable {

    Status readyStatus = new Status(StatusType.READY);
    setMessageAndStats(readyStatus);
    Status initializingStatus = new Status(StatusType.INITIALIZING);
    setMessageAndStats(initializingStatus);
    Status errorStatus = new Status(StatusType.ERROR);
    setMessageAndStats(errorStatus);

    mockAllClientsToReturnSameStatus(readyStatus);

    when(housekeeperClients.get(0).getStatus()).thenReturn(readyStatus);
    when(housekeeperClients.get(1).getStatus()).thenReturn(initializingStatus);
    when(housekeeperClients.get(2).getStatus()).thenReturn(errorStatus);

    SystemStatus systemStatus = client.getSystemStatus();
    assertThat(systemStatus.getComponents().size(), is(statusConfig.getComponents().size()));
    assertThat(systemStatus.getStatus(), is(StatusType.PARTIAL_ERROR));

    List<ComponentStatus> compStatuses = systemStatus.getComponents();

    for (ComponentStatus status : compStatuses) {
      if (status.getComponent().equals(Component.HOUSEKEEPER)) {
        assertThat(status.getStatus(), is(StatusType.PARTIAL_ERROR));
        assertThat(status.getStats().get(StatusType.READY.toString()), is("1"));
        assertThat(status.getStats().get(StatusType.INITIALIZING.toString()), is("1"));
        assertThat(status.getStats().get(StatusType.ERROR.toString()), is("1"));
      } else {
        assertThat(status.getStatus(), is(StatusType.READY));
        assertThat(status.getStats().get(StatusType.READY.toString()), is("3"));
      }
    }
  }
  @Test
  public void testAllComponents() throws Throwable {
    Status readyStatus = new Status(StatusType.READY);
    setMessageAndStats(readyStatus);

    mockAllClientsToReturnSameStatus(readyStatus);

    SystemStatus systemStatus = client.getSystemStatus();

    assertThat(systemStatus.getComponents().size(), is(statusConfig.getComponents().size()));
    assertThat(systemStatus.getStatus(), is(StatusType.READY));
  }
  @Test
  public void testPartialErrorWithDifferentNumOfInstances() throws Throwable {
    Status readyStatus = new Status(StatusType.READY);
    setMessageAndStats(readyStatus);
    Status initializingStatus = new Status(StatusType.INITIALIZING);
    setMessageAndStats(initializingStatus);
    Status errorStatus = new Status(StatusType.ERROR);
    setMessageAndStats(errorStatus);

    when(chairmanServerSet.getServers()).thenReturn(singleInstanceServerSets.get(0).getServers());
    when(rootSchedulerServerSet.getServers())
        .thenReturn(singleInstanceServerSets.get(1).getServers());

    mockAllClientsToReturnSameStatus(readyStatus);

    when(housekeeperClients.get(0).getStatus()).thenReturn(readyStatus);
    when(housekeeperClients.get(1).getStatus()).thenReturn(initializingStatus);
    when(housekeeperClients.get(2).getStatus()).thenReturn(errorStatus);

    SystemStatus systemStatus = client.getSystemStatus();
    assertThat(systemStatus.getComponents().size(), is(statusConfig.getComponents().size()));
    assertThat(systemStatus.getStatus(), is(StatusType.PARTIAL_ERROR));

    List<ComponentStatus> compStatuses = systemStatus.getComponents();

    for (ComponentStatus status : compStatuses) {
      if (status.getComponent().equals(Component.HOUSEKEEPER)) {
        assertThat(status.getStatus(), is(StatusType.PARTIAL_ERROR));
        assertThat(status.getStats().get(StatusType.READY.toString()), is("1"));
        assertThat(status.getStats().get(StatusType.INITIALIZING.toString()), is("1"));
        assertThat(status.getStats().get(StatusType.ERROR.toString()), is("1"));
      } else if (status.getComponent().equals(Component.CHAIRMAN)
          || status.getComponent().equals(Component.ROOT_SCHEDULER)) {
        assertThat(status.getStatus(), is(StatusType.READY));
        assertThat(status.getStats().get(StatusType.READY.toString()), is("1"));
      } else {
        assertThat(status.getStatus(), is(StatusType.READY));
        assertThat(status.getStats().get(StatusType.READY.toString()), is("3"));
      }
    }
  }
  @Test
  public void testAllInstancesInErrorState() throws Throwable {
    Status readyStatus = new Status(StatusType.READY);
    setMessageAndStats(readyStatus);
    Status initializingStatus = new Status(StatusType.INITIALIZING);
    setMessageAndStats(initializingStatus);
    Status errorStatus = new Status(StatusType.ERROR);
    setMessageAndStats(errorStatus);

    mockAllClientsToReturnSameStatus(errorStatus);

    SystemStatus systemStatus = client.getSystemStatus();
    assertThat(systemStatus.getComponents().size(), is(statusConfig.getComponents().size()));
    assertThat(systemStatus.getStatus(), is(StatusType.ERROR));

    List<ComponentStatus> compStatuses = systemStatus.getComponents();

    for (ComponentStatus status : compStatuses) {
      assertThat(status.getStatus(), is(StatusType.ERROR));
      assertThat(status.getStats().get(StatusType.ERROR.toString()), is("3"));
    }
  }
  @Test
  public void testEmptyServerSet() throws Throwable {
    Status readyStatus = new Status(StatusType.READY);
    setMessageAndStats(readyStatus);
    when(deployerServerSet.getServers()).thenReturn(new HashSet<>());

    mockAllClientsToReturnSameStatus(readyStatus);

    SystemStatus systemStatus = client.getSystemStatus();

    assertThat(systemStatus.getComponents().size(), is(5));
    assertThat(systemStatus.getStatus(), is(StatusType.ERROR));

    ComponentStatus deployerComponent =
        systemStatus
            .getComponents()
            .stream()
            .filter(c -> Component.DEPLOYER.equals(c.getComponent()))
            .findFirst()
            .get();
    assertThat(deployerComponent, notNullValue());
    assertThat(deployerComponent.getStatus(), is(StatusType.UNREACHABLE));
    assertThat(deployerComponent.getMessage(), is("Empty ServerSet"));
  }
  private void prepareStatusFeClient() throws Throwable {

    client =
        new StatusFeClient(
            executor,
            housekeeperServerSet,
            chairmanServerSet,
            rootSchedulerServerSet,
            deployerServerSet,
            cloudStoreServerSet,
            houseKeeperProxyFactory,
            houseKeeperPoolFactory,
            chairmanProxyFactory,
            chairmanPoolFactory,
            rootSchedulerProxyFactory,
            rootSchedulerPoolFactory,
            deployerProxyFactory,
            deployerPoolFactory,
            statusConfig);

    Map<Component, StatusProviderFactory> statusProviderFactories =
        client.getStatusProviderFactories();
    ThriftClientFactory housekeeperClientFactory =
        spy(
            new ThriftClientFactory(
                housekeeperServerSet,
                houseKeeperPoolFactory,
                houseKeeperProxyFactory,
                HousekeeperClient.class,
                "Housekeeper"));
    setupStatusProviderFactory(housekeeperClientFactory, housekeeperClients);
    statusProviderFactories.put(Component.HOUSEKEEPER, housekeeperClientFactory);

    ThriftClientFactory chairmanClientFactory =
        spy(
            new ThriftClientFactory(
                chairmanServerSet,
                chairmanPoolFactory,
                chairmanProxyFactory,
                ChairmanClient.class,
                "Chairman"));
    setupStatusProviderFactory(chairmanClientFactory, chairmanClients);
    statusProviderFactories.put(Component.CHAIRMAN, chairmanClientFactory);

    ThriftClientFactory rootSchedulerClientFactory =
        spy(
            new ThriftClientFactory(
                rootSchedulerServerSet,
                rootSchedulerPoolFactory,
                rootSchedulerProxyFactory,
                RootSchedulerClient.class,
                "RootScheduler"));
    setupStatusProviderFactory(rootSchedulerClientFactory, rootSchedulerClients);
    statusProviderFactories.put(Component.ROOT_SCHEDULER, rootSchedulerClientFactory);

    ThriftClientFactory deployerClientFactory =
        spy(
            new ThriftClientFactory(
                deployerServerSet,
                deployerPoolFactory,
                deployerProxyFactory,
                DeployerClient.class,
                "Deployer"));
    setupStatusProviderFactory(deployerClientFactory, deployerClients);
    statusProviderFactories.put(Component.DEPLOYER, deployerClientFactory);

    StatusProviderFactory cloudStoreClientFactory =
        spy(new DcpStatusProviderFactory(cloudStoreServerSet, executor));
    setupStatusProviderFactory(cloudStoreClientFactory, cloudStoreClients);
    statusProviderFactories.put(Component.CLOUD_STORE, cloudStoreClientFactory);
  }