Mercurial > public > mercurial-scm > hg-stable
annotate tests/test-pathencode.py @ 19319:ec17ddecdf64 stable
test-pathencode: randomize length of each path component
This makes it possible for long and short components to exist in the same path.
This also makes shorter path components more likely. For
randint(1, randint(1, n)), the likelihood that one sees a number k
(1 <= k <= n) is 1/n * (\sum_{k=i}^n 1/i). This decreases with k, much like in
the real world where shorter paths are more common than longer ones.
The previous fix and this one together cause issue3958 to be detected by this
test with reasonable frequency. When this test was run 100 times in a loop, the
issue was detected 30 of those times.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Wed, 19 Jun 2013 23:05:40 -0700 |
parents | 9778c77f05d6 |
children | cf1b0a58a0de |
rev | line source |
---|---|
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
1 # This is a randomized test that generates different pathnames every |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
2 # time it is invoked, and tests the encoding of those pathnames. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
3 # |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
4 # It uses a simple probabilistic model to generate valid pathnames |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
5 # that have proven likely to expose bugs and divergent behaviour in |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
6 # different encoding implementations. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
7 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
8 from mercurial import parsers |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
9 from mercurial import store |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
10 import binascii, itertools, math, os, random, sys, time |
17935
9c888b945b65
test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents:
17934
diff
changeset
|
11 import collections |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
12 |
17947
f945caa5e963
test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents:
17935
diff
changeset
|
13 if sys.version_info[:2] < (2, 6): |
f945caa5e963
test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents:
17935
diff
changeset
|
14 sys.exit(0) |
f945caa5e963
test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents:
17935
diff
changeset
|
15 |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
16 validchars = set(map(chr, range(0, 256))) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
17 alphanum = range(ord('A'), ord('Z')) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
18 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
19 for c in '\0/': |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
20 validchars.remove(c) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
21 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
22 winreserved = ('aux con prn nul'.split() + |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
23 ['com%d' % i for i in xrange(1, 10)] + |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
24 ['lpt%d' % i for i in xrange(1, 10)]) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
25 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
26 def casecombinations(names): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
27 '''Build all case-diddled combinations of names.''' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
28 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
29 combos = set() |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
30 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
31 for r in names: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
32 for i in xrange(len(r) + 1): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
33 for c in itertools.combinations(xrange(len(r)), i): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
34 d = r |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
35 for j in c: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
36 d = ''.join((d[:j], d[j].upper(), d[j + 1:])) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
37 combos.add(d) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
38 return sorted(combos) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
39 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
40 def buildprobtable(fp, cmd='hg manifest tip'): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
41 '''Construct and print a table of probabilities for path name |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
42 components. The numbers are percentages.''' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
43 |
17935
9c888b945b65
test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents:
17934
diff
changeset
|
44 counts = collections.defaultdict(lambda: 0) |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
45 for line in os.popen(cmd).read().splitlines(): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
46 if line[-2:] in ('.i', '.d'): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
47 line = line[:-2] |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
48 if line.startswith('data/'): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
49 line = line[5:] |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
50 for c in line: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
51 counts[c] += 1 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
52 for c in '\r/\n': |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
53 counts.pop(c, None) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
54 t = sum(counts.itervalues()) / 100.0 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
55 fp.write('probtable = (') |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
56 for i, (k, v) in enumerate(sorted(counts.iteritems(), key=lambda x: x[1], |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
57 reverse=True)): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
58 if (i % 5) == 0: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
59 fp.write('\n ') |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
60 vt = v / t |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
61 if vt < 0.0005: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
62 break |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
63 fp.write('(%r, %.03f), ' % (k, vt)) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
64 fp.write('\n )\n') |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
65 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
66 # A table of character frequencies (as percentages), gleaned by |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
67 # looking at filelog names from a real-world, very large repo. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
68 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
69 probtable = ( |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
70 ('t', 9.828), ('e', 9.042), ('s', 8.011), ('a', 6.801), ('i', 6.618), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
71 ('g', 5.053), ('r', 5.030), ('o', 4.887), ('p', 4.363), ('n', 4.258), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
72 ('l', 3.830), ('h', 3.693), ('_', 3.659), ('.', 3.377), ('m', 3.194), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
73 ('u', 2.364), ('d', 2.296), ('c', 2.163), ('b', 1.739), ('f', 1.625), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
74 ('6', 0.666), ('j', 0.610), ('y', 0.554), ('x', 0.487), ('w', 0.477), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
75 ('k', 0.476), ('v', 0.473), ('3', 0.336), ('1', 0.335), ('2', 0.326), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
76 ('4', 0.310), ('5', 0.305), ('9', 0.302), ('8', 0.300), ('7', 0.299), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
77 ('q', 0.298), ('0', 0.250), ('z', 0.223), ('-', 0.118), ('C', 0.095), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
78 ('T', 0.087), ('F', 0.085), ('B', 0.077), ('S', 0.076), ('P', 0.076), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
79 ('L', 0.059), ('A', 0.058), ('N', 0.051), ('D', 0.049), ('M', 0.046), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
80 ('E', 0.039), ('I', 0.035), ('R', 0.035), ('G', 0.028), ('U', 0.026), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
81 ('W', 0.025), ('O', 0.017), ('V', 0.015), ('H', 0.013), ('Q', 0.011), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
82 ('J', 0.007), ('K', 0.005), ('+', 0.004), ('X', 0.003), ('Y', 0.001), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
83 ) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
84 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
85 for c, _ in probtable: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
86 validchars.remove(c) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
87 validchars = list(validchars) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
88 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
89 def pickfrom(rng, table): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
90 c = 0 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
91 r = rng.random() * sum(i[1] for i in table) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
92 for i, p in table: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
93 c += p |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
94 if c >= r: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
95 return i |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
96 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
97 reservedcombos = casecombinations(winreserved) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
98 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
99 # The first component of a name following a slash. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
100 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
101 firsttable = ( |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
102 (lambda rng: pickfrom(rng, probtable), 90), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
103 (lambda rng: rng.choice(validchars), 5), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
104 (lambda rng: rng.choice(reservedcombos), 5), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
105 ) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
106 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
107 # Components of a name following the first. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
108 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
109 resttable = firsttable[:-1] |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
110 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
111 # Special suffixes. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
112 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
113 internalsuffixcombos = casecombinations('.hg .i .d'.split()) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
114 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
115 # The last component of a path, before a slash or at the end of a name. |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
116 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
117 lasttable = resttable + ( |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
118 (lambda rng: '', 95), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
119 (lambda rng: rng.choice(internalsuffixcombos), 5), |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
120 ) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
121 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
122 def makepart(rng, k): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
123 '''Construct a part of a pathname, without slashes.''' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
124 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
125 p = pickfrom(rng, firsttable)(rng) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
126 l = len(p) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
127 ps = [p] |
19319
ec17ddecdf64
test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents:
19318
diff
changeset
|
128 maxl = rng.randint(1, k) |
ec17ddecdf64
test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents:
19318
diff
changeset
|
129 while l < maxl: |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
130 p = pickfrom(rng, resttable)(rng) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
131 l += len(p) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
132 ps.append(p) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
133 ps.append(pickfrom(rng, lasttable)(rng)) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
134 return ''.join(ps) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
135 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
136 def makepath(rng, j, k): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
137 '''Construct a complete pathname.''' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
138 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
139 return ('data/' + '/'.join(makepart(rng, k) for _ in xrange(j)) + |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
140 rng.choice(['.d', '.i'])) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
141 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
142 def genpath(rng, count): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
143 '''Generate random pathnames with gradually increasing lengths.''' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
144 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
145 mink, maxk = 1, 4096 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
146 def steps(): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
147 x, k = 0, mink |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
148 for i in xrange(count): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
149 yield mink + int(round(math.sqrt((maxk - mink) * float(i) / count))) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
150 for k in steps(): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
151 x = rng.randint(1, k) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
152 y = rng.randint(1, k) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
153 yield makepath(rng, x, y) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
154 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
155 def runtests(rng, seed, count): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
156 nerrs = 0 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
157 for p in genpath(rng, count): |
18435
8c019d2fd7c0
store: switch to C-based hashed path encoding
Bryan O'Sullivan <bryano@fb.com>
parents:
18110
diff
changeset
|
158 h = store._pathencode(p) # uses C implementation, if available |
18094
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
159 r = store._hybridencode(p, True) # reference implementation in Python |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
160 if h != r: |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
161 if nerrs == 0: |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
162 print >> sys.stderr, 'seed:', hex(seed)[:-1] |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
163 print >> sys.stderr, "\np: '%s'" % p.encode("string_escape") |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
164 print >> sys.stderr, "h: '%s'" % h.encode("string_escape") |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
165 print >> sys.stderr, "r: '%s'" % r.encode("string_escape") |
8ceabb34f1cb
test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents:
17947
diff
changeset
|
166 nerrs += 1 |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
167 return nerrs |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
168 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
169 def main(): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
170 import getopt |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
171 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
172 # Empirically observed to take about a second to run |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
173 count = 100 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
174 seed = None |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
175 opts, args = getopt.getopt(sys.argv[1:], 'c:s:', |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
176 ['build', 'count=', 'seed=']) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
177 for o, a in opts: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
178 if o in ('-c', '--count'): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
179 count = int(a) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
180 elif o in ('-s', '--seed'): |
18110
acfc6fab1361
test-pathencode: accept --seed parameter in hex as well
Adrian Buehlmann <adrian@cadifra.com>
parents:
18094
diff
changeset
|
181 seed = long(a, base=0) # accepts base 10 or 16 strings |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
182 elif o == '--build': |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
183 buildprobtable(sys.stdout, |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
184 'find .hg/store/data -type f && ' |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
185 'cat .hg/store/fncache 2>/dev/null') |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
186 sys.exit(0) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
187 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
188 if seed is None: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
189 try: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
190 seed = long(binascii.hexlify(os.urandom(16)), 16) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
191 except AttributeError: |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
192 seed = long(time.time() * 1000) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
193 |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
194 rng = random.Random(seed) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
195 if runtests(rng, seed, count): |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
196 sys.exit(1) |
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
197 |
17947
f945caa5e963
test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents:
17935
diff
changeset
|
198 if __name__ == '__main__': |
17934
736f1c09f321
tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff
changeset
|
199 main() |