コード例 #1
0
ファイル: compileShell.py プロジェクト: byteways/funfuzz
def main():
    """Build a shell and place it in the autoBisect cache."""
    usage = 'Usage: %prog [options]'
    parser = OptionParser(usage)
    parser.disable_interspersed_args()

    parser.set_defaults(
        buildOptions="",
    )

    # Specify how the shell will be built.
    # See buildOptions.py for details.
    parser.add_option('-b', '--build',
                      dest='buildOptions',
                      help="Specify build options, e.g. -b '--disable-debug --enable-optimize' "
                           "(python buildOptions.py --help)")

    parser.add_option('-r', '--rev',
                      dest='revision',
                      help='Specify revision to build')

    options = parser.parse_args()[0]
    options.buildOptions = buildOptions.parseShellOptions(options.buildOptions)

    with LockDir(getLockDirPath(options.buildOptions.repoDir)):
        if options.revision:
            shell = CompiledShell(options.buildOptions, options.revision)
        else:
            localOrigHgHash = hgCmds.getRepoHashAndId(options.buildOptions.repoDir)[0]
            shell = CompiledShell(options.buildOptions, localOrigHgHash)

        obtainShell(shell, updateToRev=options.revision)
        print(shell.getShellCacheFullPath())
コード例 #2
0
ファイル: compileShell.py プロジェクト: RanchoIce/funfuzz
def main():
    """Build a shell and place it in the autoBisect cache."""

    usage = 'Usage: %prog [options]'
    parser = OptionParser(usage)
    parser.disable_interspersed_args()

    parser.set_defaults(
        buildOptions="",
    )

    # Specify how the shell will be built.
    # See buildOptions.py for details.
    parser.add_option('-b', '--build',
                      dest='buildOptions',
                      help='Specify build options, e.g. -b "--disable-debug --enable-optimize" ' +
                      '(python buildOptions.py --help)')

    parser.add_option('-r', '--rev',
                      dest='revision',
                      help='Specify revision to build')

    options = parser.parse_args()[0]
    options.buildOptions = buildOptions.parseShellOptions(options.buildOptions)

    with LockDir(getLockDirPath(options.buildOptions.repoDir)):
        if options.revision:
            shell = CompiledShell(options.buildOptions, options.revision)
        else:
            localOrigHgHash = hgCmds.getRepoHashAndId(options.buildOptions.repoDir)[0]
            shell = CompiledShell(options.buildOptions, localOrigHgHash)

        obtainShell(shell, updateToRev=options.revision)
        print shell.getShellCacheFullPath()
コード例 #3
0
def ensureBuild(options):
    if options.existingBuildDir:
        # Pre-downloaded treeherder builds (browser only for now)
        bDir = options.existingBuildDir
        bType = 'local-build'
        bSrc = bDir
        bRev = ''
        manyTimedRunArgs = []
    elif not options.useTreeherderBuilds:
        # Compiled browser
        options.buildOptions = buildBrowser.parseOptions(
            options.buildOptions.split())
        bDir = options.buildOptions.objDir
        bType = platform.system() + "-" + os.path.basename(
            options.buildOptions.mozconfig)
        bSrc = repr(hgCmds.getRepoHashAndId(options.buildOptions.repoDir))
        bRev = ''
        manyTimedRunArgs = []
        success = buildBrowser.tryCompiling(options.buildOptions)
        if not success:
            raise Exception('Building a browser failed.')
    else:
        # Treeherder browser
        # Download from Treeherder and call it 'build'
        # FIXME: Put 'build' somewhere nicer, like ~/fuzzbuilds/. Don't re-download a build that's up to date.
        # FIXME: randomize branch selection, get appropriate builds, use appropriate known dirs
        bDir = 'build'
        bType = downloadBuild.defaultBuildType(options.repoName, None, True)
        bSrc = downloadBuild.downloadLatestBuild(bType,
                                                 './',
                                                 getJsShell=False,
                                                 wantTests=True)
        bRev = ''

        # These two lines are only used for treeherder js shells:
        shell = os.path.join(bDir, "dist", "js.exe" if sps.isWin else "js")
        manyTimedRunArgs = [
            "--random-flags",
            str(JS_SHELL_DEFAULT_TIMEOUT), "mozilla-central", shell
        ]

    return BuildInfo(bDir, bType, bSrc, bRev, manyTimedRunArgs)
