#!/usr/bin/env python

"""
Static Analyzer qualification infrastructure.

The goal is to test the analyzer against different projects,
check for failures, compare results, and measure performance.

Repository Directory will contain sources of the projects as well as the
information on how to build them and the expected output.
Repository Directory structure:
   - ProjectMap file
   - Historical Performance Data
   - Project Dir1
     - ReferenceOutput
   - Project Dir2
     - ReferenceOutput
   ..
Note that the build tree must be inside the project dir.

To test the build of the analyzer one would:
   - Copy over a copy of the Repository Directory. (TODO: Prefer to ensure that
     the build directory does not pollute the repository to min network
     traffic).
   - Build all projects, until error. Produce logs to report errors.
   - Compare results.

The files which should be kept around for failure investigations:
   RepositoryCopy/Project DirI/ScanBuildResults
   RepositoryCopy/Project DirI/run_static_analyzer.log

Assumptions (TODO: shouldn't need to assume these.):
   The script is being run from the Repository Directory.
   The compiler for scan-build and scan-build are in the PATH.
   export PATH=/Users/zaks/workspace/c2llvm/build/Release+Asserts/bin:$PATH

For more logging, set the  env variables:
   zaks:TI zaks$ export CCC_ANALYZER_LOG=1
   zaks:TI zaks$ export CCC_ANALYZER_VERBOSE=1

The list of checkers tested are hardcoded in the Checkers variable.
For testing additional checkers, use the SA_ADDITIONAL_CHECKERS environment
variable. It should contain a comma separated list.
"""
import CmpRuns
import SATestUtils

from subprocess import CalledProcessError, check_call
import argparse
import csv
import glob
import logging
import math
import multiprocessing
import os
import plistlib
import shutil
import sys
import threading
import time
try:
    import queue
except ImportError:
    import Queue as queue

###############################################################################
# Helper functions.
###############################################################################

Local = threading.local()
Local.stdout = sys.stdout
Local.stderr = sys.stderr
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s:%(levelname)s:%(name)s: %(message)s')

class StreamToLogger(object):
    def __init__(self, logger, log_level=logging.INFO):
        self.logger = logger
        self.log_level = log_level

    def write(self, buf):
        # Rstrip in order not to write an extra newline.
        self.logger.log(self.log_level, buf.rstrip())

    def flush(self):
        pass

    def fileno(self):
        return 0


def getProjectMapPath():
    ProjectMapPath = os.path.join(os.path.abspath(os.curdir),
                                  ProjectMapFile)
    if not os.path.exists(ProjectMapPath):
        Local.stdout.write("Error: Cannot find the Project Map file " +
                           ProjectMapPath +
                           "\nRunning script for the wrong directory?\n")
        sys.exit(1)
    return ProjectMapPath


def getProjectDir(ID):
    return os.path.join(os.path.abspath(os.curdir), ID)


def getSBOutputDirName(IsReferenceBuild):
    if IsReferenceBuild:
        return SBOutputDirReferencePrefix + SBOutputDirName
    else:
        return SBOutputDirName

###############################################################################
# Configuration setup.
###############################################################################


# Find Clang for static analysis.
if 'CC' in os.environ:
    Clang = os.environ['CC']
else:
    Clang = SATestUtils.which("clang", os.environ['PATH'])
if not Clang:
    print("Error: cannot find 'clang' in PATH")
    sys.exit(1)

# Number of jobs.
MaxJobs = int(math.ceil(multiprocessing.cpu_count() * 0.75))

# Project map stores info about all the "registered" projects.
ProjectMapFile = "projectMap.csv"

# Names of the project specific scripts.
# The script that downloads the project.
DownloadScript = "download_project.sh"
# The script that needs to be executed before the build can start.
CleanupScript = "cleanup_run_static_analyzer.sh"
# This is a file containing commands for scan-build.
BuildScript = "run_static_analyzer.cmd"

