public List<Future<Object>> run() {
    List<Future<Object>> futureList = new ArrayList<>();
    this.multiExecutorService = Executors.newFixedThreadPool(this.testConfig.getNoOfThreads());

    if (this.testManagerList.isEmpty()) {
      int totalTestCases = this.tupleList.size();
      if (totalTestCases < 1) {
        return null;
      }
      logger.info("Executing " + this.testConfig + " for " + totalTestCases
          + " browser tuples with size :" + tupleList.get(0).size());
      testConfig.setLogger(KiteLogger.getLogger(testConfig.getTestClassName()));
      if (testConfig.isLoadTest()) {
        Tuple neo = new Tuple();
        for (Tuple tuple: this.tupleList) {
          neo.mergeWith(tuple);
        }
        this.tupleList.clear();
        this.tupleList.add(neo);
      }

      for (int index = 0; index < this.tupleList.size(); index++) {
        TestManager manager = new TestManager(this.testConfig, this.tupleList.get(index));
        manager.setSuite(this.testSuite);
        if (this.testConfig.isLoadTest()) {
          manager.setId((currentIteration + index * this.tupleList.get(index).size() + 1));
        } else {
          manager.setId(index);
        }
        manager.setTotal(this.tupleList.size());
        manager.setDelay(index*ONE_SECOND_INTERVAL);
        this.testManagerList.add(manager);
      }
    }

    try {
      this.currentPhase = testManagerList.get(0).getCurrentPhase(); // if null -> firs time executing
      //Runtime.getRuntime().addShutdownHook(new Thread(() -> terminate()));
      futureList.addAll(multiExecutorService.invokeAll(testManagerList));
    } catch (Exception e) {
      logger.error(getStackTrace(e));
    } finally {
      if (this.currentPhase.isLastPhase()) {
        if (this.currentPhase.equals(StepPhase.LOADREACHED)) {
          // todo: wait for last iteration
          if (this.isLastThread()) {
            logger.info("Last thread has finished!");
            this.testConfig.setDone(true);
          }
          logger.info("Waiting for all threads to finish");
          while (!this.testConfig.isDone()) {
            waitAround(FIVE_SECOND_INTERVAL);
          }
        } else {
          logger.info("Matrix runner at last phase, ending. ");
        }
        terminate();
      }
      this.shutdownExecutors();
    }

    return futureList;
  }
Executes the test contained inside the TestManager for the provided matrix.

@return List<Future < Object>>
KITE-Engine/src/main/java/org/webrtc/kite/MatrixRunner.java