@Test
  public void testListBenchmarks() throws Exception {
    SearchRequest searchRequest = prepareBlockingScriptQuery();
    final BenchmarkRequest request =
        BenchmarkTestUtil.randomRequest(
            client(), indices, numExecutorNodes, competitionSettingsMap, searchRequest);
    logger.info(
        "--> Submitting benchmark - competitors [{}] iterations [{}]",
        request.competitors().size(),
        request.settings().iterations());

    final ActionFuture<BenchmarkResponse> future = client().bench(request);
    try {
      waitForQuery.await();
      final BenchmarkStatusResponse statusResponse =
          client().prepareBenchStatus().execute().actionGet();
      waitForTestLatch.countDown();
      assertThat(statusResponse.benchmarkResponses().size(), equalTo(1));
      for (BenchmarkResponse benchmarkResponse : statusResponse.benchmarkResponses()) {
        assertThat(benchmarkResponse.benchmarkName(), equalTo(BENCHMARK_NAME));
        assertThat(benchmarkResponse.state(), equalTo(BenchmarkResponse.State.RUNNING));
        assertFalse(benchmarkResponse.hasErrors());

        for (CompetitionResult result : benchmarkResponse.competitionResults().values()) {
          assertThat(result.nodeResults().size(), lessThanOrEqualTo(numExecutorNodes));
          validateCompetitionResult(
              result, competitionSettingsMap.get(result.competitionName()), false);
        }
      }

    } finally {
      if (waitForTestLatch.getCount() == 1) {
        waitForTestLatch.countDown();
      }
      client().prepareAbortBench(BENCHMARK_NAME).get();
      // Confirm that there are no active benchmarks in the cluster
      assertThat(
          client().prepareBenchStatus().execute().actionGet().totalActiveBenchmarks(), equalTo(0));
      assertThat(waitForTestLatch.getCount(), is(0l));
    }
    // Confirm that benchmark was indeed aborted
    assertThat(
        future.get().state(),
        isOneOf(BenchmarkResponse.State.ABORTED, BenchmarkResponse.State.COMPLETE));
  }
  @Test
  public void testSubmitBenchmark() throws Exception {
    final int iters =
        between(1, 3); // we run this more than once to make sure metadata is cleaned up propperly
    for (int i = 0; i < iters; i++) {
      final BenchmarkRequest request =
          BenchmarkTestUtil.randomRequest(
              client(), indices, numExecutorNodes, competitionSettingsMap);
      logger.info(
          "--> Submitting benchmark - competitors [{}] iterations [{}]",
          request.competitors().size(),
          request.settings().iterations());
      final BenchmarkResponse response = client().bench(request).actionGet();

      assertThat(response, notNullValue());
      assertThat(response.state(), equalTo(BenchmarkResponse.State.COMPLETE));
      assertFalse(response.hasErrors());
      assertThat(response.benchmarkName(), equalTo(BENCHMARK_NAME));
      assertThat(response.competitionResults().size(), equalTo(request.competitors().size()));

      for (CompetitionResult result : response.competitionResults().values()) {
        assertThat(result.nodeResults().size(), equalTo(numExecutorNodes));
        validateCompetitionResult(
            result, competitionSettingsMap.get(result.competitionName()), true);
      }
    }
  }
  @Test
  public void testBenchmarkWithErrors() {
    List<SearchRequest> reqList = new ArrayList<>();
    int numQueries = scaledRandomIntBetween(20, 100);
    int numErrors = scaledRandomIntBetween(1, numQueries);
    final boolean containsFatal = randomBoolean();
    if (containsFatal) {
      ScriptScoreFunctionBuilder scriptFunction =
          scriptFunction("DOES NOT COMPILE - fails on any shard");
      SearchRequest searchRequest =
          searchRequest()
              .source(
                  searchSource()
                      .query(functionScoreQuery(FilterBuilders.matchAllFilter(), scriptFunction)));
      reqList.add(searchRequest);
    }
    for (int i = 0; reqList.size() < numErrors; i++) {
      ScriptScoreFunctionBuilder scriptFunction = scriptFunction("throw new RuntimeException();");
      SearchRequest searchRequest =
          searchRequest()
              .source(
                  searchSource()
                      .query(functionScoreQuery(FilterBuilders.matchAllFilter(), scriptFunction)));
      reqList.add(searchRequest);
    }
    logger.info("--> run with [{}] errors ", numErrors);
    for (int i = 0; reqList.size() < numQueries; i++) {

      reqList.add(BenchmarkTestUtil.randomSearch(client(), indices));
    }
    Collections.shuffle(reqList, getRandom());

    final BenchmarkRequest request =
        BenchmarkTestUtil.randomRequest(
            client(),
            indices,
            numExecutorNodes,
            competitionSettingsMap,
            reqList.toArray(new SearchRequest[0]));
    logger.info(
        "--> Submitting benchmark - competitors [{}] iterations [{}]",
        request.competitors().size(),
        request.settings().iterations());
    final BenchmarkResponse response = client().bench(request).actionGet();

    assertThat(response, notNullValue());
    if (response.hasErrors() || containsFatal) {
      assertThat(response.state(), equalTo(BenchmarkResponse.State.FAILED));
    } else {
      assertThat(response.state(), equalTo(BenchmarkResponse.State.COMPLETE));
      for (CompetitionResult result : response.competitionResults().values()) {
        assertThat(result.nodeResults().size(), equalTo(numExecutorNodes));
        validateCompetitionResult(
            result, competitionSettingsMap.get(result.competitionName()), true);
      }
    }
    assertThat(response.benchmarkName(), equalTo(BENCHMARK_NAME));
  }