Mercurial > hg
comparison tests/bruterebase.py @ 33708:71b77b61ed60
test-rebase: add a brute force test
Rebase is becoming more complex and it looks like a good idea to try some
brute force enumeration to cover cases that are hard to find manually.
Using brute force to generate repos in different shapes and enumerating the
rebase source and destination would generate too many cases that takes too
long to compute. This patch limits the "brute force" to only the "rebase
source" part. Repo and destination are still manual.
The added test cases are crafted manually to reveal some behaviors that are
not covered by other tests:
- "revlog index out of range" crash
- after rebase, p1 == p2, p2 != null
- "nothing to merge" abort
In the future we might want to add more tests here. For now I'm more
interested in revealing interesting behaviors in a minified way. I tried
some more complex cases but didn't find other interesting behaviors.
Differential Revision: https://phab.mercurial-scm.org/D262
author | Jun Wu <quark@fb.com> |
---|---|
date | Sun, 06 Aug 2017 11:40:53 -0700 |
parents | |
children | bab82c43c065 |
comparison
equal
deleted
inserted
replaced
33707:36d216dcae6a | 33708:71b77b61ed60 |
---|---|
1 # bruterebase.py - brute force rebase testing | |
2 # | |
3 # Copyright 2017 Facebook, Inc. | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
8 from __future__ import absolute_import | |
9 | |
10 from mercurial import ( | |
11 error, | |
12 registrar, | |
13 revsetlang, | |
14 ) | |
15 | |
16 from hgext import rebase | |
17 | |
18 cmdtable = {} | |
19 command = registrar.command(cmdtable) | |
20 | |
21 @command('debugbruterebase') | |
22 def debugbruterebase(ui, repo, source, dest): | |
23 """for every non-empty subset of source, run rebase -r subset -d dest | |
24 | |
25 Print one line summary for each subset. Assume obsstore is enabled. | |
26 """ | |
27 srevs = list(repo.revs(source)) | |
28 | |
29 with repo.wlock(), repo.lock(): | |
30 repolen = len(repo) | |
31 cl = repo.changelog | |
32 | |
33 def getdesc(rev): | |
34 result = cl.changelogrevision(rev).description | |
35 if rev >= repolen: | |
36 result += "'" | |
37 return result | |
38 | |
39 for i in xrange(1, 2 ** len(srevs)): | |
40 subset = [rev for j, rev in enumerate(srevs) if i & (1 << j) != 0] | |
41 spec = revsetlang.formatspec('%ld', subset) | |
42 tr = repo.transaction('rebase') | |
43 tr.report = lambda x: 0 # hide "transaction abort" | |
44 | |
45 ui.pushbuffer() | |
46 try: | |
47 rebase.rebase(ui, repo, dest=dest, rev=[spec]) | |
48 except error.Abort as ex: | |
49 summary = 'ABORT: %s' % ex | |
50 except Exception as ex: | |
51 summary = 'CRASH: %s' % ex | |
52 else: | |
53 # short summary about new nodes | |
54 cl = repo.changelog | |
55 descs = [] | |
56 for rev in xrange(repolen, len(repo)): | |
57 desc = '%s:' % getdesc(rev) | |
58 for prev in cl.parentrevs(rev): | |
59 if prev > -1: | |
60 desc += getdesc(prev) | |
61 descs.append(desc) | |
62 descs.sort() | |
63 summary = ' '.join(descs) | |
64 ui.popbuffer() | |
65 repo.vfs.tryunlink('rebasestate') | |
66 | |
67 subsetdesc = ''.join(getdesc(rev) for rev in subset) | |
68 ui.write(('%s: %s\n') % (subsetdesc.rjust(len(srevs)), summary)) | |
69 tr.abort() |