tests/test-pathencode.py
author Bryan O'Sullivan <bryano@fb.com>
Thu, 15 Nov 2012 22:24:36 -0800
changeset 17947 f945caa5e963
parent 17935 9c888b945b65
child 18094 8ceabb34f1cb
permissions -rw-r--r--
test-pathencode: more aggressively check for python < 2.6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
def hybridencode(path):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    17
    return store._hybridencode(path, True)
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
validchars = set(map(chr, range(0, 256)))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    20
alphanum = range(ord('A'), ord('Z'))
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
for c in '\0/':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    23
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    24
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    25
winreserved = ('aux con prn nul'.split() +
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    26
               ['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
    27
               ['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
    28
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    29
def casecombinations(names):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    30
    '''Build all case-diddled combinations of names.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    31
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    32
    combos = set()
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    33
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    34
    for r in names:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    35
        for i in xrange(len(r) + 1):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    36
            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
    37
                d = r
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    38
                for j in c:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    39
                    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
    40
                combos.add(d)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    41
    return sorted(combos)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    42
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    43
def buildprobtable(fp, cmd='hg manifest tip'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    44
    '''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
    45
    components.  The numbers are percentages.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    46
17935
9c888b945b65 test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents: 17934
diff changeset
    47
    counts = collections.defaultdict(lambda: 0)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    48
    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
    49
        if line[-2:] in ('.i', '.d'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    50
            line = line[:-2]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    51
        if line.startswith('data/'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    52
            line = line[5:]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    53
        for c in line:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    54
            counts[c] += 1
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    55
    for c in '\r/\n':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    56
        counts.pop(c, None)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    57
    t = sum(counts.itervalues()) / 100.0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    58
    fp.write('probtable = (')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    59
    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
    60
                                      reverse=True)):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    61
        if (i % 5) == 0:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    62
            fp.write('\n    ')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    63
        vt = v / t
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    64
        if vt < 0.0005:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    65
            break
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    66
        fp.write('(%r, %.03f), ' % (k, vt))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    67
    fp.write('\n    )\n')
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
# 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
    70
# 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
    71
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    72
probtable = (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    73
    ('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
    74
    ('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
    75
    ('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
    76
    ('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
    77
    ('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
    78
    ('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
    79
    ('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
    80
    ('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
    81
    ('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
    82
    ('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
    83
    ('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
    84
    ('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
    85
    ('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
    86
    )
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    87
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    88
for c, _ in probtable:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    89
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    90
validchars = list(validchars)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    91
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    92
def pickfrom(rng, table):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    93
    c = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    94
    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
    95
    for i, p in table:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    96
        c += p
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    97
        if c >= r:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    98
            return i
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    99
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   100
reservedcombos = casecombinations(winreserved)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   101
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   102
# 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
   103
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   104
firsttable = (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   105
    (lambda rng: pickfrom(rng, probtable), 90),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   106
    (lambda rng: rng.choice(validchars), 5),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   107
    (lambda rng: rng.choice(reservedcombos), 5),
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
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   110
# Components of a name following the first.
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   111
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   112
resttable = firsttable[:-1]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   113
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   114
# Special suffixes.
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   115
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   116
internalsuffixcombos = casecombinations('.hg .i .d'.split())
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   117
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   118
# 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
   119
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   120
lasttable = resttable + (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   121
    (lambda rng: '', 95),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   122
    (lambda rng: rng.choice(internalsuffixcombos), 5),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   123
    )
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
def makepart(rng, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   126
    '''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
   127
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   128
    p = pickfrom(rng, firsttable)(rng)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   129
    l = len(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   130
    ps = [p]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   131
    while l <= k:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   132
        p = pickfrom(rng, resttable)(rng)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   133
        l += len(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   134
        ps.append(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   135
    ps.append(pickfrom(rng, lasttable)(rng))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   136
    return ''.join(ps)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   137
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   138
def makepath(rng, j, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   139
    '''Construct a complete pathname.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   140
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   141
    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
   142
            rng.choice(['.d', '.i']))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   143
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   144
def genpath(rng, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   145
    '''Generate random pathnames with gradually increasing lengths.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   146
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   147
    mink, maxk = 1, 4096
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   148
    def steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   149
        x, k = 0, mink
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   150
        for i in xrange(count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   151
            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
   152
    for k in steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   153
        x = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   154
        y = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   155
        yield makepath(rng, x, y)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   156
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   157
def runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   158
    nerrs = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   159
    for p in genpath(rng, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   160
        hybridencode(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   161
    return nerrs
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   162
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   163
def main():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   164
    import getopt
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   165
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   166
    # 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
   167
    count = 100
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   168
    seed = None
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   169
    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
   170
                               ['build', 'count=', 'seed='])
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   171
    for o, a in opts:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   172
        if o in ('-c', '--count'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   173
            count = int(a)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   174
        elif o in ('-s', '--seed'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   175
            seed = long(a)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   176
        elif o == '--build':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   177
            buildprobtable(sys.stdout,
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   178
                           'find .hg/store/data -type f && '
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   179
                           'cat .hg/store/fncache 2>/dev/null')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   180
            sys.exit(0)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   181
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   182
    if seed is None:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   183
        try:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   184
            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
   185
        except AttributeError:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   186
            seed = long(time.time() * 1000)
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
    rng = random.Random(seed)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   189
    if runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   190
        sys.exit(1)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   191
17947
f945caa5e963 test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents: 17935
diff changeset
   192
if __name__ == '__main__':
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   193
    main()