コード例 #4
0
def parseOpts():
    usage = 'Usage: %prog [options]'
    parser = OptionParser(usage)
    # http://docs.python.org/library/optparse.html#optparse.OptionParser.disable_interspersed_args
    parser.disable_interspersed_args()

    parser.set_defaults(
        resetRepoFirst=False,
        startRepo=None,
        endRepo='default',
        testInitialRevs=True,
        output='',
        watchExitCode=None,
        useInterestingnessTests=False,
        parameters=
        '-e 42',  # http://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy
        compilationFailedLabel='skip',
        buildOptions="",
        useTreeherderBinaries=False,
        nameOfTreeherderBranch='mozilla-inbound',
    )

    # Specify how the shell will be built.
    # See buildOptions.py for details.
    parser.add_option(
        '-b',
        '--build',
        dest='buildOptions',
        help=
        'Specify js shell build options, e.g. -b "--enable-debug --32" (python buildOptions.py --help)'
    )
    parser.add_option(
        '-B',
        '--browser',
        dest='browserOptions',
        help='Specify browser build options, e.g. -b "-c mozconfig"')

    parser.add_option(
        '--resetToTipFirst',
        dest='resetRepoFirst',
        action='store_true',
        help='First reset to default tip overwriting all local changes. ' +
        'Equivalent to first executing `hg update -C default`. ' +
        'Defaults to "%default".')

    # Specify the revisions between which to bisect.
    parser.add_option(
        '-s',
        '--startRev',
        dest='startRepo',
        help=
        'Earliest changeset/build numeric ID to consider (usually a "good" cset). '
        + 'Defaults to the earliest revision known to work at all/available.')
    parser.add_option(
        '-e',
        '--endRev',
        dest='endRepo',
        help=
        'Latest changeset/build numeric ID to consider (usually a "bad" cset). '
        +
        'Defaults to the head of the main branch, "default", or latest available build.'
    )
    parser.add_option(
        '-k',
        '--skipInitialRevs',
        dest='testInitialRevs',
        action='store_false',
        help=
        'Skip testing the -s and -e revisions and automatically trust them ' +
        'as -g and -b.')

    # Specify the type of failure to look for.
    # (Optional -- by default, internalTestAndLabel will look for exit codes that indicate a crash or assert.)
    parser.add_option(
        '-o',
        '--output',
        dest='output',
        help='Stdout or stderr output to be observed. Defaults to "%default". '
        + 'For assertions, set to "ssertion fail"')
    parser.add_option(
        '-w',
        '--watchExitCode',
        dest='watchExitCode',
        type='int',
        help='Look out for a specific exit code. Only this exit code will be '
        + 'considered "bad".')
    parser.add_option(
        '-i',
        '--useInterestingnessTests',
        dest='useInterestingnessTests',
        action="store_true",
        help="Interpret the final arguments as an interestingness test.")

    # Specify parameters for the js shell.
    parser.add_option(
        '-p',
        '--parameters',
        dest='parameters',
        help=
        'Specify parameters for the js shell, e.g. -p "-a --ion-eager testcase.js".'
    )

    # Specify how to treat revisions that fail to compile.
    # (You might want to add these to kbew.knownBrokenRanges in knownBrokenEarliestWorking.py.)
    parser.add_option(
        '-l',
        '--compilationFailedLabel',
        dest='compilationFailedLabel',
        help='Specify how to treat revisions that fail to compile. ' +
        '(bad, good, or skip) Defaults to "%default"')

    parser.add_option(
        '-T',
        '--useTreeherderBinaries',
        dest='useTreeherderBinaries',
        action="store_true",
        help='Use treeherder binaries for quick bisection, assuming a fast ' +
        'internet connection. Defaults to "%default"')
    parser.add_option(
        '-N',
        '--nameOfTreeherderBranch',
        dest='nameOfTreeherderBranch',
        help='Name of the branch to download. Defaults to "%default"')

    (options, args) = parser.parse_args()
    if options.browserOptions:
        assert not options.buildOptions
        options.browserOptions = buildBrowser.parseOptions(
            options.browserOptions.split())
        options.skipRevs = ' + '.join(
            kbew.knownBrokenRangesBrowser(options.browserOptions))
    else:
        options.buildOptions = buildOptions.parseShellOptions(
            options.buildOptions)
        options.skipRevs = ' + '.join(
            kbew.knownBrokenRanges(options.buildOptions))

    options.paramList = [
        sps.normExpUserPath(x) for x in options.parameters.split(' ') if x
    ]
    # First check that the testcase is present.
    if '-e 42' not in options.parameters and not os.path.isfile(
            options.paramList[-1]):
        print '\nList of parameters to be passed to the shell is: ' + ' '.join(
            options.paramList)
        print
        raise Exception('Testcase at ' + options.paramList[-1] +
                        ' is not present.')

    assert options.compilationFailedLabel in ('bad', 'good', 'skip')

    extraFlags = []

    if options.useInterestingnessTests:
        if len(args) < 1:
            print 'args are: ' + args
            parser.error('Not enough arguments.')
        if not options.browserOptions:
            for a in args:
                if a.startswith("--flags="):
                    extraFlags = a[8:].split(' ')
        options.testAndLabel = externalTestAndLabel(options, args)
    else:
        assert not options.browserOptions  # autoBisect doesn't have a built-in way to run the browser
        if len(args) >= 1:
            parser.error('Too many arguments.')
        options.testAndLabel = internalTestAndLabel(options)

    if options.browserOptions:
        earliestKnownQuery = kbew.earliestKnownWorkingRevForBrowser(
            options.browserOptions)
    else:
        earliestKnownQuery = kbew.earliestKnownWorkingRev(
            options.buildOptions, options.paramList + extraFlags,
            options.skipRevs)

    earliestKnown = ''

    if not options.useTreeherderBinaries:
        earliestKnown = hgCmds.getRepoHashAndId(options.buildOptions.repoDir,
                                                repoRev=earliestKnownQuery)[0]

    if options.startRepo is None:
        if options.useTreeherderBinaries:
            options.startRepo = 'default'
        else:
            options.startRepo = earliestKnown
    # elif not (options.useTreeherderBinaries or hgCmds.isAncestor(options.buildOptions.repoDir, earliestKnown, options.startRepo)):
    #     raise Exception('startRepo is not a descendant of kbew.earliestKnownWorkingRev for this configuration')
    #
    # if not options.useTreeherderBinaries and not hgCmds.isAncestor(options.buildOptions.repoDir, earliestKnown, options.endRepo):
    #     raise Exception('endRepo is not a descendant of kbew.earliestKnownWorkingRev for this configuration')

    if options.parameters == '-e 42':
        print "Note: since no parameters were specified, we're just ensuring the shell does not crash on startup/shutdown."

    if options.nameOfTreeherderBranch != 'mozilla-inbound' and not options.useTreeherderBinaries:
        raise Exception(
            'Setting the name of branches only works for treeherder shell bisection.'
        )

    return options
