tests/test-pathencode.py
author Pulkit Goyal <7895pulkit@gmail.com>
Thu, 14 Apr 2016 01:06:45 +0530
changeset 28918 72f683260f31
parent 26849 a6eb4e481134
child 28928 59481bfdb7f3
permissions -rw-r--r--
tests: make test-pathencode use print_function
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
26098
ce26928cbe41 spelling: behaviour -> behavior
timeless@mozdev.org
parents: 20938
diff changeset
     5
# that have proven likely to expose bugs and divergent behavior in
17934
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
28918
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
     8
from __future__ import print_function
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
     9
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    10
from mercurial import store
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    11
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
    12
import collections
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    13
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    14
validchars = set(map(chr, range(0, 256)))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    15
alphanum = range(ord('A'), ord('Z'))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    16
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    17
for c in '\0/':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    18
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    19
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    20
winreserved = ('aux con prn nul'.split() +
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    21
               ['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
    22
               ['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
    23
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    24
def casecombinations(names):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    25
    '''Build all case-diddled combinations of names.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    26
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    27
    combos = set()
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
    for r in names:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    30
        for i in xrange(len(r) + 1):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    31
            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
    32
                d = r
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    33
                for j in c:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    34
                    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
    35
                combos.add(d)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    36
    return sorted(combos)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    37
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    38
def buildprobtable(fp, cmd='hg manifest tip'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    39
    '''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
    40
    components.  The numbers are percentages.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    41
17935
9c888b945b65 test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents: 17934
diff changeset
    42
    counts = collections.defaultdict(lambda: 0)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    43
    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
    44
        if line[-2:] in ('.i', '.d'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    45
            line = line[:-2]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    46
        if line.startswith('data/'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    47
            line = line[5:]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    48
        for c in line:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    49
            counts[c] += 1
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    50
    for c in '\r/\n':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    51
        counts.pop(c, None)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    52
    t = sum(counts.itervalues()) / 100.0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    53
    fp.write('probtable = (')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    54
    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
    55
                                      reverse=True)):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    56
        if (i % 5) == 0:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    57
            fp.write('\n    ')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    58
        vt = v / t
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    59
        if vt < 0.0005:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    60
            break
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    61
        fp.write('(%r, %.03f), ' % (k, vt))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    62
    fp.write('\n    )\n')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    63
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    64
# 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
    65
# 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
    66
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    67
probtable = (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    68
    ('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
    69
    ('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
    70
    ('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
    71
    ('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
    72
    ('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
    73
    ('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
    74
    ('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
    75
    ('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
    76
    ('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
    77
    ('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
    78
    ('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
    79
    ('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
    80
    ('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
    81
    )
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    82
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    83
for c, _ in probtable:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    84
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    85
validchars = list(validchars)
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
def pickfrom(rng, table):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    88
    c = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    89
    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
    90
    for i, p in table:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    91
        c += p
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    92
        if c >= r:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    93
            return i
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    94
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    95
reservedcombos = casecombinations(winreserved)
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
# 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
    98
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    99
firsttable = (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   100
    (lambda rng: pickfrom(rng, probtable), 90),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   101
    (lambda rng: rng.choice(validchars), 5),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   102
    (lambda rng: rng.choice(reservedcombos), 5),
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
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   105
# Components of a name following the first.
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
resttable = firsttable[:-1]
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
# Special suffixes.
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
internalsuffixcombos = casecombinations('.hg .i .d'.split())
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
# 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
   114
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   115
lasttable = resttable + (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   116
    (lambda rng: '', 95),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   117
    (lambda rng: rng.choice(internalsuffixcombos), 5),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   118
    )
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
def makepart(rng, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   121
    '''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
   122
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   123
    p = pickfrom(rng, firsttable)(rng)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   124
    l = len(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   125
    ps = [p]
19319
ec17ddecdf64 test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents: 19318
diff changeset
   126
    maxl = rng.randint(1, k)
ec17ddecdf64 test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents: 19318
diff changeset
   127
    while l < maxl:
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   128
        p = pickfrom(rng, resttable)(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.append(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   131
    ps.append(pickfrom(rng, lasttable)(rng))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   132
    return ''.join(ps)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   133
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   134
def makepath(rng, j, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   135
    '''Construct a complete pathname.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   136
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   137
    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
   138
            rng.choice(['.d', '.i']))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   139
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   140
def genpath(rng, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   141
    '''Generate random pathnames with gradually increasing lengths.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   142
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   143
    mink, maxk = 1, 4096
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   144
    def steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   145
        for i in xrange(count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   146
            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
   147
    for k in steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   148
        x = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   149
        y = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   150
        yield makepath(rng, x, y)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   151
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   152
def runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   153
    nerrs = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   154
    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
   155
        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
   156
        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
   157
        if h != r:
8ceabb34f1cb test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents: 17947
diff changeset
   158
            if nerrs == 0:
28918
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
   159
                print('seed:', hex(seed)[:-1], file=sys.stderr)
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
   160
            print("\np: '%s'" % p.encode("string_escape"), file=sys.stderr)
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
   161
            print("h: '%s'" % h.encode("string_escape"), file=sys.stderr)
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
   162
            print("r: '%s'" % r.encode("string_escape"), file=sys.stderr)
18094
8ceabb34f1cb test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents: 17947
diff changeset
   163
            nerrs += 1
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   164
    return nerrs
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
def main():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   167
    import getopt
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
    # 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
   170
    count = 100
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   171
    seed = None
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   172
    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
   173
                               ['build', 'count=', 'seed='])
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   174
    for o, a in opts:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   175
        if o in ('-c', '--count'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   176
            count = int(a)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   177
        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
   178
            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
   179
        elif o == '--build':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   180
            buildprobtable(sys.stdout,
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   181
                           'find .hg/store/data -type f && '
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   182
                           'cat .hg/store/fncache 2>/dev/null')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   183
            sys.exit(0)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   184
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   185
    if seed is None:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   186
        try:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   187
            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
   188
        except AttributeError:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   189
            seed = long(time.time() * 1000)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   190
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   191
    rng = random.Random(seed)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   192
    if runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   193
        sys.exit(1)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   194
17947
f945caa5e963 test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents: 17935
diff changeset
   195
if __name__ == '__main__':
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   196
    main()