##// END OF EJS Templates
tests: port test-pathencode.py to Python 3...
Augie Fackler -
r37897:1b230e19 default
parent child Browse files
Show More
@@ -1,463 +1,464
1 1 test-abort-checkin.t
2 2 test-add.t
3 3 test-addremove-similar.t
4 4 test-addremove.t
5 5 test-amend-subrepo.t
6 6 test-amend.t
7 7 test-ancestor.py
8 8 test-annotate.py
9 9 test-annotate.t
10 10 test-archive-symlinks.t
11 11 test-atomictempfile.py
12 12 test-audit-path.t
13 13 test-audit-subrepo.t
14 14 test-automv.t
15 15 test-backout.t
16 16 test-backwards-remove.t
17 17 test-basic.t
18 18 test-bheads.t
19 19 test-bisect.t
20 20 test-bisect2.t
21 21 test-bisect3.t
22 22 test-blackbox.t
23 23 test-bookmarks-current.t
24 24 test-bookmarks-merge.t
25 25 test-bookmarks-rebase.t
26 26 test-bookmarks-strip.t
27 27 test-bookmarks.t
28 28 test-branch-change.t
29 29 test-branch-option.t
30 30 test-branch-tag-confict.t
31 31 test-branches.t
32 32 test-bundle-phases.t
33 33 test-bundle-type.t
34 34 test-bundle-vs-outgoing.t
35 35 test-bundle2-multiple-changegroups.t
36 36 test-cappedreader.py
37 37 test-casecollision.t
38 38 test-cat.t
39 39 test-censor.t
40 40 test-changelog-exec.t
41 41 test-check-commit.t
42 42 test-check-execute.t
43 43 test-check-interfaces.py
44 44 test-check-module-imports.t
45 45 test-check-pyflakes.t
46 46 test-check-pylint.t
47 47 test-check-shbang.t
48 48 test-children.t
49 49 test-clone-cgi.t
50 50 test-clone-pull-corruption.t
51 51 test-clone-r.t
52 52 test-clone-update-order.t
53 53 test-command-template.t
54 54 test-commit-amend.t
55 55 test-commit-interactive.t
56 56 test-commit-multiple.t
57 57 test-commit-unresolved.t
58 58 test-commit.t
59 59 test-committer.t
60 60 test-completion.t
61 61 test-config-env.py
62 62 test-config.t
63 63 test-conflict.t
64 64 test-confused-revert.t
65 65 test-contrib-check-code.t
66 66 test-contrib-check-commit.t
67 67 test-convert-authormap.t
68 68 test-convert-clonebranches.t
69 69 test-convert-datesort.t
70 70 test-convert-filemap.t
71 71 test-convert-hg-sink.t
72 72 test-convert-hg-source.t
73 73 test-convert-hg-startrev.t
74 74 test-convert-splicemap.t
75 75 test-convert-tagsbranch-topology.t
76 76 test-copy-move-merge.t
77 77 test-copy.t
78 78 test-copytrace-heuristics.t
79 79 test-debugbuilddag.t
80 80 test-debugbundle.t
81 81 test-debugextensions.t
82 82 test-debugindexdot.t
83 83 test-debugrename.t
84 84 test-default-push.t
85 85 test-diff-binary-file.t
86 86 test-diff-change.t
87 87 test-diff-copy-depth.t
88 88 test-diff-hashes.t
89 89 test-diff-ignore-whitespace.t
90 90 test-diff-indent-heuristic.t
91 91 test-diff-issue2761.t
92 92 test-diff-newlines.t
93 93 test-diff-reverse.t
94 94 test-diff-subdir.t
95 95 test-diff-unified.t
96 96 test-diff-upgrade.t
97 97 test-diffdir.t
98 98 test-diffstat.t
99 99 test-directaccess.t
100 100 test-dirstate-backup.t
101 101 test-dirstate-nonnormalset.t
102 102 test-dirstate.t
103 103 test-doctest.py
104 104 test-double-merge.t
105 105 test-drawdag.t
106 106 test-duplicateoptions.py
107 107 test-editor-filename.t
108 108 test-empty-dir.t
109 109 test-empty-file.t
110 110 test-empty-group.t
111 111 test-empty.t
112 112 test-encode.t
113 113 test-encoding-func.py
114 114 test-encoding.t
115 115 test-eol-add.t
116 116 test-eol-clone.t
117 117 test-eol-hook.t
118 118 test-eol-tag.t
119 119 test-eol-update.t
120 120 test-excessive-merge.t
121 121 test-exchange-obsmarkers-case-A1.t
122 122 test-exchange-obsmarkers-case-A2.t
123 123 test-exchange-obsmarkers-case-A3.t
124 124 test-exchange-obsmarkers-case-A4.t
125 125 test-exchange-obsmarkers-case-A5.t
126 126 test-exchange-obsmarkers-case-A6.t
127 127 test-exchange-obsmarkers-case-A7.t
128 128 test-exchange-obsmarkers-case-B1.t
129 129 test-exchange-obsmarkers-case-B2.t
130 130 test-exchange-obsmarkers-case-B3.t
131 131 test-exchange-obsmarkers-case-B4.t
132 132 test-exchange-obsmarkers-case-B5.t
133 133 test-exchange-obsmarkers-case-B6.t
134 134 test-exchange-obsmarkers-case-B7.t
135 135 test-exchange-obsmarkers-case-C1.t
136 136 test-exchange-obsmarkers-case-C2.t
137 137 test-exchange-obsmarkers-case-C3.t
138 138 test-exchange-obsmarkers-case-C4.t
139 139 test-exchange-obsmarkers-case-D1.t
140 140 test-exchange-obsmarkers-case-D2.t
141 141 test-exchange-obsmarkers-case-D3.t
142 142 test-exchange-obsmarkers-case-D4.t
143 143 test-execute-bit.t
144 144 test-export.t
145 145 test-extdata.t
146 146 test-extdiff.t
147 147 test-extra-filelog-entry.t
148 148 test-filebranch.t
149 149 test-fileset-generated.t
150 150 test-fix-topology.t
151 151 test-flags.t
152 152 test-generaldelta.t
153 153 test-getbundle.t
154 154 test-git-export.t
155 155 test-glog-topological.t
156 156 test-gpg.t
157 157 test-graft.t
158 158 test-hg-parseurl.py
159 159 test-hghave.t
160 160 test-hgignore.t
161 161 test-hgk.t
162 162 test-hgweb-bundle.t
163 163 test-hgweb-descend-empties.t
164 164 test-hgweb-empty.t
165 165 test-hgweb-removed.t
166 166 test-hgwebdir-paths.py
167 167 test-hgwebdirsym.t
168 168 test-histedit-arguments.t
169 169 test-histedit-base.t
170 170 test-histedit-bookmark-motion.t
171 171 test-histedit-commute.t
172 172 test-histedit-drop.t
173 173 test-histedit-edit.t
174 174 test-histedit-fold-non-commute.t
175 175 test-histedit-fold.t
176 176 test-histedit-no-change.t
177 177 test-histedit-non-commute-abort.t
178 178 test-histedit-non-commute.t
179 179 test-histedit-obsolete.t
180 180 test-histedit-outgoing.t
181 181 test-histedit-templates.t
182 182 test-http-branchmap.t
183 183 test-http-bundle1.t
184 184 test-http-clone-r.t
185 185 test-http.t
186 186 test-hybridencode.py
187 187 test-identify.t
188 188 test-import-unknown.t
189 189 test-import.t
190 190 test-imports-checker.t
191 191 test-incoming-outgoing.t
192 192 test-inherit-mode.t
193 193 test-issue1089.t
194 194 test-issue1102.t
195 195 test-issue1175.t
196 196 test-issue1306.t
197 197 test-issue1438.t
198 198 test-issue1502.t
199 199 test-issue1802.t
200 200 test-issue1877.t
201 201 test-issue1993.t
202 202 test-issue2137.t
203 203 test-issue3084.t
204 204 test-issue4074.t
205 205 test-issue522.t
206 206 test-issue586.t
207 207 test-issue612.t
208 208 test-issue619.t
209 209 test-issue660.t
210 210 test-issue672.t
211 211 test-issue842.t
212 212 test-journal-exists.t
213 213 test-journal-share.t
214 214 test-journal.t
215 215 test-largefiles-cache.t
216 216 test-largefiles-misc.t
217 217 test-largefiles-small-disk.t
218 218 test-largefiles-update.t
219 219 test-largefiles.t
220 220 test-lfs-largefiles.t
221 221 test-linerange.py
222 222 test-locate.t
223 223 test-lock-badness.t
224 224 test-log-linerange.t
225 225 test-log.t
226 226 test-logexchange.t
227 227 test-lrucachedict.py
228 228 test-mactext.t
229 229 test-mailmap.t
230 230 test-manifest-merging.t
231 231 test-manifest.py
232 232 test-manifest.t
233 233 test-match.py
234 234 test-mdiff.py
235 235 test-merge-changedelete.t
236 236 test-merge-closedheads.t
237 237 test-merge-commit.t
238 238 test-merge-criss-cross.t
239 239 test-merge-default.t
240 240 test-merge-force.t
241 241 test-merge-halt.t
242 242 test-merge-internal-tools-pattern.t
243 243 test-merge-local.t
244 244 test-merge-remove.t
245 245 test-merge-revert.t
246 246 test-merge-revert2.t
247 247 test-merge-subrepos.t
248 248 test-merge-symlinks.t
249 249 test-merge-tools.t
250 250 test-merge-types.t
251 251 test-merge1.t
252 252 test-merge10.t
253 253 test-merge2.t
254 254 test-merge4.t
255 255 test-merge5.t
256 256 test-merge6.t
257 257 test-merge7.t
258 258 test-merge8.t
259 259 test-merge9.t
260 260 test-minifileset.py
261 261 test-mq-git.t
262 262 test-mq-header-date.t
263 263 test-mq-header-from.t
264 264 test-mq-merge.t
265 265 test-mq-pull-from-bundle.t
266 266 test-mq-qclone-http.t
267 267 test-mq-qdelete.t
268 268 test-mq-qdiff.t
269 269 test-mq-qfold.t
270 270 test-mq-qgoto.t
271 271 test-mq-qimport-fail-cleanup.t
272 272 test-mq-qnew.t
273 273 test-mq-qpush-exact.t
274 274 test-mq-qqueue.t
275 275 test-mq-qrefresh-interactive.t
276 276 test-mq-qrefresh-replace-log-message.t
277 277 test-mq-qrefresh.t
278 278 test-mq-qrename.t
279 279 test-mq-qsave.t
280 280 test-mq-safety.t
281 281 test-mq-subrepo.t
282 282 test-mq-symlinks.t
283 283 test-mv-cp-st-diff.t
284 284 test-narrow-archive.t
285 285 test-narrow-clone-no-ellipsis.t
286 286 test-narrow-clone-non-narrow-server.t
287 287 test-narrow-clone-nonlinear.t
288 288 test-narrow-clone.t
289 289 test-narrow-commit.t
290 290 test-narrow-copies.t
291 291 test-narrow-debugcommands.t
292 292 test-narrow-debugrebuilddirstate.t
293 293 test-narrow-exchange-merges.t
294 294 test-narrow-exchange.t
295 295 test-narrow-expanddirstate.t
296 296 test-narrow-merge.t
297 297 test-narrow-patch.t
298 298 test-narrow-patterns.t
299 299 test-narrow-pull.t
300 300 test-narrow-rebase.t
301 301 test-narrow-shallow-merges.t
302 302 test-narrow-shallow.t
303 303 test-narrow-strip.t
304 304 test-narrow-update.t
305 305 test-nested-repo.t
306 306 test-newbranch.t
307 307 test-obshistory.t
308 308 test-obsmarker-template.t
309 309 test-obsmarkers-effectflag.t
310 310 test-obsolete-bundle-strip.t
311 311 test-obsolete-changeset-exchange.t
312 312 test-obsolete-checkheads.t
313 313 test-obsolete-distributed.t
314 314 test-obsolete-tag-cache.t
315 315 test-parents.t
316 316 test-pathconflicts-merge.t
317 317 test-pathconflicts-update.t
318 test-pathencode.py
318 319 test-pending.t
319 320 test-permissions.t
320 321 test-phases.t
321 322 test-pull-branch.t
322 323 test-pull-http.t
323 324 test-pull-permission.t
324 325 test-pull-pull-corruption.t
325 326 test-pull-r.t
326 327 test-pull-update.t
327 328 test-purge.t
328 329 test-push-checkheads-partial-C1.t
329 330 test-push-checkheads-partial-C2.t
330 331 test-push-checkheads-partial-C3.t
331 332 test-push-checkheads-partial-C4.t
332 333 test-push-checkheads-pruned-B1.t
333 334 test-push-checkheads-pruned-B2.t
334 335 test-push-checkheads-pruned-B3.t
335 336 test-push-checkheads-pruned-B4.t
336 337 test-push-checkheads-pruned-B5.t
337 338 test-push-checkheads-pruned-B6.t
338 339 test-push-checkheads-pruned-B7.t
339 340 test-push-checkheads-pruned-B8.t
340 341 test-push-checkheads-superceed-A1.t
341 342 test-push-checkheads-superceed-A2.t
342 343 test-push-checkheads-superceed-A3.t
343 344 test-push-checkheads-superceed-A4.t
344 345 test-push-checkheads-superceed-A5.t
345 346 test-push-checkheads-superceed-A6.t
346 347 test-push-checkheads-superceed-A7.t
347 348 test-push-checkheads-superceed-A8.t
348 349 test-push-checkheads-unpushed-D1.t
349 350 test-push-checkheads-unpushed-D2.t
350 351 test-push-checkheads-unpushed-D3.t
351 352 test-push-checkheads-unpushed-D4.t
352 353 test-push-checkheads-unpushed-D5.t
353 354 test-push-checkheads-unpushed-D6.t
354 355 test-push-checkheads-unpushed-D7.t
355 356 test-push-http.t
356 357 test-push-warn.t
357 358 test-pushvars.t
358 359 test-rebase-abort.t
359 360 test-rebase-base-flag.t
360 361 test-rebase-bookmarks.t
361 362 test-rebase-brute-force.t
362 363 test-rebase-cache.t
363 364 test-rebase-check-restore.t
364 365 test-rebase-collapse.t
365 366 test-rebase-conflicts.t
366 367 test-rebase-dest.t
367 368 test-rebase-detach.t
368 369 test-rebase-emptycommit.t
369 370 test-rebase-inmemory.t
370 371 test-rebase-interruptions.t
371 372 test-rebase-issue-noparam-single-rev.t
372 373 test-rebase-legacy.t
373 374 test-rebase-mq-skip.t
374 375 test-rebase-mq.t
375 376 test-rebase-named-branches.t
376 377 test-rebase-newancestor.t
377 378 test-rebase-obsolete.t
378 379 test-rebase-parameters.t
379 380 test-rebase-partial.t
380 381 test-rebase-pull.t
381 382 test-rebase-rename.t
382 383 test-rebase-scenario-global.t
383 384 test-rebase-templates.t
384 385 test-rebase-transaction.t
385 386 test-record.t
386 387 test-relink.t
387 388 test-remove.t
388 389 test-rename-after-merge.t
389 390 test-rename-dir-merge.t
390 391 test-rename-merge1.t
391 392 test-rename.t
392 393 test-repair-strip.t
393 394 test-repo-compengines.t
394 395 test-resolve.t
395 396 test-revert-flags.t
396 397 test-revert-unknown.t
397 398 test-revlog-ancestry.py
398 399 test-revlog-group-emptyiter.t
399 400 test-revlog-mmapindex.t
400 401 test-revlog-packentry.t
401 402 test-revset-dirstate-parents.t
402 403 test-revset-legacy-lookup.t
403 404 test-revset-outgoing.t
404 405 test-rollback.t
405 406 test-run-tests.py
406 407 test-run-tests.t
407 408 test-schemes.t
408 409 test-serve.t
409 410 test-setdiscovery.t
410 411 test-share.t
411 412 test-shelve.t
412 413 test-show-stack.t
413 414 test-show-work.t
414 415 test-show.t
415 416 test-simple-update.t
416 417 test-single-head.t
417 418 test-sparse-clear.t
418 419 test-sparse-import.t
419 420 test-sparse-merges.t
420 421 test-sparse-profiles.t
421 422 test-sparse-requirement.t
422 423 test-sparse-verbose-json.t
423 424 test-ssh-clone-r.t
424 425 test-ssh-proto.t
425 426 test-sshserver.py
426 427 test-stack.t
427 428 test-status-rev.t
428 429 test-status-terse.t
429 430 test-strip-cross.t
430 431 test-strip.t
431 432 test-subrepo-deep-nested-change.t
432 433 test-subrepo-missing.t
433 434 test-subrepo-recursion.t
434 435 test-subrepo-relative-path.t
435 436 test-subrepo.t
436 437 test-symlinks.t
437 438 test-tag.t
438 439 test-tags.t
439 440 test-template-engine.t
440 441 test-treemanifest.t
441 442 test-unamend.t
442 443 test-uncommit.t
443 444 test-unified-test.t
444 445 test-unrelated-pull.t
445 446 test-up-local-change.t
446 447 test-update-branches.t
447 448 test-update-dest.t
448 449 test-update-issue1456.t
449 450 test-update-names.t
450 451 test-update-reverse.t
451 452 test-upgrade-repo.t
452 453 test-url-download.t
453 454 test-url-rev.t
454 455 test-url.py
455 456 test-username-newline.t
456 457 test-verify.t
457 458 test-walkrepo.py
458 459 test-websub.t
459 460 test-win32text.t
460 461 test-wireproto-clientreactor.py
461 462 test-wireproto-framing.py
462 463 test-wireproto-serverreactor.py
463 464 test-xdg.t
@@ -1,209 +1,210
1 1 # This is a randomized test that generates different pathnames every
2 2 # time it is invoked, and tests the encoding of those pathnames.
3 3 #
4 4 # It uses a simple probabilistic model to generate valid pathnames
5 5 # that have proven likely to expose bugs and divergent behavior in
6 6 # different encoding implementations.
7 7
8 8 from __future__ import absolute_import, print_function
9 9
10 10 import binascii
11 11 import collections
12 12 import itertools
13 13 import math
14 14 import os
15 15 import random
16 16 import sys
17 17 import time
18 18 from mercurial import (
19 pycompat,
19 20 store,
20 21 )
21 22
22 23 try:
23 24 xrange
24 25 except NameError:
25 26 xrange = range
26 27
27 validchars = set(map(chr, range(0, 256)))
28 validchars = set(map(pycompat.bytechr, range(0, 256)))
28 29 alphanum = range(ord('A'), ord('Z'))
29 30
30 for c in '\0/':
31 for c in (b'\0', b'/'):
31 32 validchars.remove(c)
32 33
33 winreserved = ('aux con prn nul'.split() +
34 ['com%d' % i for i in xrange(1, 10)] +
35 ['lpt%d' % i for i in xrange(1, 10)])
34 winreserved = (b'aux con prn nul'.split() +
35 [b'com%d' % i for i in xrange(1, 10)] +
36 [b'lpt%d' % i for i in xrange(1, 10)])
36 37
37 38 def casecombinations(names):
38 39 '''Build all case-diddled combinations of names.'''
39 40
40 41 combos = set()
41 42
42 43 for r in names:
43 44 for i in xrange(len(r) + 1):
44 45 for c in itertools.combinations(xrange(len(r)), i):
45 46 d = r
46 47 for j in c:
47 d = ''.join((d[:j], d[j].upper(), d[j + 1:]))
48 d = b''.join((d[:j], d[j:j + 1].upper(), d[j + 1:]))
48 49 combos.add(d)
49 50 return sorted(combos)
50 51
51 52 def buildprobtable(fp, cmd='hg manifest tip'):
52 53 '''Construct and print a table of probabilities for path name
53 54 components. The numbers are percentages.'''
54 55
55 56 counts = collections.defaultdict(lambda: 0)
56 57 for line in os.popen(cmd).read().splitlines():
57 58 if line[-2:] in ('.i', '.d'):
58 59 line = line[:-2]
59 60 if line.startswith('data/'):
60 61 line = line[5:]
61 62 for c in line:
62 63 counts[c] += 1
63 64 for c in '\r/\n':
64 65 counts.pop(c, None)
65 66 t = sum(counts.itervalues()) / 100.0
66 67 fp.write('probtable = (')
67 68 for i, (k, v) in enumerate(sorted(counts.items(), key=lambda x: x[1],
68 69 reverse=True)):
69 70 if (i % 5) == 0:
70 71 fp.write('\n ')
71 72 vt = v / t
72 73 if vt < 0.0005:
73 74 break
74 75 fp.write('(%r, %.03f), ' % (k, vt))
75 76 fp.write('\n )\n')
76 77
77 78 # A table of character frequencies (as percentages), gleaned by
78 79 # looking at filelog names from a real-world, very large repo.
79 80
80 81 probtable = (
81 ('t', 9.828), ('e', 9.042), ('s', 8.011), ('a', 6.801), ('i', 6.618),
82 ('g', 5.053), ('r', 5.030), ('o', 4.887), ('p', 4.363), ('n', 4.258),
83 ('l', 3.830), ('h', 3.693), ('_', 3.659), ('.', 3.377), ('m', 3.194),
84 ('u', 2.364), ('d', 2.296), ('c', 2.163), ('b', 1.739), ('f', 1.625),
85 ('6', 0.666), ('j', 0.610), ('y', 0.554), ('x', 0.487), ('w', 0.477),
86 ('k', 0.476), ('v', 0.473), ('3', 0.336), ('1', 0.335), ('2', 0.326),
87 ('4', 0.310), ('5', 0.305), ('9', 0.302), ('8', 0.300), ('7', 0.299),
88 ('q', 0.298), ('0', 0.250), ('z', 0.223), ('-', 0.118), ('C', 0.095),
89 ('T', 0.087), ('F', 0.085), ('B', 0.077), ('S', 0.076), ('P', 0.076),
90 ('L', 0.059), ('A', 0.058), ('N', 0.051), ('D', 0.049), ('M', 0.046),
91 ('E', 0.039), ('I', 0.035), ('R', 0.035), ('G', 0.028), ('U', 0.026),
92 ('W', 0.025), ('O', 0.017), ('V', 0.015), ('H', 0.013), ('Q', 0.011),
93 ('J', 0.007), ('K', 0.005), ('+', 0.004), ('X', 0.003), ('Y', 0.001),
82 (b't', 9.828), (b'e', 9.042), (b's', 8.011), (b'a', 6.801), (b'i', 6.618),
83 (b'g', 5.053), (b'r', 5.030), (b'o', 4.887), (b'p', 4.363), (b'n', 4.258),
84 (b'l', 3.830), (b'h', 3.693), (b'_', 3.659), (b'.', 3.377), (b'm', 3.194),
85 (b'u', 2.364), (b'd', 2.296), (b'c', 2.163), (b'b', 1.739), (b'f', 1.625),
86 (b'6', 0.666), (b'j', 0.610), (b'y', 0.554), (b'x', 0.487), (b'w', 0.477),
87 (b'k', 0.476), (b'v', 0.473), (b'3', 0.336), (b'1', 0.335), (b'2', 0.326),
88 (b'4', 0.310), (b'5', 0.305), (b'9', 0.302), (b'8', 0.300), (b'7', 0.299),
89 (b'q', 0.298), (b'0', 0.250), (b'z', 0.223), (b'-', 0.118), (b'C', 0.095),
90 (b'T', 0.087), (b'F', 0.085), (b'B', 0.077), (b'S', 0.076), (b'P', 0.076),
91 (b'L', 0.059), (b'A', 0.058), (b'N', 0.051), (b'D', 0.049), (b'M', 0.046),
92 (b'E', 0.039), (b'I', 0.035), (b'R', 0.035), (b'G', 0.028), (b'U', 0.026),
93 (b'W', 0.025), (b'O', 0.017), (b'V', 0.015), (b'H', 0.013), (b'Q', 0.011),
94 (b'J', 0.007), (b'K', 0.005), (b'+', 0.004), (b'X', 0.003), (b'Y', 0.001),
94 95 )
95 96
96 97 for c, _ in probtable:
97 98 validchars.remove(c)
98 99 validchars = list(validchars)
99 100
100 101 def pickfrom(rng, table):
101 102 c = 0
102 103 r = rng.random() * sum(i[1] for i in table)
103 104 for i, p in table:
104 105 c += p
105 106 if c >= r:
106 107 return i
107 108
108 109 reservedcombos = casecombinations(winreserved)
109 110
110 111 # The first component of a name following a slash.
111 112
112 113 firsttable = (
113 114 (lambda rng: pickfrom(rng, probtable), 90),
114 115 (lambda rng: rng.choice(validchars), 5),
115 116 (lambda rng: rng.choice(reservedcombos), 5),
116 117 )
117 118
118 119 # Components of a name following the first.
119 120
120 121 resttable = firsttable[:-1]
121 122
122 123 # Special suffixes.
123 124
124 internalsuffixcombos = casecombinations('.hg .i .d'.split())
125 internalsuffixcombos = casecombinations(b'.hg .i .d'.split())
125 126
126 127 # The last component of a path, before a slash or at the end of a name.
127 128
128 129 lasttable = resttable + (
129 (lambda rng: '', 95),
130 (lambda rng: b'', 95),
130 131 (lambda rng: rng.choice(internalsuffixcombos), 5),
131 132 )
132 133
133 134 def makepart(rng, k):
134 135 '''Construct a part of a pathname, without slashes.'''
135 136
136 137 p = pickfrom(rng, firsttable)(rng)
137 138 l = len(p)
138 139 ps = [p]
139 140 maxl = rng.randint(1, k)
140 141 while l < maxl:
141 142 p = pickfrom(rng, resttable)(rng)
142 143 l += len(p)
143 144 ps.append(p)
144 145 ps.append(pickfrom(rng, lasttable)(rng))
145 return ''.join(ps)
146 return b''.join(ps)
146 147
147 148 def makepath(rng, j, k):
148 149 '''Construct a complete pathname.'''
149 150
150 return ('data/' + '/'.join(makepart(rng, k) for _ in xrange(j)) +
151 rng.choice(['.d', '.i']))
151 return (b'data/' + b'/'.join(makepart(rng, k) for _ in xrange(j)) +
152 rng.choice([b'.d', b'.i']))
152 153
153 154 def genpath(rng, count):
154 155 '''Generate random pathnames with gradually increasing lengths.'''
155 156
156 157 mink, maxk = 1, 4096
157 158 def steps():
158 159 for i in xrange(count):
159 160 yield mink + int(round(math.sqrt((maxk - mink) * float(i) / count)))
160 161 for k in steps():
161 162 x = rng.randint(1, k)
162 163 y = rng.randint(1, k)
163 164 yield makepath(rng, x, y)
164 165
165 166 def runtests(rng, seed, count):
166 167 nerrs = 0
167 168 for p in genpath(rng, count):
168 169 h = store._pathencode(p) # uses C implementation, if available
169 170 r = store._hybridencode(p, True) # reference implementation in Python
170 171 if h != r:
171 172 if nerrs == 0:
172 173 print('seed:', hex(seed)[:-1], file=sys.stderr)
173 174 print("\np: '%s'" % p.encode("string_escape"), file=sys.stderr)
174 175 print("h: '%s'" % h.encode("string_escape"), file=sys.stderr)
175 176 print("r: '%s'" % r.encode("string_escape"), file=sys.stderr)
176 177 nerrs += 1
177 178 return nerrs
178 179
179 180 def main():
180 181 import getopt
181 182
182 183 # Empirically observed to take about a second to run
183 184 count = 100
184 185 seed = None
185 186 opts, args = getopt.getopt(sys.argv[1:], 'c:s:',
186 187 ['build', 'count=', 'seed='])
187 188 for o, a in opts:
188 189 if o in ('-c', '--count'):
189 190 count = int(a)
190 191 elif o in ('-s', '--seed'):
191 192 seed = int(a, base=0) # accepts base 10 or 16 strings
192 193 elif o == '--build':
193 194 buildprobtable(sys.stdout,
194 195 'find .hg/store/data -type f && '
195 196 'cat .hg/store/fncache 2>/dev/null')
196 197 sys.exit(0)
197 198
198 199 if seed is None:
199 200 try:
200 201 seed = int(binascii.hexlify(os.urandom(16)), 16)
201 202 except AttributeError:
202 203 seed = int(time.time() * 1000)
203 204
204 205 rng = random.Random(seed)
205 206 if runtests(rng, seed, count):
206 207 sys.exit(1)
207 208
208 209 if __name__ == '__main__':
209 210 main()
General Comments 0
You need to be logged in to leave comments. Login now