private void validateCompetitionResult(
      CompetitionResult result, BenchmarkSettings requestedSettings, boolean strict) {
    // Validate settings
    assertTrue(result.competitionName().startsWith(COMPETITOR_PREFIX));
    assertThat(result.concurrency(), equalTo(requestedSettings.concurrency()));
    assertThat(result.multiplier(), equalTo(requestedSettings.multiplier()));

    // Validate node-level responses
    for (CompetitionNodeResult nodeResult : result.nodeResults()) {

      assertThat(nodeResult.nodeName(), notNullValue());

      assertThat(nodeResult.totalIterations(), equalTo(requestedSettings.iterations()));
      if (strict) {
        assertThat(nodeResult.completedIterations(), equalTo(requestedSettings.iterations()));
        final int expectedQueryCount =
            requestedSettings.multiplier()
                * nodeResult.totalIterations()
                * requestedSettings.searchRequests().size();
        assertThat(nodeResult.totalExecutedQueries(), equalTo(expectedQueryCount));
        assertThat(nodeResult.iterations().size(), equalTo(requestedSettings.iterations()));
      }

      assertThat(nodeResult.warmUpTime(), greaterThanOrEqualTo(0L));

      for (CompetitionIteration iteration : nodeResult.iterations()) {
        // Basic sanity checks
        iteration.computeStatistics();
        assertThat(iteration.totalTime(), greaterThanOrEqualTo(0L));
        assertThat(iteration.min(), greaterThanOrEqualTo(0L));
        assertThat(iteration.max(), greaterThanOrEqualTo(iteration.min()));
        assertThat(iteration.mean(), greaterThanOrEqualTo((double) iteration.min()));
        assertThat(iteration.mean(), lessThanOrEqualTo((double) iteration.max()));
        assertThat(iteration.queriesPerSecond(), greaterThanOrEqualTo(0.0));
        assertThat(iteration.millisPerHit(), greaterThanOrEqualTo(0.0));
        validatePercentiles(iteration.percentileValues());
      }
    }

    // Validate summary statistics
    final CompetitionSummary summary = result.competitionSummary();
    summary.computeSummaryStatistics();
    assertThat(summary, notNullValue());
    assertThat(summary.getMin(), greaterThanOrEqualTo(0L));
    assertThat(summary.getMax(), greaterThanOrEqualTo(summary.getMin()));
    assertThat(summary.getMean(), greaterThanOrEqualTo((double) summary.getMin()));
    assertThat(summary.getMean(), lessThanOrEqualTo((double) summary.getMax()));
    assertThat(summary.getTotalTime(), greaterThanOrEqualTo(0L));
    assertThat(summary.getQueriesPerSecond(), greaterThanOrEqualTo(0.0));
    assertThat(summary.getMillisPerHit(), greaterThanOrEqualTo(0.0));
    assertThat(summary.getAvgWarmupTime(), greaterThanOrEqualTo(0.0));
    if (strict) {
      assertThat(
          (int) summary.getTotalIterations(),
          equalTo(requestedSettings.iterations() * summary.nodeResults().size()));
      assertThat(
          (int) summary.getCompletedIterations(),
          equalTo(requestedSettings.iterations() * summary.nodeResults().size()));
      assertThat(
          (int) summary.getTotalQueries(),
          equalTo(
              requestedSettings.iterations()
                  * requestedSettings.multiplier()
                  * requestedSettings.searchRequests().size()
                  * summary.nodeResults().size()));
      validatePercentiles(summary.percentileValues);
    }
  }