コード例 #5
0
def findBlamedCset(options, repoDir, testRev):
    print "%s | Bisecting on: %s" % (sps.dateStr(), repoDir)

    hgPrefix = ['hg', '-R', repoDir]

    # Resolve names such as "tip", "default", or "52707" to stable hg hash ids, e.g. "9f2641871ce8".
    realStartRepo = sRepo = hgCmds.getRepoHashAndId(
        repoDir, repoRev=options.startRepo)[0]
    realEndRepo = eRepo = hgCmds.getRepoHashAndId(repoDir,
                                                  repoRev=options.endRepo)[0]
    sps.vdump("Bisecting in the range " + sRepo + ":" + eRepo)

    # Refresh source directory (overwrite all local changes) to default tip if required.
    if options.resetRepoFirst:
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        # Throws exit code 255 if purge extension is not enabled in .hgrc:
        subprocess.check_call(hgPrefix + ['purge', '--all'])

    # Reset bisect ranges and set skip ranges.
    sps.captureStdout(hgPrefix + ['bisect', '-r'])
    if options.skipRevs:
        sps.captureStdout(hgPrefix + ['bisect', '--skip', options.skipRevs])

    labels = {}
    # Specify `hg bisect` ranges.
    if options.testInitialRevs:
        currRev = eRepo  # If testInitialRevs mode is set, compile and test the latest rev first.
    else:
        labels[sRepo] = ('good', 'assumed start rev is good')
        labels[eRepo] = ('bad', 'assumed end rev is bad')
        subprocess.check_call(hgPrefix + ['bisect', '-U', '-g', sRepo])
        currRev = hgCmds.getCsetHashFromBisectMsg(
            fileManipulation.firstLine(
                sps.captureStdout(hgPrefix +
                                  ['bisect', '-U', '-b', eRepo])[0]))

    iterNum = 1
    if options.testInitialRevs:
        iterNum -= 2

    skipCount = 0
    blamedRev = None

    while currRev is not None:
        startTime = time.time()
        label = testRev(currRev)
        labels[currRev] = label
        if label[0] == 'skip':
            skipCount += 1
            # If we use "skip", we tell hg bisect to do a linear search to get around the skipping.
            # If the range is large, doing a bisect to find the start and endpoints of compilation
            # bustage would be faster. 20 total skips being roughly the time that the pair of
            # bisections would take.
            if skipCount > 20:
                print 'Skipped 20 times, stopping autoBisect.'
                break
        print label[0] + " (" + label[1] + ") ",

        if iterNum <= 0:
            print 'Finished testing the initial boundary revisions...',
        else:
            print "Bisecting for the n-th round where n is", iterNum, "and 2^n is", \
                  str(2**iterNum), "...",
        (blamedGoodOrBad, blamedRev, currRev, sRepo, eRepo) = \
            bisectLabel(hgPrefix, options, label[0], currRev, sRepo, eRepo)

        if options.testInitialRevs:
            options.testInitialRevs = False
            assert currRev is None
            currRev = sRepo  # If options.testInitialRevs is set, test earliest possible rev next.

        iterNum += 1
        endTime = time.time()
        oneRunTime = endTime - startTime
        print 'This iteration took %.3f seconds to run.' % oneRunTime

    if blamedRev is not None:
        checkBlameParents(repoDir, blamedRev, blamedGoodOrBad, labels, testRev,
                          realStartRepo, realEndRepo)

    sps.vdump("Resetting bisect")
    subprocess.check_call(hgPrefix + ['bisect', '-U', '-r'])

    sps.vdump("Resetting working directory")
    sps.captureStdout(hgPrefix + ['update', '-C', '-r', 'default'],
                      ignoreStderr=True)
    hgCmds.destroyPyc(repoDir)

    print sps.dateStr()