# A comment in a build script which disables wrapping.
NoPrefixCmd = "#NOPREFIX"

# The log file name.
LogFolderName = "Logs"
BuildLogName = "run_static_analyzer.log"
# Summary file - contains the summary of the failures. Ex: This info can be be
# displayed when buildbot detects a build failure.
NumOfFailuresInSummary = 10
FailuresSummaryFileName = "failures.txt"

# The scan-build result directory.
SBOutputDirName = "ScanBuildResults"
SBOutputDirReferencePrefix = "Ref"

# The name of the directory storing the cached project source. If this
# directory does not exist, the download script will be executed.
# That script should create the "CachedSource" directory and download the
# project source into it.
CachedSourceDirName = "CachedSource"

# The name of the directory containing the source code that will be analyzed.
# Each time a project is analyzed, a fresh copy of its CachedSource directory
# will be copied to the PatchedSource directory and then the local patches
# in PatchfileName will be applied (if PatchfileName exists).
PatchedSourceDirName = "PatchedSource"

# The name of the patchfile specifying any changes that should be applied
# to the CachedSource before analyzing.
PatchfileName = "changes_for_analyzer.patch"

# The list of checkers used during analyzes.
# Currently, consists of all the non-experimental checkers, plus a few alpha
# checkers we don't want to regress on.
Checkers = ",".join([
    "alpha.unix.SimpleStream",
    "alpha.security.taint",
    "cplusplus.NewDeleteLeaks",
    "core",
    "cplusplus",
    "deadcode",
    "security",
    "unix",
    "osx",
    "nullability"
])

Verbose = 0

###############################################################################
# Test harness logic.
###############################################################################


def runCleanupScript(Dir, PBuildLogFile):
    """
    Run pre-processing script if any.
    """
    Cwd = os.path.join(Dir, PatchedSourceDirName)
    ScriptPath = os.path.join(Dir, CleanupScript)
    SATestUtils.runScript(ScriptPath, PBuildLogFile, Cwd,
                          Stdout=Local.stdout, Stderr=Local.stderr)


def runDownloadScript(Dir, PBuildLogFile):
    """
    Run the script to download the project, if it exists.
    """
    ScriptPath = os.path.join(Dir, DownloadScript)
    SATestUtils.runScript(ScriptPath, PBuildLogFile, Dir,
                          Stdout=Local.stdout, Stderr=Local.stderr)


def downloadAndPatch(Dir, PBuildLogFile):
    """
    Download the project and apply the local patchfile if it exists.
    """
    CachedSourceDirPath = os.path.join(Dir, CachedSourceDirName)

    # If the we don't already have the cached source, run the project's
    # download script to download it.
    if not os.path.exists(CachedSourceDirPath):
        runDownloadScript(Dir, PBuildLogFile)
        if not os.path.exists(CachedSourceDirPath):
            Local.stderr.write("Error: '%s' not found after download.\n" % (
                               CachedSourceDirPath))
            exit(1)

    PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)

    # Remove potentially stale patched source.
    if os.path.exists(PatchedSourceDirPath):
        shutil.rmtree(PatchedSourceDirPath)

    # Copy the cached source and apply any patches to the copy.
    shutil.copytree(CachedSourceDirPath, PatchedSourceDirPath, symlinks=True)
    applyPatch(Dir, PBuildLogFile)


def applyPatch(Dir, PBuildLogFile):
    PatchfilePath = os.path.join(Dir, PatchfileName)
    PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
    if not os.path.exists(PatchfilePath):
        Local.stdout.write("  No local patches.\n")
        return

    Local.stdout.write("  Applying patch.\n")
    try:
        check_call("patch -p1 < '%s'" % (PatchfilePath),
                   cwd=PatchedSourceDirPath,
                   stderr=PBuildLogFile,
                   stdout=PBuildLogFile,
                   shell=True)
    except:
        Local.stderr.write("Error: Patch failed. See %s for details.\n" % (
            PBuildLogFile.name))
        sys.exit(1)


