#!/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 + " -cc1 "

    # For now, we assume the preprocessed files should be analyzed
    # with the OS X SDK.
    SDKPath = SATestUtils.getSDKPath("macosx")
    if SDKPath is not None:
        CmdPrefix += "-isysroot " + SDKPath + " "

    CmdPrefix += "-analyze -analyzer-output=plist -w "
    CmdPrefix += "-analyzer-checker=" + Checkers
    CmdPrefix += " -fcxx-exceptions -fblocks "
    CmdPrefix += " -analyzer-config %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
    PairList = zip(RefList, NewList)
    for P in PairList:
        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)