コード例 #6
0
ファイル: bot.py プロジェクト: MikeHolman/funfuzz
def ensureBuild(options):
    if options.existingBuildDir:
        # Pre-downloaded treeherder builds (browser only for now)
        bDir = options.existingBuildDir
        bType = 'local-build'
        bSrc = bDir
        bRev = ''
        manyTimedRunArgs = []
    elif not options.useTreeherderBuilds:
        if options.testType == "js":
            # Compiled js shells
            options.buildOptions = buildOptions.parseShellOptions(options.buildOptions)
            options.timeout = options.timeout or machineTimeoutDefaults(options)

            with LockDir(compileShell.getLockDirPath(options.buildOptions.repoDir)):
                bRev = hgCmds.getRepoHashAndId(options.buildOptions.repoDir)[0]
                cshell = compileShell.CompiledShell(options.buildOptions, bRev)
                compileShell.obtainShell(cshell, updateLatestTxt=True)

                bDir = cshell.getShellCacheDir()
                # Strip out first 3 chars or else the dir name in fuzzing jobs becomes:
                #   js-js-dbg-opt-64-dm-linux
                # This is because options.testType gets prepended along with a dash later.
                bType = buildOptions.computeShellType(options.buildOptions)[3:]
                bSrc = (
                    'Create another shell in shell-cache like this one:\n' +
                    'python -u %s -b "%s -R %s" -r %s\n\n' % (
                        os.path.join(path3, 'compileShell.py'), options.buildOptions.buildOptionsStr,
                        options.buildOptions.repoDir, bRev
                    ) +
                    '==============================================\n' +
                    '|  Fuzzing %s js shell builds\n'  % cshell.getRepoName() +
                    '|  DATE: %s\n'                    % sps.dateStr() +
                    '==============================================\n\n')

                manyTimedRunArgs = mtrArgsCreation(options, cshell)
                print 'buildDir is: ' + bDir
                print 'buildSrc is: ' + bSrc
        else:
            # Compiled browser
            options.buildOptions = buildBrowser.parseOptions(options.buildOptions.split())
            bDir = options.buildOptions.objDir
            bType = platform.system() + "-" + os.path.basename(options.buildOptions.mozconfig)
            bSrc = repr(hgCmds.getRepoHashAndId(options.buildOptions.repoDir))
            bRev = ''
            manyTimedRunArgs = []
            success = buildBrowser.tryCompiling(options.buildOptions)
            if not success:
                raise Exception('Building a browser failed.')
    else:
        # Treeherder js shells and browser
        # Download from Treeherder and call it 'build'
        # FIXME: Put 'build' somewhere nicer, like ~/fuzzbuilds/. Don't re-download a build that's up to date.
        # FIXME: randomize branch selection, get appropriate builds, use appropriate known dirs
        bDir = 'build'
        bType = downloadBuild.defaultBuildType(options.repoName, None, True)
        bSrc = downloadBuild.downloadLatestBuild(bType, './', getJsShell=(options.testType == 'js'))
        bRev = ''

        # These two lines are only used for treeherder js shells:
        shell = os.path.join(bDir, "dist", "js.exe" if sps.isWin else "js")
        manyTimedRunArgs = ["--random-flags", str(JS_SHELL_DEFAULT_TIMEOUT), "mozilla-central", shell]

    return BuildInfo(bDir, bType, bSrc, bRev, manyTimedRunArgs)
