presto-verifier/src/main/java/io/prestosql/verifier/Verifier.java/Verifier/run
class Verifier:    public int run(List<QueryPair> queries)
            throws InterruptedException
    {
        ExecutorService executor = newFixedThreadPool(threadCount);
        CompletionService<Validator> completionService = new ExecutorCompletionService<>(executor);

        int totalQueries = queries.size() * config.getSuiteRepetitions() * config.getQueryRepetitions();
        log.info("Total Queries:     %d", totalQueries);

        log.info("Whitelisted Queries: %s", Joiner.on(',').join(whitelist));

        int queriesSubmitted = 0;
        for (int i = 0; i < config.getSuiteRepetitions(); i++) {
            for (QueryPair query : queries) {
                for (int j = 0; j < config.getQueryRepetitions(); j++) {
                    // If a whitelist exists, only run the tests on the whitelist
                    if (!whitelist.isEmpty() && !whitelist.contains(query.getName())) {
                        log.debug("Query %s is not whitelisted", query.getName());
                        continue;
                    }
                    if (blacklist.contains(query.getName())) {
                        log.debug("Query %s is blacklisted", query.getName());
                        continue;
                    }
                    Validator validator = new Validator(
                            config.getControlGateway(),
                            config.getTestGateway(),
                            config.getControlTimeout(),
                            config.getTestTimeout(),
                            config.getMaxRowCount(),
                            config.isExplainOnly(),
                            config.getDoublePrecision(),
                            isCheckCorrectness(query),
                            true,
                            config.isVerboseResultsComparison(),
                            config.getControlTeardownRetries(),
                            config.getTestTeardownRetries(),
                            config.getRunTearDownOnResultMismatch(),
                            query);
                    completionService.submit(validator::valid, validator);
                    queriesSubmitted++;
                }
            }
        }

        log.info("Allowed Queries:     %d", queriesSubmitted);
        log.info("Skipped Queries:     %d", (totalQueries - queriesSubmitted));
        log.info("---------------------");

        executor.shutdown();

        int total = 0;
        int valid = 0;
        int failed = 0;
        int skipped = 0;
        double lastProgress = 0;

        while (total < queriesSubmitted) {
            total++;

            Validator validator = takeUnchecked(completionService);

            if (validator.isSkipped()) {
                if (!config.isQuiet()) {
                    log.warn("%s", validator.getSkippedMessage());
                }

                skipped++;
                continue;
            }

            if (validator.valid()) {
                valid++;
            }
            else {
                failed++;
            }

            for (EventClient eventClient : eventClients) {
                eventClient.post(buildEvent(validator));
            }

            double progress = (((double) total) / totalQueries) * 100;
            if (!config.isQuiet() || (progress - lastProgress) > 1) {
                log.info("Progress: %s valid, %s failed, %s skipped, %.2f%% done", valid, failed, skipped, progress);
                lastProgress = progress;
            }
        }

        log.info("Results: %s / %s (%s skipped)", valid, failed, skipped);
        log.info("");

        for (EventClient eventClient : eventClients) {
            if (eventClient instanceof Closeable) {
                try {
                    ((Closeable) eventClient).close();
                }
                catch (IOException ignored) {
                }
                log.info("");
            }
        }

        return failed;
    }