def generateAnalyzerConfig(Args):
    Out = "serialize-stats=true,stable-report-filename=true"
    if Args.extra_analyzer_config:
        Out += "," + Args.extra_analyzer_config
    return Out


def runScanBuild(Args, Dir, SBOutputDir, PBuildLogFile):
    """
    Build the project with scan-build by reading in the commands and
    prefixing them with the scan-build options.
    """
    BuildScriptPath = os.path.join(Dir, BuildScript)
    if not os.path.exists(BuildScriptPath):
        Local.stderr.write(
            "Error: build script is not defined: %s\n" % BuildScriptPath)
        sys.exit(1)

    AllCheckers = Checkers
    if 'SA_ADDITIONAL_CHECKERS' in os.environ:
        AllCheckers = AllCheckers + ',' + os.environ['SA_ADDITIONAL_CHECKERS']

    # Run scan-build from within the patched source directory.
    SBCwd = os.path.join(Dir, PatchedSourceDirName)

    SBOptions = "--use-analyzer '%s' " % Clang
    SBOptions += "-plist-html -o '%s' " % SBOutputDir
    SBOptions += "-enable-checker " + AllCheckers + " "
    SBOptions += "--keep-empty "
    SBOptions += "-analyzer-config '%s' " % generateAnalyzerConfig(Args)

    # Always use ccc-analyze to ensure that we can locate the failures
    # directory.
    SBOptions += "--override-compiler "
    ExtraEnv = {}
    try:
        SBCommandFile = open(BuildScriptPath, "r")
        SBPrefix = "scan-build " + SBOptions + " "
        for Command in SBCommandFile:
            Command = Command.strip()
            if len(Command) == 0:
                continue

            # Custom analyzer invocation specified by project.
            # Communicate required information using environment variables
            # instead.
            if Command == NoPrefixCmd:
                SBPrefix = ""
                ExtraEnv['OUTPUT'] = SBOutputDir
                ExtraEnv['CC'] = Clang
                ExtraEnv['ANALYZER_CONFIG'] = generateAnalyzerConfig(Args)
                continue

            # If using 'make', auto imply a -jX argument
            # to speed up analysis.  xcodebuild will
            # automatically use the maximum number of cores.
            if (Command.startswith("make ") or Command == "make") and \
                    "-j" not in Command:
                Command += " -j%d" % MaxJobs
            SBCommand = SBPrefix + Command

            if Verbose == 1:
                Local.stdout.write("  Executing: %s\n" % (SBCommand,))
            check_call(SBCommand, cwd=SBCwd,
                       stderr=PBuildLogFile,
                       stdout=PBuildLogFile,
                       env=dict(os.environ, **ExtraEnv),
                       shell=True)
    except CalledProcessError:
        Local.stderr.write("Error: scan-build failed. Its output was: \n")
        PBuildLogFile.seek(0)
        shutil.copyfileobj(PBuildLogFile, Local.stderr)
        sys.exit(1)