コード例 #7
0
ファイル: bot.py プロジェクト: ArashAll/funfuzz
def ensureBuild(options):
    if options.existingBuildDir:
        # Pre-downloaded treeherder builds (browser only for now)
        bDir = options.existingBuildDir
        bType = 'local-build'
        bSrc = bDir
        bRev = ''
        manyTimedRunArgs = []
    elif not options.useTreeherderBuilds:
        if options.testType == "js":
            # Compiled js shells
            options.buildOptions = buildOptions.parseShellOptions(
                options.buildOptions)
            options.timeout = options.timeout or machineTimeoutDefaults(
                options)

            with LockDir(
                    compileShell.getLockDirPath(options.buildOptions.repoDir)):
                bRev = hgCmds.getRepoHashAndId(options.buildOptions.repoDir)[0]
                cshell = compileShell.CompiledShell(options.buildOptions, bRev)
                compileShell.obtainShell(cshell, updateLatestTxt=True)

                bDir = cshell.getShellCacheDir()
                # Strip out first 3 chars or else the dir name in fuzzing jobs becomes:
                #   js-js-dbg-opt-64-dm-linux
                # This is because options.testType gets prepended along with a dash later.
                bType = buildOptions.computeShellType(options.buildOptions)[3:]
                bSrc = (
                    'Create another shell in shell-cache like this one:\n' +
                    'python -u %s -b "%s -R %s" -r %s\n\n' %
                    (os.path.join(path3, 'compileShell.py'),
                     options.buildOptions.buildOptionsStr,
                     options.buildOptions.repoDir, bRev) +
                    '==============================================\n' +
                    '|  Fuzzing %s js shell builds\n' % cshell.getRepoName() +
                    '|  DATE: %s\n' % sps.dateStr() +
                    '==============================================\n\n')

                manyTimedRunArgs = mtrArgsCreation(options, cshell)
                print 'buildDir is: ' + bDir
                print 'buildSrc is: ' + bSrc
        else:
            # Compiled browser
            options.buildOptions = buildBrowser.parseOptions(
                options.buildOptions.split())
            bDir = options.buildOptions.objDir
            bType = platform.system() + "-" + os.path.basename(
                options.buildOptions.mozconfig)
            bSrc = repr(hgCmds.getRepoHashAndId(options.buildOptions.repoDir))
            bRev = ''
            manyTimedRunArgs = []
            success = buildBrowser.tryCompiling(options.buildOptions)
            if not success:
                raise Exception('Building a browser failed.')
    else:
        # Treeherder js shells and browser
        # Download from Treeherder and call it 'build'
        # FIXME: Put 'build' somewhere nicer, like ~/fuzzbuilds/. Don't re-download a build that's up to date.
        # FIXME: randomize branch selection, get appropriate builds, use appropriate known dirs
        bDir = 'build'
        bType = downloadBuild.defaultBuildType(options.repoName, None, True)
        bSrc = downloadBuild.downloadLatestBuild(
            bType, './', getJsShell=(options.testType == 'js'))
        bRev = ''

        # These two lines are only used for treeherder js shells:
        shell = os.path.join(bDir, "dist", "js.exe" if sps.isWin else "js")
        manyTimedRunArgs = [
            "--random-flags",
            str(JS_SHELL_DEFAULT_TIMEOUT), "mozilla-central", shell
        ]

    return BuildInfo(bDir, bType, bSrc, bRev, manyTimedRunArgs)
