public void run(Callable<Boolean> monkeyCallable, String testName) throws Exception {
    int maxIters = util.getHBaseClusterInterface().isDistributedCluster() ? 10 : 3;
    LOG.info("Starting " + testName + " with " + maxIters + " iterations.");

    // Array to keep track of times.
    ArrayList<TimingResult> resultPuts = new ArrayList<>(maxIters);
    ArrayList<TimingResult> resultScan = new ArrayList<>(maxIters);
    ArrayList<TimingResult> resultAdmin = new ArrayList<>(maxIters);
    long start = System.nanoTime();

    try {
      // We're going to try this multiple times
      for (int fullIterations = 0; fullIterations < maxIters; fullIterations++) {
        // Create and start executing a callable that will kill the servers
        Future<Boolean> monkeyFuture = executorService.submit(monkeyCallable);

        // Pass that future to the timing Callables.
        Future<TimingResult> putFuture = executorService.submit(new PutCallable(monkeyFuture));
        Future<TimingResult> scanFuture = executorService.submit(new ScanCallable(monkeyFuture));
        Future<TimingResult> adminFuture = executorService.submit(new AdminCallable(monkeyFuture));

        Future<Boolean> loadFuture = executorService.submit(new LoadCallable(monkeyFuture));

        monkeyFuture.get();
        loadFuture.get();

        // Get the values from the futures.
        TimingResult putTime = putFuture.get();
        TimingResult scanTime = scanFuture.get();
        TimingResult adminTime = adminFuture.get();

        // Store the times to display later.
        resultPuts.add(putTime);
        resultScan.add(scanTime);
        resultAdmin.add(adminTime);

        // Wait some time for everything to settle down.
        Thread.sleep(5000l);
      }
    } catch (Exception e) {
      long runtimeMs =
        TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
      LOG.info(testName + " failed after " + runtimeMs + "ms.", e);
      throw e;
    }

    long runtimeMs = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);

    MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper("MTTRResults")
      .add("putResults", resultPuts).add("scanResults", resultScan).add("adminResults", resultAdmin)
      .add("totalRuntimeMs", runtimeMs).add("name", testName);

    // Log the info
    LOG.info(helper.toString());
  }
The load test tool used to create load and make sure that WALs aren't empty.
hbase-it/src/test/java/org/apache/hadoop/hbase/mttr/IntegrationTestMTTR.java