public DistStageAck executeOnSlave() {
    if (!isServiceRunning()) {
      log.info("Not running test on this slave as service is not running.");
      return successfulResponse();
    }
    runningTest = (RunningTest) slaveState.get(RunningTest.nameFor(testName));
    if (runningTest == null) {
      runningTest = new RunningTest();
      slaveState.put(RunningTest.nameFor(testName), runningTest);
      slaveState.addServiceListener(runningTest);
    } else if (runningTest.isTerminated()) {
      return errorResponse("The test was terminated in previous iteration");
    }
    prepare();
    runningTest.setMinThreadCreationDelay(minThreadCreationDelay);
    runningTest.setMinWaitingThreads(rampUpMinWaitingThreads);
    runningTest.setMaxThreads(maxThreads);
    runningTest.setLogExceptions(logRequestExceptions, logTransactionExceptions);
    runningTest.updateSelector(createSelector());

    log.info("Starting test " + testName + " ramp-up");
    int minThreads = Math.max(this.minThreads, rampUpMinWaitingThreads + 1);
    while (runningTest.getUsedThreads() < minThreads) {
      // one of the started threads may already create his sibling;
      // fail silently if we attempt to reach the limit
      runningTest.addStressor(true);
    }
    int lastThreads = 0;
    long now = TimeService.currentTimeMillis();
    long lastThreadsChange = now;
    long startTime = now;
    while (!runningTest.isTerminated()) {
      int currentThreads = runningTest.getUsedThreads();
      if (currentThreads != lastThreads) {
        lastThreadsChange = now;
        lastThreads = currentThreads;
      }
      if (now < startTime + rampUpMinDuration || now < lastThreadsChange + rampUpMinSteadyPeriod) {
        if (rampUpMaxDuration > 0 && now > startTime + rampUpMaxDuration) {
          break;
        }
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          log.warn("Interruptions should not happen.", e);
        }
      } else {
        break;
      }
      now = TimeService.currentTimeMillis();
    }
    if (runningTest.isTerminated()) {
      return errorResponse("Test was terminated during ramp-up");
    } else if (rampUpMaxDuration > 0 && now >= startTime + rampUpMaxDuration) {
      return errorResponse("Ramp-up has not stabilized within timeout");
    } else if (runningTest.isReachedMax()) {
      return errorResponse("Max thread count reached during ramp-up");
    }
    return successfulResponse();
  }
 private boolean check(List<Event> history) {
   if (history.isEmpty()) return !changed;
   long lastChange = history.get(history.size() - 1).getTime().getTime();
   long current = TimeService.currentTimeMillis();
   boolean hasChanged = lastChange + period > current;
   return hasChanged == changed;
 }