コード例 #8
0
ファイル: autoBisect.py プロジェクト: ArashAll/funfuzz
def parseOpts():
    usage = 'Usage: %prog [options]'
    parser = OptionParser(usage)
    # http://docs.python.org/library/optparse.html#optparse.OptionParser.disable_interspersed_args
    parser.disable_interspersed_args()

    parser.set_defaults(
        resetRepoFirst=False,
        startRepo=None,
        endRepo='default',
        testInitialRevs=True,
        output='',
        watchExitCode=None,
        useInterestingnessTests=False,
        parameters='-e 42',  # http://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy
        compilationFailedLabel='skip',
        buildOptions="",
        useTreeherderBinaries=False,
        nameOfTreeherderBranch='mozilla-inbound',
    )

    # Specify how the shell will be built.
    # See buildOptions.py for details.
    parser.add_option('-b', '--build',
                      dest='buildOptions',
                      help='Specify js shell build options, e.g. -b "--enable-debug --32" (python buildOptions.py --help)')
    parser.add_option('-B', '--browser',
                      dest='browserOptions',
                      help='Specify browser build options, e.g. -b "-c mozconfig"')

    parser.add_option('--resetToTipFirst', dest='resetRepoFirst',
                      action='store_true',
                      help='First reset to default tip overwriting all local changes. ' +
                      'Equivalent to first executing `hg update -C default`. ' +
                      'Defaults to "%default".')

    # Specify the revisions between which to bisect.
    parser.add_option('-s', '--startRev', dest='startRepo',
                      help='Earliest changeset/build numeric ID to consider (usually a "good" cset). ' +
                      'Defaults to the earliest revision known to work at all/available.')
    parser.add_option('-e', '--endRev', dest='endRepo',
                      help='Latest changeset/build numeric ID to consider (usually a "bad" cset). ' +
                      'Defaults to the head of the main branch, "default", or latest available build.')
    parser.add_option('-k', '--skipInitialRevs', dest='testInitialRevs',
                      action='store_false',
                      help='Skip testing the -s and -e revisions and automatically trust them ' +
                      'as -g and -b.')

    # Specify the type of failure to look for.
    # (Optional -- by default, internalTestAndLabel will look for exit codes that indicate a crash or assert.)
    parser.add_option('-o', '--output', dest='output',
                      help='Stdout or stderr output to be observed. Defaults to "%default". ' +
                      'For assertions, set to "ssertion fail"')
    parser.add_option('-w', '--watchExitCode', dest='watchExitCode',
                      type='int',
                      help='Look out for a specific exit code. Only this exit code will be ' +
                      'considered "bad".')
    parser.add_option('-i', '--useInterestingnessTests',
                      dest='useInterestingnessTests',
                      action="store_true",
                      help="Interpret the final arguments as an interestingness test.")

    # Specify parameters for the js shell.
    parser.add_option('-p', '--parameters', dest='parameters',
                      help='Specify parameters for the js shell, e.g. -p "-a --ion-eager testcase.js".')

    # Specify how to treat revisions that fail to compile.
    # (You might want to add these to kbew.knownBrokenRanges in knownBrokenEarliestWorking.py.)
    parser.add_option('-l', '--compilationFailedLabel', dest='compilationFailedLabel',
                      help='Specify how to treat revisions that fail to compile. ' +
                      '(bad, good, or skip) Defaults to "%default"')

    parser.add_option('-T', '--useTreeherderBinaries',
                      dest='useTreeherderBinaries',
                      action="store_true",
                      help='Use treeherder binaries for quick bisection, assuming a fast ' +
                      'internet connection. Defaults to "%default"')
    parser.add_option('-N', '--nameOfTreeherderBranch',
                      dest='nameOfTreeherderBranch',
                      help='Name of the branch to download. Defaults to "%default"')

    (options, args) = parser.parse_args()
    if options.browserOptions:
        assert not options.buildOptions
        options.browserOptions = buildBrowser.parseOptions(options.browserOptions.split())
        options.skipRevs = ' + '.join(kbew.knownBrokenRangesBrowser(options.browserOptions))
    else:
        options.buildOptions = buildOptions.parseShellOptions(options.buildOptions)
        options.skipRevs = ' + '.join(kbew.knownBrokenRanges(options.buildOptions))

    options.paramList = [sps.normExpUserPath(x) for x in options.parameters.split(' ') if x]
    # First check that the testcase is present.
    if '-e 42' not in options.parameters and not os.path.isfile(options.paramList[-1]):
        print '\nList of parameters to be passed to the shell is: ' + ' '.join(options.paramList)
        print
        raise Exception('Testcase at ' + options.paramList[-1] + ' is not present.')

    assert options.compilationFailedLabel in ('bad', 'good', 'skip')

    extraFlags = []

    if options.useInterestingnessTests:
        if len(args) < 1:
            print 'args are: ' + args
            parser.error('Not enough arguments.')
        if not options.browserOptions:
            for a in args:
                if a.startswith("--flags="):
                    extraFlags = a[8:].split(' ')
        options.testAndLabel = externalTestAndLabel(options, args)
    else:
        assert not options.browserOptions  # autoBisect doesn't have a built-in way to run the browser
        if len(args) >= 1:
            parser.error('Too many arguments.')
        options.testAndLabel = internalTestAndLabel(options)

    if options.browserOptions:
        earliestKnownQuery = kbew.earliestKnownWorkingRevForBrowser(options.browserOptions)
    else:
        earliestKnownQuery = kbew.earliestKnownWorkingRev(options.buildOptions, options.paramList + extraFlags, options.skipRevs)

    earliestKnown = ''

    if not options.useTreeherderBinaries:
        earliestKnown = hgCmds.getRepoHashAndId(options.buildOptions.repoDir, repoRev=earliestKnownQuery)[0]

    if options.startRepo is None:
        if options.useTreeherderBinaries:
            options.startRepo = 'default'
        else:
            options.startRepo = earliestKnown
    # elif not (options.useTreeherderBinaries or hgCmds.isAncestor(options.buildOptions.repoDir, earliestKnown, options.startRepo)):
    #     raise Exception('startRepo is not a descendant of kbew.earliestKnownWorkingRev for this configuration')
    #
    # if not options.useTreeherderBinaries and not hgCmds.isAncestor(options.buildOptions.repoDir, earliestKnown, options.endRepo):
    #     raise Exception('endRepo is not a descendant of kbew.earliestKnownWorkingRev for this configuration')

    if options.parameters == '-e 42':
        print "Note: since no parameters were specified, we're just ensuring the shell does not crash on startup/shutdown."

    if options.nameOfTreeherderBranch != 'mozilla-inbound' and not options.useTreeherderBinaries:
        raise Exception('Setting the name of branches only works for treeherder shell bisection.')

    return options