def runAnalyzePreprocessed(Args, Dir, SBOutputDir, Mode):
    """
    Run analysis on a set of preprocessed files.
    """
    if os.path.exists(os.path.join(Dir, BuildScript)):
        Local.stderr.write(
            "Error: The preprocessed files project should not contain %s\n" % (
                BuildScript))
        raise Exception()

    CmdPrefix = Clang + " --analyze "

    CmdPrefix += "--analyzer-output plist "
    CmdPrefix += " -Xclang -analyzer-checker=" + Checkers
    CmdPrefix += " -fcxx-exceptions -fblocks "
    CmdPrefix += " -Xclang -analyzer-config -Xclang %s "\
        % generateAnalyzerConfig(Args)

    if (Mode == 2):
        CmdPrefix += "-std=c++11 "

    PlistPath = os.path.join(Dir, SBOutputDir, "date")
    FailPath = os.path.join(PlistPath, "failures")
    os.makedirs(FailPath)

    for FullFileName in glob.glob(Dir + "/*"):
        FileName = os.path.basename(FullFileName)
        Failed = False

        # Only run the analyzes on supported files.
        if SATestUtils.hasNoExtension(FileName):
            continue
        if not SATestUtils.isValidSingleInputFile(FileName):
            Local.stderr.write(
                "Error: Invalid single input file %s.\n" % (FullFileName,))
            raise Exception()

        # Build and call the analyzer command.
        OutputOption = "-o '%s.plist' " % os.path.join(PlistPath, FileName)
        Command = CmdPrefix + OutputOption + ("'%s'" % FileName)
        LogFile = open(os.path.join(FailPath, FileName + ".stderr.txt"), "w+b")
        try:
            if Verbose == 1:
                Local.stdout.write("  Executing: %s\n" % (Command,))
            check_call(Command, cwd=Dir, stderr=LogFile,
                       stdout=LogFile,
                       shell=True)
        except CalledProcessError as e:
            Local.stderr.write("Error: Analyzes of %s failed. "
                               "See %s for details."
                               "Error code %d.\n" % (
                                   FullFileName, LogFile.name, e.returncode))
            Failed = True
        finally:
            LogFile.close()

        # If command did not fail, erase the log file.
        if not Failed:
            os.remove(LogFile.name)


def getBuildLogPath(SBOutputDir):
    return os.path.join(SBOutputDir, LogFolderName, BuildLogName)


def removeLogFile(SBOutputDir):
    BuildLogPath = getBuildLogPath(SBOutputDir)
    # Clean up the log file.
    if (os.path.exists(BuildLogPath)):
        RmCommand = "rm '%s'" % BuildLogPath
        if Verbose == 1:
            Local.stdout.write("  Executing: %s\n" % (RmCommand,))
        check_call(RmCommand, shell=True)


def buildProject(Args, Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild):
    TBegin = time.time()

    BuildLogPath = getBuildLogPath(SBOutputDir)
    Local.stdout.write("Log file: %s\n" % (BuildLogPath,))
    Local.stdout.write("Output directory: %s\n" % (SBOutputDir, ))

    removeLogFile(SBOutputDir)

    # Clean up scan build results.
    if (os.path.exists(SBOutputDir)):
        RmCommand = "rm -r '%s'" % SBOutputDir
        if Verbose == 1:
            Local.stdout.write("  Executing: %s\n" % (RmCommand,))
            check_call(RmCommand, shell=True, stdout=Local.stdout,
                       stderr=Local.stderr)
    assert(not os.path.exists(SBOutputDir))
    os.makedirs(os.path.join(SBOutputDir, LogFolderName))

    # Build and analyze the project.
    with open(BuildLogPath, "wb+") as PBuildLogFile:
        if (ProjectBuildMode == 1):
            downloadAndPatch(Dir, PBuildLogFile)
            runCleanupScript(Dir, PBuildLogFile)
            runScanBuild(Args, Dir, SBOutputDir, PBuildLogFile)
        else:
            runAnalyzePreprocessed(Args, Dir, SBOutputDir, ProjectBuildMode)

        if IsReferenceBuild:
            runCleanupScript(Dir, PBuildLogFile)
            normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode)

    Local.stdout.write("Build complete (time: %.2f). "
                       "See the log for more details: %s\n" % (
                           (time.time() - TBegin), BuildLogPath))


def normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode):
    """
    Make the absolute paths relative in the reference results.
    """
    for (DirPath, Dirnames, Filenames) in os.walk(SBOutputDir):
        for F in Filenames:
            if (not F.endswith('plist')):
                continue
            Plist = os.path.join(DirPath, F)
            Data = plistlib.readPlist(Plist)
            PathPrefix = Dir
            if (ProjectBuildMode == 1):
                PathPrefix = os.path.join(Dir, PatchedSourceDirName)
            Paths = [SourceFile[len(PathPrefix) + 1:]
                     if SourceFile.startswith(PathPrefix)
                     else SourceFile for SourceFile in Data['files']]
            Data['files'] = Paths

            # Remove transient fields which change from run to run.
            for Diag in Data['diagnostics']:
                if 'HTMLDiagnostics_files' in Diag:
                    Diag.pop('HTMLDiagnostics_files')
            if 'clang_version' in Data:
                Data.pop('clang_version')

            plistlib.writePlist(Data, Plist)


def CleanUpEmptyPlists(SBOutputDir):
    """
    A plist file is created for each call to the analyzer(each source file).
    We are only interested on the once that have bug reports,
    so delete the rest.
    """
    for F in glob.glob(SBOutputDir + "/*/*.plist"):
        P = os.path.join(SBOutputDir, F)

        Data = plistlib.readPlist(P)
        # Delete empty reports.
        if not Data['files']:
            os.remove(P)
            continue


def CleanUpEmptyFolders(SBOutputDir):
    """
    Remove empty folders from results, as git would not store them.
    """
    Subfolders = glob.glob(SBOutputDir + "/*")
    for Folder in Subfolders:
        if not os.listdir(Folder):
            os.removedirs(Folder)


def checkBuild(SBOutputDir):
    """
    Given the scan-build output directory, checks if the build failed
    (by searching for the failures directories). If there are failures, it
    creates a summary file in the output directory.

    """
    # Check if there are failures.
    Failures = glob.glob(SBOutputDir + "/*/failures/*.stderr.txt")
    TotalFailed = len(Failures)
    if TotalFailed == 0:
        CleanUpEmptyPlists(SBOutputDir)
        CleanUpEmptyFolders(SBOutputDir)
        Plists = glob.glob(SBOutputDir + "/*/*.plist")
        Local.stdout.write(
            "Number of bug reports (non-empty plist files) produced: %d\n" %
            len(Plists))
        return

    Local.stderr.write("Error: analysis failed.\n")
    Local.stderr.write("Total of %d failures discovered.\n" % TotalFailed)
    if TotalFailed > NumOfFailuresInSummary:
        Local.stderr.write(
            "See the first %d below.\n" % NumOfFailuresInSummary)
        # TODO: Add a line "See the results folder for more."

    Idx = 0
    for FailLogPathI in Failures:
        if Idx >= NumOfFailuresInSummary:
            break
        Idx += 1
        Local.stderr.write("\n-- Error #%d -----------\n" % Idx)
        with open(FailLogPathI, "r") as FailLogI:
            shutil.copyfileobj(FailLogI, Local.stdout)

    sys.exit(1)


