tests/test-pathencode.py
author Manuel Jacob <me@manueljacob.de>
Sun, 22 May 2022 03:50:34 +0200
changeset 49269 395f28064826
parent 48935 2cce2fa5bcf7
child 49285 56f98406831b
permissions -rw-r--r--
worker: avoid potential partial write of pickled data Previously, the code wrote the pickled data using os.write(). However, os.write() can write less bytes than passed to it. To trigger the problem, the pickled data had to be larger than 2147479552 bytes on my system. Instead, open a file object and pass it to pickle.dump(). This also has the advantage that it doesn’t buffer the whole pickled data in memory. Note that the opened file must be buffered because pickle doesn’t support unbuffered streams because unbuffered streams’ write() method might write less bytes than passed to it (like os.write()) but pickle.dump() relies on that all bytes are written (see https://github.com/python/cpython/issues/93050). The side effect of using a file object and a with statement is that wfd is explicitly closed now while it seems like before it was implicitly closed by process exit.
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
28928
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
     9
import binascii
17935
9c888b945b65 test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents: 17934
diff changeset
    10
import collections
28928
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    11
import itertools
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    12
import math
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    13
import os
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    14
import random
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    15
import sys
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    16
import time
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    17
from mercurial import (
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
    18
    pycompat,
28928
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    19
    store,
59481bfdb7f3 tests: make test-pathencode use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28918
diff changeset
    20
)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    21
34224
0f200e2310ca tests: add xrange alias for test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 28928
diff changeset
    22
try:
0f200e2310ca tests: add xrange alias for test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 28928
diff changeset
    23
    xrange
0f200e2310ca tests: add xrange alias for test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 28928
diff changeset
    24
except NameError:
0f200e2310ca tests: add xrange alias for test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 28928
diff changeset
    25
    xrange = range
0f200e2310ca tests: add xrange alias for test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 28928
diff changeset
    26
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
    27
validchars = set(map(pycompat.bytechr, range(0, 256)))
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    28
alphanum = range(ord('A'), ord('Z'))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    29
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
    30
for c in (b'\0', b'/'):
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    31
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    32
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    33
winreserved = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    34
    b'aux con prn nul'.split()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    35
    + [b'com%d' % i for i in xrange(1, 10)]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    36
    + [b'lpt%d' % i for i in xrange(1, 10)]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    37
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    38
17934
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 casecombinations(names):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    41
    '''Build all case-diddled combinations of names.'''
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
    combos = set()
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    44
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    45
    for r in names:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    46
        for i in xrange(len(r) + 1):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    47
            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
    48
                d = r
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    49
                for j in c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    50
                    d = b''.join((d[:j], d[j : j + 1].upper(), d[j + 1 :]))
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    51
                combos.add(d)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    52
    return sorted(combos)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    53
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    54
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    55
def buildprobtable(fp, cmd='hg manifest tip'):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43104
diff changeset
    56
    """Construct and print a table of probabilities for path name
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43104
diff changeset
    57
    components.  The numbers are percentages."""
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    58
17935
9c888b945b65 test-pathencode: make a 2.4-safe import of collections
Bryan O'Sullivan <bryano@fb.com>
parents: 17934
diff changeset
    59
    counts = collections.defaultdict(lambda: 0)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    60
    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
    61
        if line[-2:] in ('.i', '.d'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    62
            line = line[:-2]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    63
        if line.startswith('data/'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    64
            line = line[5:]
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    65
        for c in line:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    66
            counts[c] += 1
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    67
    for c in '\r/\n':
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    68
        counts.pop(c, None)
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    69
    t = sum(counts.values()) / 100.0
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    70
    fp.write('probtable = (')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    71
    for i, (k, v) in enumerate(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    72
        sorted(counts.items(), key=lambda x: x[1], reverse=True)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    73
    ):
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    74
        if (i % 5) == 0:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    75
            fp.write('\n    ')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    76
        vt = v / t
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    77
        if vt < 0.0005:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    78
            break
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    79
        fp.write('(%r, %.03f), ' % (k, vt))
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    80
    fp.write('\n    )\n')
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    81
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    82
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    83
# 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
    84
# 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
    85
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
    86
probtable = (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    87
    (b't', 9.828),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    88
    (b'e', 9.042),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    89
    (b's', 8.011),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    90
    (b'a', 6.801),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    91
    (b'i', 6.618),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    92
    (b'g', 5.053),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    93
    (b'r', 5.030),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    94
    (b'o', 4.887),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    95
    (b'p', 4.363),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    96
    (b'n', 4.258),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    97
    (b'l', 3.830),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    98
    (b'h', 3.693),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
    99
    (b'_', 3.659),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   100
    (b'.', 3.377),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   101
    (b'm', 3.194),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   102
    (b'u', 2.364),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   103
    (b'd', 2.296),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   104
    (b'c', 2.163),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   105
    (b'b', 1.739),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   106
    (b'f', 1.625),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   107
    (b'6', 0.666),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   108
    (b'j', 0.610),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   109
    (b'y', 0.554),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   110
    (b'x', 0.487),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   111
    (b'w', 0.477),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   112
    (b'k', 0.476),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   113
    (b'v', 0.473),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   114
    (b'3', 0.336),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   115
    (b'1', 0.335),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   116
    (b'2', 0.326),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   117
    (b'4', 0.310),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   118
    (b'5', 0.305),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   119
    (b'9', 0.302),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   120
    (b'8', 0.300),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   121
    (b'7', 0.299),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   122
    (b'q', 0.298),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   123
    (b'0', 0.250),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   124
    (b'z', 0.223),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   125
    (b'-', 0.118),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   126
    (b'C', 0.095),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   127
    (b'T', 0.087),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   128
    (b'F', 0.085),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   129
    (b'B', 0.077),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   130
    (b'S', 0.076),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   131
    (b'P', 0.076),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   132
    (b'L', 0.059),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   133
    (b'A', 0.058),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   134
    (b'N', 0.051),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   135
    (b'D', 0.049),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   136
    (b'M', 0.046),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   137
    (b'E', 0.039),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   138
    (b'I', 0.035),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   139
    (b'R', 0.035),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   140
    (b'G', 0.028),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   141
    (b'U', 0.026),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   142
    (b'W', 0.025),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   143
    (b'O', 0.017),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   144
    (b'V', 0.015),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   145
    (b'H', 0.013),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   146
    (b'Q', 0.011),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   147
    (b'J', 0.007),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   148
    (b'K', 0.005),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   149
    (b'+', 0.004),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   150
    (b'X', 0.003),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   151
    (b'Y', 0.001),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   152
)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   153
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   154
for c, _ in probtable:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   155
    validchars.remove(c)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   156
validchars = list(validchars)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   157
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   158
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   159
def pickfrom(rng, table):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   160
    c = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   161
    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
   162
    for i, p in table:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   163
        c += p
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   164
        if c >= r:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   165
            return i
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   166
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   167
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   168
reservedcombos = casecombinations(winreserved)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   169
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   170
# 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
   171
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   172
firsttable = (
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   173
    (lambda rng: pickfrom(rng, probtable), 90),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   174
    (lambda rng: rng.choice(validchars), 5),
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   175
    (lambda rng: rng.choice(reservedcombos), 5),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   176
)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   177
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   178
# Components of a name following the first.
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   179
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   180
resttable = firsttable[:-1]
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
# Special suffixes.
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   183
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
   184
internalsuffixcombos = casecombinations(b'.hg .i .d'.split())
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   185
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   186
# 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
   187
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   188
lasttable = resttable + (
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
   189
    (lambda rng: b'', 95),
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   190
    (lambda rng: rng.choice(internalsuffixcombos), 5),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   191
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   192
17934
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
def makepart(rng, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   195
    '''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
   196
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   197
    p = pickfrom(rng, firsttable)(rng)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   198
    l = len(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   199
    ps = [p]
19319
ec17ddecdf64 test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents: 19318
diff changeset
   200
    maxl = rng.randint(1, k)
ec17ddecdf64 test-pathencode: randomize length of each path component
Siddharth Agarwal <sid0@fb.com>
parents: 19318
diff changeset
   201
    while l < maxl:
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   202
        p = pickfrom(rng, resttable)(rng)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   203
        l += len(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   204
        ps.append(p)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   205
    ps.append(pickfrom(rng, lasttable)(rng))
37880
1b230e19d044 tests: port test-pathencode.py to Python 3
Augie Fackler <augie@google.com>
parents: 36327
diff changeset
   206
    return b''.join(ps)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   207
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   208
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   209
def makepath(rng, j, k):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   210
    '''Construct a complete pathname.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   211
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   212
    return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   213
        b'data/'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   214
        + b'/'.join(makepart(rng, k) for _ in xrange(j))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   215
        + rng.choice([b'.d', b'.i'])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   216
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   217
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   218
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   219
def genpath(rng, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   220
    '''Generate random pathnames with gradually increasing lengths.'''
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   221
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   222
    mink, maxk = 1, 4096
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   223
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   224
    def steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   225
        for i in xrange(count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   226
            yield mink + int(round(math.sqrt((maxk - mink) * float(i) / count)))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   227
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   228
    for k in steps():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   229
        x = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   230
        y = rng.randint(1, k)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   231
        yield makepath(rng, x, y)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   232
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   233
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   234
def runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   235
    nerrs = 0
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   236
    for p in genpath(rng, count):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   237
        h = store._pathencode(p)  # uses C implementation, if available
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   238
        r = store._hybridencode(p, True)  # reference implementation in Python
18094
8ceabb34f1cb test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents: 17947
diff changeset
   239
        if h != r:
8ceabb34f1cb test-pathencode: compare current pathencoding implementations
Adrian Buehlmann <adrian@cadifra.com>
parents: 17947
diff changeset
   240
            if nerrs == 0:
28918
72f683260f31 tests: make test-pathencode use print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 26849
diff changeset
   241
                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
   242
            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
   243
            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
   244
            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
   245
            nerrs += 1
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   246
    return nerrs
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   247
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   248
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   249
def main():
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   250
    import getopt
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   251
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   252
    # 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
   253
    count = 100
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   254
    seed = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   255
    opts, args = getopt.getopt(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   256
        sys.argv[1:], 'c:s:', ['build', 'count=', 'seed=']
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   257
    )
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   258
    for o, a in opts:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   259
        if o in ('-c', '--count'):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   260
            count = int(a)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   261
        elif o in ('-s', '--seed'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   262
            seed = int(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
   263
        elif o == '--build':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   264
            buildprobtable(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   265
                sys.stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   266
                'find .hg/store/data -type f && '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   267
                'cat .hg/store/fncache 2>/dev/null',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   268
            )
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   269
            sys.exit(0)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   270
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   271
    if seed is None:
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   272
        try:
34225
d43340bec0f5 tests: use int() instead of long() in test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 34224
diff changeset
   273
            seed = int(binascii.hexlify(os.urandom(16)), 16)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   274
        except AttributeError:
34225
d43340bec0f5 tests: use int() instead of long() in test-pathencode.py
Augie Fackler <raf@durin42.com>
parents: 34224
diff changeset
   275
            seed = int(time.time() * 1000)
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   276
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   277
    rng = random.Random(seed)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   278
    if runtests(rng, seed, count):
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   279
        sys.exit(1)
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   280
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37880
diff changeset
   281
17947
f945caa5e963 test-pathencode: more aggressively check for python < 2.6
Bryan O'Sullivan <bryano@fb.com>
parents: 17935
diff changeset
   282
if __name__ == '__main__':
17934
736f1c09f321 tests: add a randomized test for pathencode
Bryan O'Sullivan <bryano@fb.com>
parents:
diff changeset
   283
    main()