コード例 #9
0
ファイル: autoBisect.py プロジェクト: ArashAll/funfuzz
def findBlamedCset(options, repoDir, testRev):
    print sps.dateStr()

    hgPrefix = ['hg', '-R', repoDir]

    # Resolve names such as "tip", "default", or "52707" to stable hg hash ids, e.g. "9f2641871ce8".
    realStartRepo = sRepo = hgCmds.getRepoHashAndId(repoDir, repoRev=options.startRepo)[0]
    realEndRepo = eRepo = hgCmds.getRepoHashAndId(repoDir, repoRev=options.endRepo)[0]
    sps.vdump("Bisecting in the range " + sRepo + ":" + eRepo)

    # Refresh source directory (overwrite all local changes) to default tip if required.
    if options.resetRepoFirst:
        subprocess.check_call(hgPrefix + ['update', '-C', 'default'])
        # Throws exit code 255 if purge extension is not enabled in .hgrc:
        subprocess.check_call(hgPrefix + ['purge', '--all'])

    # Reset bisect ranges and set skip ranges.
    sps.captureStdout(hgPrefix + ['bisect', '-r'])
    if options.skipRevs:
        sps.captureStdout(hgPrefix + ['bisect', '--skip', options.skipRevs])

    labels = {}
    # Specify `hg bisect` ranges.
    if options.testInitialRevs:
        currRev = eRepo  # If testInitialRevs mode is set, compile and test the latest rev first.
    else:
        labels[sRepo] = ('good', 'assumed start rev is good')
        labels[eRepo] = ('bad', 'assumed end rev is bad')
        subprocess.check_call(hgPrefix + ['bisect', '-U', '-g', sRepo])
        currRev = hgCmds.getCsetHashFromBisectMsg(fileManipulation.firstLine(
            sps.captureStdout(hgPrefix + ['bisect', '-U', '-b', eRepo])[0]))

    iterNum = 1
    if options.testInitialRevs:
        iterNum -= 2

    skipCount = 0
    blamedRev = None

    while currRev is not None:
        startTime = time.time()
        label = testRev(currRev)
        labels[currRev] = label
        if label[0] == 'skip':
            skipCount += 1
            # If we use "skip", we tell hg bisect to do a linear search to get around the skipping.
            # If the range is large, doing a bisect to find the start and endpoints of compilation
            # bustage would be faster. 20 total skips being roughly the time that the pair of
            # bisections would take.
            if skipCount > 20:
                print 'Skipped 20 times, stopping autoBisect.'
                break
        print label[0] + " (" + label[1] + ") ",

        if iterNum <= 0:
            print 'Finished testing the initial boundary revisions...',
        else:
            print "Bisecting for the n-th round where n is", iterNum, "and 2^n is", \
                  str(2**iterNum), "...",
        (blamedGoodOrBad, blamedRev, currRev, sRepo, eRepo) = \
            bisectLabel(hgPrefix, options, label[0], currRev, sRepo, eRepo)

        if options.testInitialRevs:
            options.testInitialRevs = False
            assert currRev is None
            currRev = sRepo  # If options.testInitialRevs is set, test earliest possible rev next.

        iterNum += 1
        endTime = time.time()
        oneRunTime = endTime - startTime
        print 'This iteration took %.3f seconds to run.' % oneRunTime

    if blamedRev is not None:
        checkBlameParents(repoDir, blamedRev, blamedGoodOrBad, labels, testRev, realStartRepo,
                          realEndRepo)

    sps.vdump("Resetting bisect")
    subprocess.check_call(hgPrefix + ['bisect', '-U', '-r'])

    sps.vdump("Resetting working directory")
    sps.captureStdout(hgPrefix + ['update', '-C', '-r', 'default'], ignoreStderr=True)
    hgCmds.destroyPyc(repoDir)

    print sps.dateStr()