private void removePublishTimeout() {
   // to test that the acknowledgement mechanism is working we better disable the wait for publish
   // otherwise the operation is most likely acknowledged even if it doesn't support ack
   assertAcked(
       client()
           .admin()
           .cluster()
           .prepareUpdateSettings()
           .setTransientSettings(
               Settings.builder()
                   .put(DiscoverySettings.PUBLISH_TIMEOUT_SETTING.getKey(), "0")
                   .put(DiscoverySettings.COMMIT_TIMEOUT_SETTING.getKey(), "30s")));
 }
  /**
   * Tests that cluster is committed or times out. It should never be the case that we fail an
   * update due to a commit timeout, but it ends up being committed anyway
   */
  public void testTimeoutOrCommit() throws Exception {
    Settings settings =
        Settings.builder()
            // short but so we will sometime commit sometime timeout
            .put(DiscoverySettings.COMMIT_TIMEOUT_SETTING.getKey(), "1ms")
            .build();

    MockNode master = createMockNode("master", settings, null);
    MockNode node = createMockNode("node", settings, null);
    ClusterState state =
        ClusterState.builder(master.clusterState)
            .nodes(
                DiscoveryNodes.builder(master.clusterState.nodes())
                    .add(node.discoveryNode)
                    .masterNodeId(master.discoveryNode.getId()))
            .build();

    for (int i = 0; i < 10; i++) {
      state = ClusterState.builder(state).incrementVersion().build();
      logger.debug("--> publishing version [{}], UUID [{}]", state.version(), state.stateUUID());
      boolean success;
      try {
        publishState(master.action, state, master.clusterState, 2).await(1, TimeUnit.HOURS);
        success = true;
      } catch (Discovery.FailedToCommitClusterStateException OK) {
        success = false;
      }
      logger.debug("--> publishing [{}], verifying...", success ? "succeeded" : "failed");

      if (success) {
        assertSameState(node.clusterState, state);
      } else {
        assertThat(node.clusterState.stateUUID(), not(equalTo(state.stateUUID())));
      }
    }
  }
  public void testPublishingWithSendingErrors() throws Exception {
    int goodNodes = randomIntBetween(2, 5);
    int errorNodes = randomIntBetween(1, 5);
    int timeOutNodes =
        randomBoolean()
            ? 0
            : randomIntBetween(1, 5); // adding timeout nodes will force timeout errors
    final int numberOfMasterNodes = goodNodes + errorNodes + timeOutNodes + 1; // master
    final boolean expectingToCommit = randomBoolean();
    Settings.Builder settings = Settings.builder();
    // make sure we have a reasonable timeout if we expect to timeout, o.w. one that will make the
    // test "hang"
    settings
        .put(
            DiscoverySettings.COMMIT_TIMEOUT_SETTING.getKey(),
            expectingToCommit == false && timeOutNodes > 0 ? "100ms" : "1h")
        .put(DiscoverySettings.PUBLISH_TIMEOUT_SETTING.getKey(), "5ms"); // test is about committing

    MockNode master = createMockNode("master", settings.build(), null);

    // randomize things a bit
    int[] nodeTypes = new int[goodNodes + errorNodes + timeOutNodes];
    for (int i = 0; i < goodNodes; i++) {
      nodeTypes[i] = 0;
    }
    for (int i = goodNodes; i < goodNodes + errorNodes; i++) {
      nodeTypes[i] = 1;
    }
    for (int i = goodNodes + errorNodes; i < nodeTypes.length; i++) {
      nodeTypes[i] = 2;
    }
    Collections.shuffle(Arrays.asList(nodeTypes), random());

    DiscoveryNodes.Builder discoveryNodesBuilder =
        DiscoveryNodes.builder().add(master.discoveryNode);
    for (int i = 0; i < nodeTypes.length; i++) {
      final MockNode mockNode = createMockNode("node" + i);
      discoveryNodesBuilder.add(mockNode.discoveryNode);
      switch (nodeTypes[i]) {
        case 1:
          mockNode.action.errorOnSend.set(true);
          break;
        case 2:
          mockNode.action.timeoutOnSend.set(true);
          break;
      }
    }
    final int dataNodes = randomIntBetween(0, 3); // data nodes don't matter
    for (int i = 0; i < dataNodes; i++) {
      final MockNode mockNode =
          createMockNode(
              "data_" + i,
              Settings.builder().put(Node.NODE_MASTER_SETTING.getKey(), false).build(),
              null);
      discoveryNodesBuilder.add(mockNode.discoveryNode);
      if (randomBoolean()) {
        // we really don't care - just chaos monkey
        mockNode.action.errorOnCommit.set(randomBoolean());
        mockNode.action.errorOnSend.set(randomBoolean());
        mockNode.action.timeoutOnCommit.set(randomBoolean());
        mockNode.action.timeoutOnSend.set(randomBoolean());
      }
    }

    final int minMasterNodes;
    final String expectedBehavior;
    if (expectingToCommit) {
      minMasterNodes = randomIntBetween(0, goodNodes + 1); // count master
      expectedBehavior = "succeed";
    } else {
      minMasterNodes = randomIntBetween(goodNodes + 2, numberOfMasterNodes); // +2 because of master
      expectedBehavior = timeOutNodes > 0 ? "timeout" : "fail";
    }
    logger.info(
        "--> expecting commit to {}. good nodes [{}], errors [{}], timeouts [{}]. min_master_nodes [{}]",
        expectedBehavior,
        goodNodes + 1,
        errorNodes,
        timeOutNodes,
        minMasterNodes);

    discoveryNodesBuilder
        .localNodeId(master.discoveryNode.getId())
        .masterNodeId(master.discoveryNode.getId());
    DiscoveryNodes discoveryNodes = discoveryNodesBuilder.build();
    MetaData metaData = MetaData.EMPTY_META_DATA;
    ClusterState clusterState =
        ClusterState.builder(CLUSTER_NAME).metaData(metaData).nodes(discoveryNodes).build();
    ClusterState previousState = master.clusterState;
    try {
      publishState(master.action, clusterState, previousState, minMasterNodes);
      if (expectingToCommit == false) {
        fail("cluster state publishing didn't fail despite of not have enough nodes");
      }
    } catch (Discovery.FailedToCommitClusterStateException exception) {
      logger.debug("failed to publish as expected", exception);
      if (expectingToCommit) {
        throw exception;
      }
      assertThat(exception.getMessage(), containsString(timeOutNodes > 0 ? "timed out" : "failed"));
    }
  }