diff --git a/bin/run_testcase_bisect b/bin/run_testcase_bisect index 30816d3e1b6915c3eb5c49b88c2913a4d145111f..0739fdcd0bf181f903a6e9a96933bb638f233b38 100755 --- a/bin/run_testcase_bisect +++ b/bin/run_testcase_bisect @@ -3,51 +3,67 @@ """%prog [options] testcase -Helper script to use `hg bisect` to find a bug by dichotomy. +Helper script to use `git bisect` to find a bug by dichotomy. -You know that the testcase fails at the parent revision (for example #1501). -You know that the testcase is ok at the revision for example #1481. +You know that the testcase fails at the parent revision (for example 539426c9dd). +You know that the testcase is ok at the revision for example f030e0ee5d. - @ 1501: known as bad + @ 539426c9dd: known as bad | - o 1500: ? + o 16c0aff5385: ? | ... | - o 1483: ? + o 61d352a4c6e: ? | - o 1481: known as good + o f030e0ee5d: known as good The command is: - $ run_testcase_bisect --good 1481 --bad 1501 sslp114a - - Testing changeset 1489:6ed91ad5ae5d (16 changesets remaining, ~4 tests) - 94 files updated, 0 files merged, 11 files removed, 0 files unresolved - INFO testcase output: /tmp/runtest_31mDvc/sslp114a.output - INFO this revision is good - Testing changeset 1495:a04dec3fb60d (8 changesets remaining, ~3 tests) - 115 files updated, 0 files merged, 11 files removed, 0 files unresolved - - INFO testcase output: /tmp/runtest_8eNSGd/sslp114a.output - INFO this revision is bad - Testing changeset 1491:774811d6dea5 (4 changesets remaining, ~2 tests) - 29 files updated, 0 files merged, 0 files removed, 0 files unresolved - - INFO testcase output: /tmp/runtest_eyCzHW/sslp114a.output - INFO this revision is good - Testing changeset 1492:6588f79c98cf (2 changesets remaining, ~1 tests) - 24 files updated, 0 files merged, 3 files removed, 0 files unresolved - - INFO testcase output: /tmp/runtest_YFxoA2/sslp114a.output - INFO this revision is bad - The first bad revision is: - changeset: 1492:6588f79c98cf - user: ... - date: ... - summary: ... - -The bad revision is found in 4 runs instead of 20 using brut force. + $ run_testcase_bisect --good f030e0ee5d --bad 539426c9dd zzzz123a + + Bisecting: 3 revisions left to test after this (roughly 2 steps) + [c8b0022b3118ef2af8a79827fa1c05bf55e93273] [#32337] compute the term dStress_nn_du + build at the commit + checking environment... loading /opt/public/scibian9_mpi.sh + executing: ./waf.engine install -p --out=build/mpi --jobs=4 + + build the elements catalog elem.1 using installed aster (from cata_ele.ojb) + 'install' finished successfully (40.507s) + run the testcase + testcase output: /tmp/runtest_c5iugpx7/zzzz123a.mpi.release.output + this revision is good + + Bisecting: 1 revision left to test after this (roughly 1 step) + [539426c9dd28385388004149f6ad3845eea9bb70] [#32337] Add CNH8Q4 contact element + + build at the commit + checking environment... loading /opt/public/scibian9_mpi.sh + executing: ./waf.engine install -p --out=build/mpi --jobs=4 + + build the elements catalog elem.1 using installed aster (from cata_ele.ojb) + 'install' finished successfully (27.938s) + run the testcase + testcase output: /tmp/runtest_dcz8a63t/zzzz123a.mpi.release.output + this revision is good + + Bisecting: 0 revisions left to test after this (roughly 0 steps) + [1f0c0ac1950a3b3271cfd44cccf255b628ed950d] [#32336] Handling some exceptions + + build at the commit + checking environment... loading /opt/public/scibian9_mpi.sh + executing: ./waf.engine install -p --out=build/mpi --jobs=4 + + build the elements catalog elem.1 using installed aster (from cata_ele.ojb) + 'install' finished successfully (1m1.839s) + run the testcase + testcase output: /tmp/runtest_vjwnkahh/zzzz123a.mpi.release.output + this revision is bad + + 1f0c0ac1950a3b3271cfd44cccf255b628ed950d is the first bad commit + commit 1f0c0ac1950a3b3271cfd44cccf255b628ed950d + Author: Author <Author@edf.fr> + Date: Mon Jan 30 17:39:18 2023 +0100 + + [#32336] Handling some exceptions +The bad revision is found in 3 runs instead of 6. At each tested revision, it runs: @@ -152,6 +168,7 @@ if __name__ == '__main__': silent=not opts.debug, hook=hook, patch=opts.patch) + if opts.bisect: bisect_main(func, opts.good, opts.bad) else: diff --git a/lib/hgaster/bisect_engine.py b/lib/hgaster/bisect_engine.py index 947d4ce442bc402dae9d602a57fbef14c4d1121e..1a84cf35eb55e930c885060e056b88e26b11235e 100644 --- a/lib/hgaster/bisect_engine.py +++ b/lib/hgaster/bisect_engine.py @@ -44,7 +44,7 @@ def run_install(waf, vdbg, opts=None, configure=None, silent=True): if configure: ok = run_configure(waf, opts, silent) if ok: - logger.title(_("build at the revision")) + logger.title(_("build at the commit")) dbg = vdbg and "_debug" or "" cmd = [waf, "install" + dbg] + opts # because it blocks with silent=True ?!! with or without '-p' ! @@ -58,14 +58,14 @@ def run_install(waf, vdbg, opts=None, configure=None, silent=True): def run_testcase1(testcase, waf, vdbg, opts=None, configure=None, silent=True, hook=None, patch=None): - """Check the testcase at the current revision + """Check the testcase at the current commit Arguments: testcase (str): the testcase to check. waf (str): the waf script to be used. vdbg (bool): if True, use the debug version. opts (list): aditional options passed to the waf command. - configure (bool): if True, run configure at each tested revision. + configure (bool): if True, run configure at each tested commit. silent (bool): if False, print the execution trace. hook (callable): function called after each execution. patch (filename): patch applied before each build. @@ -95,7 +95,7 @@ def run_testcase1(testcase, waf, vdbg, opts=None, configure=None, ok = hook(ok, output) # revert the patch if patch: - SPR.check_call(["hg", "revert", "-aC"]) + SPR.check_call(["git", "checkout", "."]) logger.info(_("patch reverted.")) return ok @@ -111,11 +111,11 @@ def bisect_main(testfunc, good, bad): env = os.environ.copy() env['LANGUAGE'] = 'en' try: - SPR.check_call(["hg", "bisect", '--reset']) - SPR.check_call(["hg", "bisect", '--good', good]) - SPR.check_call(["hg", "bisect", '--bad', bad]) + SPR.check_call(["git", "bisect", 'start']) + SPR.check_call(["git", "bisect", 'good', good]) + SPR.check_call(["git", "bisect", 'bad', bad]) except SPR.CalledProcessError: - logger.error(_("`hg bisect` command failed. Usually this means that " + logger.error(_("`git bisect` command failed. Usually this means that " "there are uncommitted changes. If you have to patch " "the source code, consider the `--patch` option.")) raise @@ -127,28 +127,31 @@ def bisect_main(testfunc, good, bad): else: result = "bad" logger.title(_("this revision is {0}").format(result)) - proc = Popen(["hg", "bisect", "--" + result], + proc = Popen(["git", "bisect", result], env=env, stdout=PIPE, stderr=STDOUT) err = convert(proc.communicate()[0]) logger.info(err) assert proc.returncode == 0 - ended = 'Testing changeset' not in err + ended = 'first bad commit' in err + SPR.run(["git", "bisect", "reset"], env=env) cleanup() def runall_main(testfunc, good, bad): - """Main loop on all revisions + """Main loop on all commits testfunc() returns True if it is good, False if bad""" - proc = Popen(["hg", "log", "--rev", "{0}::{1}".format(good, bad), - "--template", "{node} "], stdout=PIPE, stderr=STDOUT) + + proc = Popen(["git", "rev-list", "--ancestry-path", "{0}..{1}".format(good, bad)], + stdout=PIPE, stderr=STDOUT) out = convert(proc.communicate()[0]) lrev = out.split() + lrev.reverse() nbr = len(lrev) for i, rev in enumerate(lrev): proc = Popen( - ["hg", "update", "--rev", rev], stdout=PIPE, stderr=STDOUT) + ["git", "checkout", rev], stdout=PIPE, stderr=STDOUT) err = convert(proc.communicate()[0]) - logger.title(_("run at revision {0} ({1:d}/{2:d})") + logger.title(_("run at commit {0} ({1:d}/{2:d})") .format(getparent(), i + 1, nbr)) logger.info(err) assert proc.returncode == 0 @@ -166,7 +169,7 @@ def cleanup(): def getparent(): """Return an identifier of the parent revision""" - cmd = ['hg', 'parent', '--template', '{rev}:{node|short}'] + cmd = ['git', 'rev-list', 'HEAD', '-1'] return convert(Popen(cmd, stdout=PIPE).communicate()[0])