def runCmpResults(Dir, Strictness=0):
    """
    Compare the warnings produced by scan-build.
    Strictness defines the success criteria for the test:
      0 - success if there are no crashes or analyzer failure.
      1 - success if there are no difference in the number of reported bugs.
      2 - success if all the bug reports are identical.

    :return success: Whether tests pass according to the Strictness
    criteria.
    """
    TestsPassed = True
    TBegin = time.time()

    RefDir = os.path.join(Dir, SBOutputDirReferencePrefix + SBOutputDirName)
    NewDir = os.path.join(Dir, SBOutputDirName)

    # We have to go one level down the directory tree.
    RefList = glob.glob(RefDir + "/*")
    NewList = glob.glob(NewDir + "/*")

    # Log folders are also located in the results dir, so ignore them.
    RefLogDir = os.path.join(RefDir, LogFolderName)
    if RefLogDir in RefList:
        RefList.remove(RefLogDir)
    NewList.remove(os.path.join(NewDir, LogFolderName))

    if len(RefList) != len(NewList):
        print("Mismatch in number of results folders: %s vs %s" % (
            RefList, NewList))
        sys.exit(1)

    # There might be more then one folder underneath - one per each scan-build
    # command (Ex: one for configure and one for make).
    if (len(RefList) > 1):
        # Assume that the corresponding folders have the same names.
        RefList.sort()
        NewList.sort()

    # Iterate and find the differences.
    NumDiffs = 0
    for P in zip(RefList, NewList):
        RefDir = P[0]
        NewDir = P[1]

        assert(RefDir != NewDir)
        if Verbose == 1:
            Local.stdout.write("  Comparing Results: %s %s\n" % (
                               RefDir, NewDir))

        PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
        Opts, Args = CmpRuns.generate_option_parser().parse_args(
            ["--rootA", "", "--rootB", PatchedSourceDirPath])
        # Scan the results, delete empty plist files.
        NumDiffs, ReportsInRef, ReportsInNew = \
            CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts,
                                             deleteEmpty=False,
                                             Stdout=Local.stdout)
        if (NumDiffs > 0):
            Local.stdout.write("Warning: %s differences in diagnostics.\n"
                               % NumDiffs)
        if Strictness >= 2 and NumDiffs > 0:
            Local.stdout.write("Error: Diffs found in strict mode (2).\n")
            TestsPassed = False
        elif Strictness >= 1 and ReportsInRef != ReportsInNew:
            Local.stdout.write("Error: The number of results are different " +
                               " strict mode (1).\n")
            TestsPassed = False

    Local.stdout.write("Diagnostic comparison complete (time: %.2f).\n" % (
                       time.time() - TBegin))
    return TestsPassed


def cleanupReferenceResults(SBOutputDir):
    """
    Delete html, css, and js files from reference results. These can
    include multiple copies of the benchmark source and so get very large.
    """
    Extensions = ["html", "css", "js"]
    for E in Extensions:
        for F in glob.glob("%s/*/*.%s" % (SBOutputDir, E)):
            P = os.path.join(SBOutputDir, F)
            RmCommand = "rm '%s'" % P
            check_call(RmCommand, shell=True)

    # Remove the log file. It leaks absolute path names.
    removeLogFile(SBOutputDir)


class TestProjectThread(threading.Thread):
    def __init__(self, Args, TasksQueue, ResultsDiffer, FailureFlag):
        """
        :param ResultsDiffer: Used to signify that results differ from
        the canonical ones.
        :param FailureFlag: Used to signify a failure during the run.
        """
        self.Args = Args
        self.TasksQueue = TasksQueue
        self.ResultsDiffer = ResultsDiffer
        self.FailureFlag = FailureFlag
        super(TestProjectThread, self).__init__()

        # Needed to gracefully handle interrupts with Ctrl-C
        self.daemon = True

    def run(self):
        while not self.TasksQueue.empty():
            try:
                ProjArgs = self.TasksQueue.get()
                Logger = logging.getLogger(ProjArgs[0])
                Local.stdout = StreamToLogger(Logger, logging.INFO)
                Local.stderr = StreamToLogger(Logger, logging.ERROR)
                if not testProject(Args, *ProjArgs):
                    self.ResultsDiffer.set()
                self.TasksQueue.task_done()
            except:
                self.FailureFlag.set()
                raise


def testProject(Args, ID, ProjectBuildMode, IsReferenceBuild=False, Strictness=0):
    """
    Test a given project.
    :return TestsPassed: Whether tests have passed according
    to the :param Strictness: criteria.
    """
    Local.stdout.write(" \n\n--- Building project %s\n" % (ID,))

    TBegin = time.time()

    Dir = getProjectDir(ID)
    if Verbose == 1:
        Local.stdout.write("  Build directory: %s.\n" % (Dir,))

    # Set the build results directory.
    RelOutputDir = getSBOutputDirName(IsReferenceBuild)
    SBOutputDir = os.path.join(Dir, RelOutputDir)

    buildProject(Args, Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild)

    checkBuild(SBOutputDir)

    if IsReferenceBuild:
        cleanupReferenceResults(SBOutputDir)
        TestsPassed = True
    else:
        TestsPassed = runCmpResults(Dir, Strictness)

    Local.stdout.write("Completed tests for project %s (time: %.2f).\n" % (
                       ID, (time.time() - TBegin)))
    return TestsPassed


def projectFileHandler():
    return open(getProjectMapPath(), "rb")


def iterateOverProjects(PMapFile):
    """
    Iterate over all projects defined in the project file handler `PMapFile`
    from the start.
    """
    PMapFile.seek(0)
    for I in csv.reader(PMapFile):
        if (SATestUtils.isCommentCSVLine(I)):
            continue
        yield I


def validateProjectFile(PMapFile):
    """
    Validate project file.
    """
    for I in iterateOverProjects(PMapFile):
        if len(I) != 2:
            print("Error: Rows in the ProjectMapFile should have 2 entries.")
            raise Exception()
        if I[1] not in ('0', '1', '2'):
            print("Error: Second entry in the ProjectMapFile should be 0" \
                  " (single file), 1 (project), or 2(single file c++11).")
            raise Exception()

def singleThreadedTestAll(Args, ProjectsToTest):
    """
    Run all projects.
    :return: whether tests have passed.
    """
    Success = True
    for ProjArgs in ProjectsToTest:
        Success &= testProject(Args, *ProjArgs)
    return Success

def multiThreadedTestAll(Args, ProjectsToTest, Jobs):
    """
    Run each project in a separate thread.

    This is OK despite GIL, as testing is blocked
    on launching external processes.

    :return: whether tests have passed.
    """
    TasksQueue = queue.Queue()

    for ProjArgs in ProjectsToTest:
        TasksQueue.put(ProjArgs)

    ResultsDiffer = threading.Event()
    FailureFlag = threading.Event()

    for i in range(Jobs):
        T = TestProjectThread(Args, TasksQueue, ResultsDiffer, FailureFlag)
        T.start()

    # Required to handle Ctrl-C gracefully.
    while TasksQueue.unfinished_tasks:
        time.sleep(0.1)  # Seconds.
        if FailureFlag.is_set():
            Local.stderr.write("Test runner crashed\n")
            sys.exit(1)
    return not ResultsDiffer.is_set()


def testAll(Args):
    ProjectsToTest = []

    with projectFileHandler() as PMapFile:
        validateProjectFile(PMapFile)

        # Test the projects.
        for (ProjName, ProjBuildMode) in iterateOverProjects(PMapFile):
            ProjectsToTest.append((ProjName,
                                  int(ProjBuildMode),
                                  Args.regenerate,
                                  Args.strictness))
    if Args.jobs <= 1:
        return singleThreadedTestAll(Args, ProjectsToTest)
    else:
        return multiThreadedTestAll(Args, ProjectsToTest, Args.jobs)


if __name__ == '__main__':
    # Parse command line arguments.
    Parser = argparse.ArgumentParser(
        description='Test the Clang Static Analyzer.')
    Parser.add_argument('--strictness', dest='strictness', type=int, default=0,
                        help='0 to fail on runtime errors, 1 to fail when the \
                             number of found bugs are different from the \
                             reference, 2 to fail on any difference from the \
                             reference. Default is 0.')
    Parser.add_argument('-r', dest='regenerate', action='store_true',
                        default=False, help='Regenerate reference output.')
    Parser.add_argument('-j', '--jobs', dest='jobs', type=int,
                        default=0,
                        help='Number of projects to test concurrently')
    Parser.add_argument('--extra-analyzer-config', dest='extra_analyzer_config',
                        type=str,
                        default="",
                        help="Arguments passed to to -analyzer-config")
    Args = Parser.parse_args()

    TestsPassed = testAll(Args)
    if not TestsPassed:
        print("ERROR: Tests failed.")
        sys.exit(42)
