##// END OF EJS Templates
tests: allow for variation in zstd output as seen on s390x and powerpc
Julien Cristau -
r49353:f447b90a stable
parent child Browse files
Show More
@@ -1,1151 +1,1156
1 1 from __future__ import absolute_import, print_function
2 2
3 3 import distutils.version
4 4 import os
5 5 import re
6 6 import socket
7 7 import stat
8 8 import subprocess
9 9 import sys
10 10 import tempfile
11 11
12 12 tempprefix = 'hg-hghave-'
13 13
14 14 checks = {
15 15 "true": (lambda: True, "yak shaving"),
16 16 "false": (lambda: False, "nail clipper"),
17 17 "known-bad-output": (lambda: True, "use for currently known bad output"),
18 18 "missing-correct-output": (lambda: False, "use for missing good output"),
19 19 }
20 20
21 21 try:
22 22 import msvcrt
23 23
24 24 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
25 25 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
26 26 except ImportError:
27 27 pass
28 28
29 29 stdout = getattr(sys.stdout, 'buffer', sys.stdout)
30 30 stderr = getattr(sys.stderr, 'buffer', sys.stderr)
31 31
32 32 is_not_python2 = sys.version_info[0] >= 3
33 33 if is_not_python2:
34 34
35 35 def _sys2bytes(p):
36 36 if p is None:
37 37 return p
38 38 return p.encode('utf-8')
39 39
40 40 def _bytes2sys(p):
41 41 if p is None:
42 42 return p
43 43 return p.decode('utf-8')
44 44
45 45
46 46 else:
47 47
48 48 def _sys2bytes(p):
49 49 return p
50 50
51 51 _bytes2sys = _sys2bytes
52 52
53 53
54 54 def check(name, desc):
55 55 """Registers a check function for a feature."""
56 56
57 57 def decorator(func):
58 58 checks[name] = (func, desc)
59 59 return func
60 60
61 61 return decorator
62 62
63 63
64 64 def checkvers(name, desc, vers):
65 65 """Registers a check function for each of a series of versions.
66 66
67 67 vers can be a list or an iterator.
68 68
69 69 Produces a series of feature checks that have the form <name><vers> without
70 70 any punctuation (even if there's punctuation in 'vers'; i.e. this produces
71 71 'py38', not 'py3.8' or 'py-38')."""
72 72
73 73 def decorator(func):
74 74 def funcv(v):
75 75 def f():
76 76 return func(v)
77 77
78 78 return f
79 79
80 80 for v in vers:
81 81 v = str(v)
82 82 f = funcv(v)
83 83 checks['%s%s' % (name, v.replace('.', ''))] = (f, desc % v)
84 84 return func
85 85
86 86 return decorator
87 87
88 88
89 89 def checkfeatures(features):
90 90 result = {
91 91 'error': [],
92 92 'missing': [],
93 93 'skipped': [],
94 94 }
95 95
96 96 for feature in features:
97 97 negate = feature.startswith('no-')
98 98 if negate:
99 99 feature = feature[3:]
100 100
101 101 if feature not in checks:
102 102 result['missing'].append(feature)
103 103 continue
104 104
105 105 check, desc = checks[feature]
106 106 try:
107 107 available = check()
108 108 except Exception as e:
109 109 result['error'].append('hghave check %s failed: %r' % (feature, e))
110 110 continue
111 111
112 112 if not negate and not available:
113 113 result['skipped'].append('missing feature: %s' % desc)
114 114 elif negate and available:
115 115 result['skipped'].append('system supports %s' % desc)
116 116
117 117 return result
118 118
119 119
120 120 def require(features):
121 121 """Require that features are available, exiting if not."""
122 122 result = checkfeatures(features)
123 123
124 124 for missing in result['missing']:
125 125 stderr.write(
126 126 ('skipped: unknown feature: %s\n' % missing).encode('utf-8')
127 127 )
128 128 for msg in result['skipped']:
129 129 stderr.write(('skipped: %s\n' % msg).encode('utf-8'))
130 130 for msg in result['error']:
131 131 stderr.write(('%s\n' % msg).encode('utf-8'))
132 132
133 133 if result['missing']:
134 134 sys.exit(2)
135 135
136 136 if result['skipped'] or result['error']:
137 137 sys.exit(1)
138 138
139 139
140 140 def matchoutput(cmd, regexp, ignorestatus=False):
141 141 """Return the match object if cmd executes successfully and its output
142 142 is matched by the supplied regular expression.
143 143 """
144 144
145 145 # Tests on Windows have to fake USERPROFILE to point to the test area so
146 146 # that `~` is properly expanded on py3.8+. However, some tools like black
147 147 # make calls that need the real USERPROFILE in order to run `foo --version`.
148 148 env = os.environ
149 149 if os.name == 'nt':
150 150 env = os.environ.copy()
151 151 env['USERPROFILE'] = env['REALUSERPROFILE']
152 152
153 153 r = re.compile(regexp)
154 154 p = subprocess.Popen(
155 155 cmd,
156 156 shell=True,
157 157 stdout=subprocess.PIPE,
158 158 stderr=subprocess.STDOUT,
159 159 env=env,
160 160 )
161 161 s = p.communicate()[0]
162 162 ret = p.returncode
163 163 return (ignorestatus or not ret) and r.search(s)
164 164
165 165
166 166 @check("baz", "GNU Arch baz client")
167 167 def has_baz():
168 168 return matchoutput('baz --version 2>&1', br'baz Bazaar version')
169 169
170 170
171 171 @check("bzr", "Breezy library and executable version >= 3.1")
172 172 def has_bzr():
173 173 if not is_not_python2:
174 174 return False
175 175 try:
176 176 # Test the Breezy python lib
177 177 import breezy
178 178 import breezy.bzr.bzrdir
179 179 import breezy.errors
180 180 import breezy.revision
181 181 import breezy.revisionspec
182 182
183 183 breezy.revisionspec.RevisionSpec
184 184 if breezy.__doc__ is None or breezy.version_info[:2] < (3, 1):
185 185 return False
186 186 except (AttributeError, ImportError):
187 187 return False
188 188 # Test the executable
189 189 return matchoutput('brz --version 2>&1', br'Breezy \(brz\) ')
190 190
191 191
192 192 @check("chg", "running with chg")
193 193 def has_chg():
194 194 return 'CHG_INSTALLED_AS_HG' in os.environ
195 195
196 196
197 197 @check("rhg", "running with rhg as 'hg'")
198 198 def has_rhg():
199 199 return 'RHG_INSTALLED_AS_HG' in os.environ
200 200
201 201
202 202 @check("pyoxidizer", "running with pyoxidizer build as 'hg'")
203 203 def has_rhg():
204 204 return 'PYOXIDIZED_INSTALLED_AS_HG' in os.environ
205 205
206 206
207 207 @check("cvs", "cvs client/server")
208 208 def has_cvs():
209 209 re = br'Concurrent Versions System.*?server'
210 210 return matchoutput('cvs --version 2>&1', re) and not has_msys()
211 211
212 212
213 213 @check("cvs112", "cvs client/server 1.12.* (not cvsnt)")
214 214 def has_cvs112():
215 215 re = br'Concurrent Versions System \(CVS\) 1.12.*?server'
216 216 return matchoutput('cvs --version 2>&1', re) and not has_msys()
217 217
218 218
219 219 @check("cvsnt", "cvsnt client/server")
220 220 def has_cvsnt():
221 221 re = br'Concurrent Versions System \(CVSNT\) (\d+).(\d+).*\(client/server\)'
222 222 return matchoutput('cvsnt --version 2>&1', re)
223 223
224 224
225 225 @check("darcs", "darcs client")
226 226 def has_darcs():
227 227 return matchoutput('darcs --version', br'\b2\.([2-9]|\d{2})', True)
228 228
229 229
230 230 @check("mtn", "monotone client (>= 1.0)")
231 231 def has_mtn():
232 232 return matchoutput('mtn --version', br'monotone', True) and not matchoutput(
233 233 'mtn --version', br'monotone 0\.', True
234 234 )
235 235
236 236
237 237 @check("eol-in-paths", "end-of-lines in paths")
238 238 def has_eol_in_paths():
239 239 try:
240 240 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
241 241 os.close(fd)
242 242 os.remove(path)
243 243 return True
244 244 except (IOError, OSError):
245 245 return False
246 246
247 247
248 248 @check("execbit", "executable bit")
249 249 def has_executablebit():
250 250 try:
251 251 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
252 252 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
253 253 try:
254 254 os.close(fh)
255 255 m = os.stat(fn).st_mode & 0o777
256 256 new_file_has_exec = m & EXECFLAGS
257 257 os.chmod(fn, m ^ EXECFLAGS)
258 258 exec_flags_cannot_flip = (os.stat(fn).st_mode & 0o777) == m
259 259 finally:
260 260 os.unlink(fn)
261 261 except (IOError, OSError):
262 262 # we don't care, the user probably won't be able to commit anyway
263 263 return False
264 264 return not (new_file_has_exec or exec_flags_cannot_flip)
265 265
266 266
267 267 @check("suidbit", "setuid and setgid bit")
268 268 def has_suidbit():
269 269 if (
270 270 getattr(os, "statvfs", None) is None
271 271 or getattr(os, "ST_NOSUID", None) is None
272 272 ):
273 273 return False
274 274 return bool(os.statvfs('.').f_flag & os.ST_NOSUID)
275 275
276 276
277 277 @check("icasefs", "case insensitive file system")
278 278 def has_icasefs():
279 279 # Stolen from mercurial.util
280 280 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
281 281 os.close(fd)
282 282 try:
283 283 s1 = os.stat(path)
284 284 d, b = os.path.split(path)
285 285 p2 = os.path.join(d, b.upper())
286 286 if path == p2:
287 287 p2 = os.path.join(d, b.lower())
288 288 try:
289 289 s2 = os.stat(p2)
290 290 return s2 == s1
291 291 except OSError:
292 292 return False
293 293 finally:
294 294 os.remove(path)
295 295
296 296
297 297 @check("fifo", "named pipes")
298 298 def has_fifo():
299 299 if getattr(os, "mkfifo", None) is None:
300 300 return False
301 301 name = tempfile.mktemp(dir='.', prefix=tempprefix)
302 302 try:
303 303 os.mkfifo(name)
304 304 os.unlink(name)
305 305 return True
306 306 except OSError:
307 307 return False
308 308
309 309
310 310 @check("killdaemons", 'killdaemons.py support')
311 311 def has_killdaemons():
312 312 return True
313 313
314 314
315 315 @check("cacheable", "cacheable filesystem")
316 316 def has_cacheable_fs():
317 317 from mercurial import util
318 318
319 319 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
320 320 os.close(fd)
321 321 try:
322 322 return util.cachestat(path).cacheable()
323 323 finally:
324 324 os.remove(path)
325 325
326 326
327 327 @check("lsprof", "python lsprof module")
328 328 def has_lsprof():
329 329 try:
330 330 import _lsprof
331 331
332 332 _lsprof.Profiler # silence unused import warning
333 333 return True
334 334 except ImportError:
335 335 return False
336 336
337 337
338 338 def _gethgversion():
339 339 m = matchoutput('hg --version --quiet 2>&1', br'(\d+)\.(\d+)')
340 340 if not m:
341 341 return (0, 0)
342 342 return (int(m.group(1)), int(m.group(2)))
343 343
344 344
345 345 _hgversion = None
346 346
347 347
348 348 def gethgversion():
349 349 global _hgversion
350 350 if _hgversion is None:
351 351 _hgversion = _gethgversion()
352 352 return _hgversion
353 353
354 354
355 355 @checkvers(
356 356 "hg", "Mercurial >= %s", list([(1.0 * x) / 10 for x in range(9, 99)])
357 357 )
358 358 def has_hg_range(v):
359 359 major, minor = v.split('.')[0:2]
360 360 return gethgversion() >= (int(major), int(minor))
361 361
362 362
363 363 @check("rust", "Using the Rust extensions")
364 364 def has_rust():
365 365 """Check is the mercurial currently running is using some rust code"""
366 366 cmd = 'hg debuginstall --quiet 2>&1'
367 367 match = br'checking module policy \(([^)]+)\)'
368 368 policy = matchoutput(cmd, match)
369 369 if not policy:
370 370 return False
371 371 return b'rust' in policy.group(1)
372 372
373 373
374 374 @check("hg08", "Mercurial >= 0.8")
375 375 def has_hg08():
376 376 if checks["hg09"][0]():
377 377 return True
378 378 return matchoutput('hg help annotate 2>&1', '--date')
379 379
380 380
381 381 @check("hg07", "Mercurial >= 0.7")
382 382 def has_hg07():
383 383 if checks["hg08"][0]():
384 384 return True
385 385 return matchoutput('hg --version --quiet 2>&1', 'Mercurial Distributed SCM')
386 386
387 387
388 388 @check("hg06", "Mercurial >= 0.6")
389 389 def has_hg06():
390 390 if checks["hg07"][0]():
391 391 return True
392 392 return matchoutput('hg --version --quiet 2>&1', 'Mercurial version')
393 393
394 394
395 395 @check("gettext", "GNU Gettext (msgfmt)")
396 396 def has_gettext():
397 397 return matchoutput('msgfmt --version', br'GNU gettext-tools')
398 398
399 399
400 400 @check("git", "git command line client")
401 401 def has_git():
402 402 return matchoutput('git --version 2>&1', br'^git version')
403 403
404 404
405 405 def getgitversion():
406 406 m = matchoutput('git --version 2>&1', br'git version (\d+)\.(\d+)')
407 407 if not m:
408 408 return (0, 0)
409 409 return (int(m.group(1)), int(m.group(2)))
410 410
411 411
412 412 @check("pygit2", "pygit2 Python library")
413 413 def has_git():
414 414 try:
415 415 import pygit2
416 416
417 417 pygit2.Oid # silence unused import
418 418 return True
419 419 except ImportError:
420 420 return False
421 421
422 422
423 423 # https://github.com/git-lfs/lfs-test-server
424 424 @check("lfs-test-server", "git-lfs test server")
425 425 def has_lfsserver():
426 426 exe = 'lfs-test-server'
427 427 if has_windows():
428 428 exe = 'lfs-test-server.exe'
429 429 return any(
430 430 os.access(os.path.join(path, exe), os.X_OK)
431 431 for path in os.environ["PATH"].split(os.pathsep)
432 432 )
433 433
434 434
435 435 @checkvers("git", "git client (with ext::sh support) version >= %s", (1.9,))
436 436 def has_git_range(v):
437 437 major, minor = v.split('.')[0:2]
438 438 return getgitversion() >= (int(major), int(minor))
439 439
440 440
441 441 @check("docutils", "Docutils text processing library")
442 442 def has_docutils():
443 443 try:
444 444 import docutils.core
445 445
446 446 docutils.core.publish_cmdline # silence unused import
447 447 return True
448 448 except ImportError:
449 449 return False
450 450
451 451
452 452 def getsvnversion():
453 453 m = matchoutput('svn --version --quiet 2>&1', br'^(\d+)\.(\d+)')
454 454 if not m:
455 455 return (0, 0)
456 456 return (int(m.group(1)), int(m.group(2)))
457 457
458 458
459 459 @checkvers("svn", "subversion client and admin tools >= %s", (1.3, 1.5))
460 460 def has_svn_range(v):
461 461 major, minor = v.split('.')[0:2]
462 462 return getsvnversion() >= (int(major), int(minor))
463 463
464 464
465 465 @check("svn", "subversion client and admin tools")
466 466 def has_svn():
467 467 return matchoutput('svn --version 2>&1', br'^svn, version') and matchoutput(
468 468 'svnadmin --version 2>&1', br'^svnadmin, version'
469 469 )
470 470
471 471
472 472 @check("svn-bindings", "subversion python bindings")
473 473 def has_svn_bindings():
474 474 try:
475 475 import svn.core
476 476
477 477 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
478 478 if version < (1, 4):
479 479 return False
480 480 return True
481 481 except ImportError:
482 482 return False
483 483
484 484
485 485 @check("p4", "Perforce server and client")
486 486 def has_p4():
487 487 return matchoutput('p4 -V', br'Rev\. P4/') and matchoutput(
488 488 'p4d -V', br'Rev\. P4D/'
489 489 )
490 490
491 491
492 492 @check("symlink", "symbolic links")
493 493 def has_symlink():
494 494 # mercurial.windows.checklink() is a hard 'no' at the moment
495 495 if os.name == 'nt' or getattr(os, "symlink", None) is None:
496 496 return False
497 497 name = tempfile.mktemp(dir='.', prefix=tempprefix)
498 498 try:
499 499 os.symlink(".", name)
500 500 os.unlink(name)
501 501 return True
502 502 except (OSError, AttributeError):
503 503 return False
504 504
505 505
506 506 @check("hardlink", "hardlinks")
507 507 def has_hardlink():
508 508 from mercurial import util
509 509
510 510 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
511 511 os.close(fh)
512 512 name = tempfile.mktemp(dir='.', prefix=tempprefix)
513 513 try:
514 514 util.oslink(_sys2bytes(fn), _sys2bytes(name))
515 515 os.unlink(name)
516 516 return True
517 517 except OSError:
518 518 return False
519 519 finally:
520 520 os.unlink(fn)
521 521
522 522
523 523 @check("hardlink-whitelisted", "hardlinks on whitelisted filesystems")
524 524 def has_hardlink_whitelisted():
525 525 from mercurial import util
526 526
527 527 try:
528 528 fstype = util.getfstype(b'.')
529 529 except OSError:
530 530 return False
531 531 return fstype in util._hardlinkfswhitelist
532 532
533 533
534 534 @check("rmcwd", "can remove current working directory")
535 535 def has_rmcwd():
536 536 ocwd = os.getcwd()
537 537 temp = tempfile.mkdtemp(dir='.', prefix=tempprefix)
538 538 try:
539 539 os.chdir(temp)
540 540 # On Linux, 'rmdir .' isn't allowed, but the other names are okay.
541 541 # On Solaris and Windows, the cwd can't be removed by any names.
542 542 os.rmdir(os.getcwd())
543 543 return True
544 544 except OSError:
545 545 return False
546 546 finally:
547 547 os.chdir(ocwd)
548 548 # clean up temp dir on platforms where cwd can't be removed
549 549 try:
550 550 os.rmdir(temp)
551 551 except OSError:
552 552 pass
553 553
554 554
555 555 @check("tla", "GNU Arch tla client")
556 556 def has_tla():
557 557 return matchoutput('tla --version 2>&1', br'The GNU Arch Revision')
558 558
559 559
560 560 @check("gpg", "gpg client")
561 561 def has_gpg():
562 562 return matchoutput('gpg --version 2>&1', br'GnuPG')
563 563
564 564
565 565 @check("gpg2", "gpg client v2")
566 566 def has_gpg2():
567 567 return matchoutput('gpg --version 2>&1', br'GnuPG[^0-9]+2\.')
568 568
569 569
570 570 @check("gpg21", "gpg client v2.1+")
571 571 def has_gpg21():
572 572 return matchoutput('gpg --version 2>&1', br'GnuPG[^0-9]+2\.(?!0)')
573 573
574 574
575 575 @check("unix-permissions", "unix-style permissions")
576 576 def has_unix_permissions():
577 577 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
578 578 try:
579 579 fname = os.path.join(d, 'foo')
580 580 for umask in (0o77, 0o07, 0o22):
581 581 os.umask(umask)
582 582 f = open(fname, 'w')
583 583 f.close()
584 584 mode = os.stat(fname).st_mode
585 585 os.unlink(fname)
586 586 if mode & 0o777 != ~umask & 0o666:
587 587 return False
588 588 return True
589 589 finally:
590 590 os.rmdir(d)
591 591
592 592
593 593 @check("unix-socket", "AF_UNIX socket family")
594 594 def has_unix_socket():
595 595 return getattr(socket, 'AF_UNIX', None) is not None
596 596
597 597
598 598 @check("root", "root permissions")
599 599 def has_root():
600 600 return getattr(os, 'geteuid', None) and os.geteuid() == 0
601 601
602 602
603 603 @check("pyflakes", "Pyflakes python linter")
604 604 def has_pyflakes():
605 605 try:
606 606 import pyflakes
607 607
608 608 pyflakes.__version__
609 609 except ImportError:
610 610 return False
611 611 else:
612 612 return True
613 613
614 614
615 615 @check("pylint", "Pylint python linter")
616 616 def has_pylint():
617 617 return matchoutput("pylint --help", br"Usage:[ ]+pylint", True)
618 618
619 619
620 620 @check("clang-format", "clang-format C code formatter (>= 11)")
621 621 def has_clang_format():
622 622 m = matchoutput('clang-format --version', br'clang-format version (\d+)')
623 623 # style changed somewhere between 10.x and 11.x
624 624 if m:
625 625 return int(m.group(1)) >= 11
626 626 # Assist Googler contributors, they have a centrally-maintained version of
627 627 # clang-format that is generally very fresh, but unlike most builds (both
628 628 # official and unofficial), it does *not* include a version number.
629 629 return matchoutput(
630 630 'clang-format --version', br'clang-format .*google3-trunk \([0-9a-f]+\)'
631 631 )
632 632
633 633
634 634 @check("jshint", "JSHint static code analysis tool")
635 635 def has_jshint():
636 636 return matchoutput("jshint --version 2>&1", br"jshint v")
637 637
638 638
639 639 @check("pygments", "Pygments source highlighting library")
640 640 def has_pygments():
641 641 try:
642 642 import pygments
643 643
644 644 pygments.highlight # silence unused import warning
645 645 return True
646 646 except ImportError:
647 647 return False
648 648
649 649
650 650 @check("pygments25", "Pygments version >= 2.5")
651 651 def pygments25():
652 652 try:
653 653 import pygments
654 654
655 655 v = pygments.__version__
656 656 except ImportError:
657 657 return False
658 658
659 659 parts = v.split(".")
660 660 major = int(parts[0])
661 661 minor = int(parts[1])
662 662
663 663 return (major, minor) >= (2, 5)
664 664
665 665
666 666 @check("outer-repo", "outer repo")
667 667 def has_outer_repo():
668 668 # failing for other reasons than 'no repo' imply that there is a repo
669 669 return not matchoutput('hg root 2>&1', br'abort: no repository found', True)
670 670
671 671
672 672 @check("ssl", "ssl module available")
673 673 def has_ssl():
674 674 try:
675 675 import ssl
676 676
677 677 ssl.CERT_NONE
678 678 return True
679 679 except ImportError:
680 680 return False
681 681
682 682
683 683 @check("defaultcacertsloaded", "detected presence of loaded system CA certs")
684 684 def has_defaultcacertsloaded():
685 685 import ssl
686 686 from mercurial import sslutil, ui as uimod
687 687
688 688 ui = uimod.ui.load()
689 689 cafile = sslutil._defaultcacerts(ui)
690 690 ctx = ssl.create_default_context()
691 691 if cafile:
692 692 ctx.load_verify_locations(cafile=cafile)
693 693 else:
694 694 ctx.load_default_certs()
695 695
696 696 return len(ctx.get_ca_certs()) > 0
697 697
698 698
699 699 @check("tls1.2", "TLS 1.2 protocol support")
700 700 def has_tls1_2():
701 701 from mercurial import sslutil
702 702
703 703 return b'tls1.2' in sslutil.supportedprotocols
704 704
705 705
706 706 @check("windows", "Windows")
707 707 def has_windows():
708 708 return os.name == 'nt'
709 709
710 710
711 711 @check("system-sh", "system() uses sh")
712 712 def has_system_sh():
713 713 return os.name != 'nt'
714 714
715 715
716 716 @check("serve", "platform and python can manage 'hg serve -d'")
717 717 def has_serve():
718 718 return True
719 719
720 720
721 721 @check("setprocname", "whether osutil.setprocname is available or not")
722 722 def has_setprocname():
723 723 try:
724 724 from mercurial.utils import procutil
725 725
726 726 procutil.setprocname
727 727 return True
728 728 except AttributeError:
729 729 return False
730 730
731 731
732 732 @check("test-repo", "running tests from repository")
733 733 def has_test_repo():
734 734 t = os.environ["TESTDIR"]
735 735 return os.path.isdir(os.path.join(t, "..", ".hg"))
736 736
737 737
738 738 @check("network-io", "whether tests are allowed to access 3rd party services")
739 739 def has_test_repo():
740 740 t = os.environ.get("HGTESTS_ALLOW_NETIO")
741 741 return t == "1"
742 742
743 743
744 744 @check("curses", "terminfo compiler and curses module")
745 745 def has_curses():
746 746 try:
747 747 import curses
748 748
749 749 curses.COLOR_BLUE
750 750
751 751 # Windows doesn't have a `tic` executable, but the windows_curses
752 752 # package is sufficient to run the tests without it.
753 753 if os.name == 'nt':
754 754 return True
755 755
756 756 return has_tic()
757 757
758 758 except (ImportError, AttributeError):
759 759 return False
760 760
761 761
762 762 @check("tic", "terminfo compiler")
763 763 def has_tic():
764 764 return matchoutput('test -x "`which tic`"', br'')
765 765
766 766
767 767 @check("xz", "xz compression utility")
768 768 def has_xz():
769 769 # When Windows invokes a subprocess in shell mode, it uses `cmd.exe`, which
770 770 # only knows `where`, not `which`. So invoke MSYS shell explicitly.
771 771 return matchoutput("sh -c 'test -x \"`which xz`\"'", b'')
772 772
773 773
774 774 @check("msys", "Windows with MSYS")
775 775 def has_msys():
776 776 return os.getenv('MSYSTEM')
777 777
778 778
779 779 @check("aix", "AIX")
780 780 def has_aix():
781 781 return sys.platform.startswith("aix")
782 782
783 783
784 784 @check("osx", "OS X")
785 785 def has_osx():
786 786 return sys.platform == 'darwin'
787 787
788 788
789 789 @check("osxpackaging", "OS X packaging tools")
790 790 def has_osxpackaging():
791 791 try:
792 792 return (
793 793 matchoutput('pkgbuild', br'Usage: pkgbuild ', ignorestatus=1)
794 794 and matchoutput(
795 795 'productbuild', br'Usage: productbuild ', ignorestatus=1
796 796 )
797 797 and matchoutput('lsbom', br'Usage: lsbom', ignorestatus=1)
798 798 and matchoutput('xar --help', br'Usage: xar', ignorestatus=1)
799 799 )
800 800 except ImportError:
801 801 return False
802 802
803 803
804 804 @check('linuxormacos', 'Linux or MacOS')
805 805 def has_linuxormacos():
806 806 # This isn't a perfect test for MacOS. But it is sufficient for our needs.
807 807 return sys.platform.startswith(('linux', 'darwin'))
808 808
809 809
810 810 @check("docker", "docker support")
811 811 def has_docker():
812 812 pat = br'A self-sufficient runtime for'
813 813 if matchoutput('docker --help', pat):
814 814 if 'linux' not in sys.platform:
815 815 # TODO: in theory we should be able to test docker-based
816 816 # package creation on non-linux using boot2docker, but in
817 817 # practice that requires extra coordination to make sure
818 818 # $TESTTEMP is going to be visible at the same path to the
819 819 # boot2docker VM. If we figure out how to verify that, we
820 820 # can use the following instead of just saying False:
821 821 # return 'DOCKER_HOST' in os.environ
822 822 return False
823 823
824 824 return True
825 825 return False
826 826
827 827
828 828 @check("debhelper", "debian packaging tools")
829 829 def has_debhelper():
830 830 # Some versions of dpkg say `dpkg', some say 'dpkg' (` vs ' on the first
831 831 # quote), so just accept anything in that spot.
832 832 dpkg = matchoutput(
833 833 'dpkg --version', br"Debian .dpkg' package management program"
834 834 )
835 835 dh = matchoutput(
836 836 'dh --help', br'dh is a part of debhelper.', ignorestatus=True
837 837 )
838 838 dh_py2 = matchoutput(
839 839 'dh_python2 --help', br'other supported Python versions'
840 840 )
841 841 # debuild comes from the 'devscripts' package, though you might want
842 842 # the 'build-debs' package instead, which has a dependency on devscripts.
843 843 debuild = matchoutput(
844 844 'debuild --help', br'to run debian/rules with given parameter'
845 845 )
846 846 return dpkg and dh and dh_py2 and debuild
847 847
848 848
849 849 @check(
850 850 "debdeps", "debian build dependencies (run dpkg-checkbuilddeps in contrib/)"
851 851 )
852 852 def has_debdeps():
853 853 # just check exit status (ignoring output)
854 854 path = '%s/../contrib/packaging/debian/control' % os.environ['TESTDIR']
855 855 return matchoutput('dpkg-checkbuilddeps %s' % path, br'')
856 856
857 857
858 858 @check("demandimport", "demandimport enabled")
859 859 def has_demandimport():
860 860 # chg disables demandimport intentionally for performance wins.
861 861 return (not has_chg()) and os.environ.get('HGDEMANDIMPORT') != 'disable'
862 862
863 863
864 864 # Add "py27", "py35", ... as possible feature checks. Note that there's no
865 865 # punctuation here.
866 866 @checkvers("py", "Python >= %s", (2.7, 3.5, 3.6, 3.7, 3.8, 3.9))
867 867 def has_python_range(v):
868 868 major, minor = v.split('.')[0:2]
869 869 py_major, py_minor = sys.version_info.major, sys.version_info.minor
870 870
871 871 return (py_major, py_minor) >= (int(major), int(minor))
872 872
873 873
874 874 @check("py3", "running with Python 3.x")
875 875 def has_py3():
876 876 return 3 == sys.version_info[0]
877 877
878 878
879 879 @check("py3exe", "a Python 3.x interpreter is available")
880 880 def has_python3exe():
881 881 py = 'python3'
882 882 if os.name == 'nt':
883 883 py = 'py -3'
884 884 return matchoutput('%s -V' % py, br'^Python 3.(5|6|7|8|9)')
885 885
886 886
887 887 @check("pure", "running with pure Python code")
888 888 def has_pure():
889 889 return any(
890 890 [
891 891 os.environ.get("HGMODULEPOLICY") == "py",
892 892 os.environ.get("HGTEST_RUN_TESTS_PURE") == "--pure",
893 893 ]
894 894 )
895 895
896 896
897 897 @check("slow", "allow slow tests (use --allow-slow-tests)")
898 898 def has_slow():
899 899 return os.environ.get('HGTEST_SLOW') == 'slow'
900 900
901 901
902 902 @check("hypothesis", "Hypothesis automated test generation")
903 903 def has_hypothesis():
904 904 try:
905 905 import hypothesis
906 906
907 907 hypothesis.given
908 908 return True
909 909 except ImportError:
910 910 return False
911 911
912 912
913 913 @check("unziplinks", "unzip(1) understands and extracts symlinks")
914 914 def unzip_understands_symlinks():
915 915 return matchoutput('unzip --help', br'Info-ZIP')
916 916
917 917
918 918 @check("zstd", "zstd Python module available")
919 919 def has_zstd():
920 920 try:
921 921 import mercurial.zstd
922 922
923 923 mercurial.zstd.__version__
924 924 return True
925 925 except ImportError:
926 926 return False
927 927
928 928
929 929 @check("devfull", "/dev/full special file")
930 930 def has_dev_full():
931 931 return os.path.exists('/dev/full')
932 932
933 933
934 934 @check("ensurepip", "ensurepip module")
935 935 def has_ensurepip():
936 936 try:
937 937 import ensurepip
938 938
939 939 ensurepip.bootstrap
940 940 return True
941 941 except ImportError:
942 942 return False
943 943
944 944
945 945 @check("virtualenv", "virtualenv support")
946 946 def has_virtualenv():
947 947 try:
948 948 import virtualenv
949 949
950 950 # --no-site-package became the default in 1.7 (Nov 2011), and the
951 951 # argument was removed in 20.0 (Feb 2020). Rather than make the
952 952 # script complicated, just ignore ancient versions.
953 953 return int(virtualenv.__version__.split('.')[0]) > 1
954 954 except (AttributeError, ImportError, IndexError):
955 955 return False
956 956
957 957
958 958 @check("fsmonitor", "running tests with fsmonitor")
959 959 def has_fsmonitor():
960 960 return 'HGFSMONITOR_TESTS' in os.environ
961 961
962 962
963 963 @check("fuzzywuzzy", "Fuzzy string matching library")
964 964 def has_fuzzywuzzy():
965 965 try:
966 966 import fuzzywuzzy
967 967
968 968 fuzzywuzzy.__version__
969 969 return True
970 970 except ImportError:
971 971 return False
972 972
973 973
974 974 @check("clang-libfuzzer", "clang new enough to include libfuzzer")
975 975 def has_clang_libfuzzer():
976 976 mat = matchoutput('clang --version', br'clang version (\d)')
977 977 if mat:
978 978 # libfuzzer is new in clang 6
979 979 return int(mat.group(1)) > 5
980 980 return False
981 981
982 982
983 983 @check("clang-6.0", "clang 6.0 with version suffix (libfuzzer included)")
984 984 def has_clang60():
985 985 return matchoutput('clang-6.0 --version', br'clang version 6\.')
986 986
987 987
988 988 @check("xdiff", "xdiff algorithm")
989 989 def has_xdiff():
990 990 try:
991 991 from mercurial import policy
992 992
993 993 bdiff = policy.importmod('bdiff')
994 994 return bdiff.xdiffblocks(b'', b'') == [(0, 0, 0, 0)]
995 995 except (ImportError, AttributeError):
996 996 return False
997 997
998 998
999 999 @check('extraextensions', 'whether tests are running with extra extensions')
1000 1000 def has_extraextensions():
1001 1001 return 'HGTESTEXTRAEXTENSIONS' in os.environ
1002 1002
1003 1003
1004 1004 def getrepofeatures():
1005 1005 """Obtain set of repository features in use.
1006 1006
1007 1007 HGREPOFEATURES can be used to define or remove features. It contains
1008 1008 a space-delimited list of feature strings. Strings beginning with ``-``
1009 1009 mean to remove.
1010 1010 """
1011 1011 # Default list provided by core.
1012 1012 features = {
1013 1013 'bundlerepo',
1014 1014 'revlogstore',
1015 1015 'fncache',
1016 1016 }
1017 1017
1018 1018 # Features that imply other features.
1019 1019 implies = {
1020 1020 'simplestore': ['-revlogstore', '-bundlerepo', '-fncache'],
1021 1021 }
1022 1022
1023 1023 for override in os.environ.get('HGREPOFEATURES', '').split(' '):
1024 1024 if not override:
1025 1025 continue
1026 1026
1027 1027 if override.startswith('-'):
1028 1028 if override[1:] in features:
1029 1029 features.remove(override[1:])
1030 1030 else:
1031 1031 features.add(override)
1032 1032
1033 1033 for imply in implies.get(override, []):
1034 1034 if imply.startswith('-'):
1035 1035 if imply[1:] in features:
1036 1036 features.remove(imply[1:])
1037 1037 else:
1038 1038 features.add(imply)
1039 1039
1040 1040 return features
1041 1041
1042 1042
1043 1043 @check('reporevlogstore', 'repository using the default revlog store')
1044 1044 def has_reporevlogstore():
1045 1045 return 'revlogstore' in getrepofeatures()
1046 1046
1047 1047
1048 1048 @check('reposimplestore', 'repository using simple storage extension')
1049 1049 def has_reposimplestore():
1050 1050 return 'simplestore' in getrepofeatures()
1051 1051
1052 1052
1053 1053 @check('repobundlerepo', 'whether we can open bundle files as repos')
1054 1054 def has_repobundlerepo():
1055 1055 return 'bundlerepo' in getrepofeatures()
1056 1056
1057 1057
1058 1058 @check('repofncache', 'repository has an fncache')
1059 1059 def has_repofncache():
1060 1060 return 'fncache' in getrepofeatures()
1061 1061
1062 1062
1063 1063 @check('dirstate-v2', 'using the v2 format of .hg/dirstate')
1064 1064 def has_dirstate_v2():
1065 1065 # Keep this logic in sync with `newreporequirements()` in `mercurial/localrepo.py`
1066 1066 return has_rust() and matchoutput(
1067 1067 'hg config format.exp-rc-dirstate-v2', b'(?i)1|yes|true|on|always'
1068 1068 )
1069 1069
1070 1070
1071 1071 @check('sqlite', 'sqlite3 module and matching cli is available')
1072 1072 def has_sqlite():
1073 1073 try:
1074 1074 import sqlite3
1075 1075
1076 1076 version = sqlite3.sqlite_version_info
1077 1077 except ImportError:
1078 1078 return False
1079 1079
1080 1080 if version < (3, 8, 3):
1081 1081 # WITH clause not supported
1082 1082 return False
1083 1083
1084 1084 return matchoutput('sqlite3 -version', br'^3\.\d+')
1085 1085
1086 1086
1087 1087 @check('vcr', 'vcr http mocking library (pytest-vcr)')
1088 1088 def has_vcr():
1089 1089 try:
1090 1090 import vcr
1091 1091
1092 1092 vcr.VCR
1093 1093 return True
1094 1094 except (ImportError, AttributeError):
1095 1095 pass
1096 1096 return False
1097 1097
1098 1098
1099 1099 @check('emacs', 'GNU Emacs')
1100 1100 def has_emacs():
1101 1101 # Our emacs lisp uses `with-eval-after-load` which is new in emacs
1102 1102 # 24.4, so we allow emacs 24.4, 24.5, and 25+ (24.5 was the last
1103 1103 # 24 release)
1104 1104 return matchoutput('emacs --version', b'GNU Emacs 2(4.4|4.5|5|6|7|8|9)')
1105 1105
1106 1106
1107 1107 @check('black', 'the black formatter for python (>= 20.8b1)')
1108 1108 def has_black():
1109 1109 blackcmd = 'black --version'
1110 1110 version_regex = b'black, version ([0-9a-b.]+)'
1111 1111 version = matchoutput(blackcmd, version_regex)
1112 1112 sv = distutils.version.StrictVersion
1113 1113 return version and sv(_bytes2sys(version.group(1))) >= sv('20.8b1')
1114 1114
1115 1115
1116 1116 @check('pytype', 'the pytype type checker')
1117 1117 def has_pytype():
1118 1118 pytypecmd = 'pytype --version'
1119 1119 version = matchoutput(pytypecmd, b'[0-9a-b.]+')
1120 1120 sv = distutils.version.StrictVersion
1121 1121 return version and sv(_bytes2sys(version.group(0))) >= sv('2019.10.17')
1122 1122
1123 1123
1124 1124 @check("rustfmt", "rustfmt tool at version nightly-2020-10-04")
1125 1125 def has_rustfmt():
1126 1126 # We use Nightly's rustfmt due to current unstable config options.
1127 1127 return matchoutput(
1128 1128 '`rustup which --toolchain nightly-2020-10-04 rustfmt` --version',
1129 1129 b'rustfmt',
1130 1130 )
1131 1131
1132 1132
1133 1133 @check("cargo", "cargo tool")
1134 1134 def has_cargo():
1135 1135 return matchoutput('`rustup which cargo` --version', b'cargo')
1136 1136
1137 1137
1138 1138 @check("lzma", "python lzma module")
1139 1139 def has_lzma():
1140 1140 try:
1141 1141 import _lzma
1142 1142
1143 1143 _lzma.FORMAT_XZ
1144 1144 return True
1145 1145 except ImportError:
1146 1146 return False
1147 1147
1148 1148
1149 1149 @check("bash", "bash shell")
1150 1150 def has_bash():
1151 1151 return matchoutput("bash -c 'echo hi'", b'^hi$')
1152
1153
1154 @check("bigendian", "big-endian CPU")
1155 def has_bigendian():
1156 return sys.byteorder == 'big'
@@ -1,904 +1,907
1 1 #require serve no-reposimplestore no-chg
2 2
3 3 #testcases stream-legacy stream-bundle2
4 4
5 5 #if stream-legacy
6 6 $ cat << EOF >> $HGRCPATH
7 7 > [server]
8 8 > bundle2.stream = no
9 9 > EOF
10 10 #endif
11 11
12 12 Initialize repository
13 13 the status call is to check for issue5130
14 14
15 15 $ hg init server
16 16 $ cd server
17 17 $ touch foo
18 18 $ hg -q commit -A -m initial
19 19 >>> for i in range(1024):
20 20 ... with open(str(i), 'wb') as fh:
21 21 ... fh.write(b"%d" % i) and None
22 22 $ hg -q commit -A -m 'add a lot of files'
23 23 $ hg st
24 24
25 25 add files with "tricky" name:
26 26
27 27 $ echo foo > 00changelog.i
28 28 $ echo foo > 00changelog.d
29 29 $ echo foo > 00changelog.n
30 30 $ echo foo > 00changelog-ab349180a0405010.nd
31 31 $ echo foo > 00manifest.i
32 32 $ echo foo > 00manifest.d
33 33 $ echo foo > foo.i
34 34 $ echo foo > foo.d
35 35 $ echo foo > foo.n
36 36 $ echo foo > undo.py
37 37 $ echo foo > undo.i
38 38 $ echo foo > undo.d
39 39 $ echo foo > undo.n
40 40 $ echo foo > undo.foo.i
41 41 $ echo foo > undo.foo.d
42 42 $ echo foo > undo.foo.n
43 43 $ echo foo > undo.babar
44 44 $ mkdir savanah
45 45 $ echo foo > savanah/foo.i
46 46 $ echo foo > savanah/foo.d
47 47 $ echo foo > savanah/foo.n
48 48 $ echo foo > savanah/undo.py
49 49 $ echo foo > savanah/undo.i
50 50 $ echo foo > savanah/undo.d
51 51 $ echo foo > savanah/undo.n
52 52 $ echo foo > savanah/undo.foo.i
53 53 $ echo foo > savanah/undo.foo.d
54 54 $ echo foo > savanah/undo.foo.n
55 55 $ echo foo > savanah/undo.babar
56 56 $ mkdir data
57 57 $ echo foo > data/foo.i
58 58 $ echo foo > data/foo.d
59 59 $ echo foo > data/foo.n
60 60 $ echo foo > data/undo.py
61 61 $ echo foo > data/undo.i
62 62 $ echo foo > data/undo.d
63 63 $ echo foo > data/undo.n
64 64 $ echo foo > data/undo.foo.i
65 65 $ echo foo > data/undo.foo.d
66 66 $ echo foo > data/undo.foo.n
67 67 $ echo foo > data/undo.babar
68 68 $ mkdir meta
69 69 $ echo foo > meta/foo.i
70 70 $ echo foo > meta/foo.d
71 71 $ echo foo > meta/foo.n
72 72 $ echo foo > meta/undo.py
73 73 $ echo foo > meta/undo.i
74 74 $ echo foo > meta/undo.d
75 75 $ echo foo > meta/undo.n
76 76 $ echo foo > meta/undo.foo.i
77 77 $ echo foo > meta/undo.foo.d
78 78 $ echo foo > meta/undo.foo.n
79 79 $ echo foo > meta/undo.babar
80 80 $ mkdir store
81 81 $ echo foo > store/foo.i
82 82 $ echo foo > store/foo.d
83 83 $ echo foo > store/foo.n
84 84 $ echo foo > store/undo.py
85 85 $ echo foo > store/undo.i
86 86 $ echo foo > store/undo.d
87 87 $ echo foo > store/undo.n
88 88 $ echo foo > store/undo.foo.i
89 89 $ echo foo > store/undo.foo.d
90 90 $ echo foo > store/undo.foo.n
91 91 $ echo foo > store/undo.babar
92 92
93 93 Name with special characters
94 94
95 95 $ echo foo > store/CélesteVille_is_a_Capital_City
96 96
97 97 name causing issue6581
98 98
99 99 $ mkdir -p container/isam-build-centos7/
100 100 $ touch container/isam-build-centos7/bazel-coverage-generator-sandboxfs-compatibility-0758e3e4f6057904d44399bd666faba9e7f40686.patch
101 101
102 102 Add all that
103 103
104 104 $ hg add .
105 105 adding 00changelog-ab349180a0405010.nd
106 106 adding 00changelog.d
107 107 adding 00changelog.i
108 108 adding 00changelog.n
109 109 adding 00manifest.d
110 110 adding 00manifest.i
111 111 adding container/isam-build-centos7/bazel-coverage-generator-sandboxfs-compatibility-0758e3e4f6057904d44399bd666faba9e7f40686.patch
112 112 adding data/foo.d
113 113 adding data/foo.i
114 114 adding data/foo.n
115 115 adding data/undo.babar
116 116 adding data/undo.d
117 117 adding data/undo.foo.d
118 118 adding data/undo.foo.i
119 119 adding data/undo.foo.n
120 120 adding data/undo.i
121 121 adding data/undo.n
122 122 adding data/undo.py
123 123 adding foo.d
124 124 adding foo.i
125 125 adding foo.n
126 126 adding meta/foo.d
127 127 adding meta/foo.i
128 128 adding meta/foo.n
129 129 adding meta/undo.babar
130 130 adding meta/undo.d
131 131 adding meta/undo.foo.d
132 132 adding meta/undo.foo.i
133 133 adding meta/undo.foo.n
134 134 adding meta/undo.i
135 135 adding meta/undo.n
136 136 adding meta/undo.py
137 137 adding savanah/foo.d
138 138 adding savanah/foo.i
139 139 adding savanah/foo.n
140 140 adding savanah/undo.babar
141 141 adding savanah/undo.d
142 142 adding savanah/undo.foo.d
143 143 adding savanah/undo.foo.i
144 144 adding savanah/undo.foo.n
145 145 adding savanah/undo.i
146 146 adding savanah/undo.n
147 147 adding savanah/undo.py
148 148 adding store/C\xc3\xa9lesteVille_is_a_Capital_City (esc)
149 149 adding store/foo.d
150 150 adding store/foo.i
151 151 adding store/foo.n
152 152 adding store/undo.babar
153 153 adding store/undo.d
154 154 adding store/undo.foo.d
155 155 adding store/undo.foo.i
156 156 adding store/undo.foo.n
157 157 adding store/undo.i
158 158 adding store/undo.n
159 159 adding store/undo.py
160 160 adding undo.babar
161 161 adding undo.d
162 162 adding undo.foo.d
163 163 adding undo.foo.i
164 164 adding undo.foo.n
165 165 adding undo.i
166 166 adding undo.n
167 167 adding undo.py
168 168 $ hg ci -m 'add files with "tricky" name'
169 169 $ hg --config server.uncompressed=false serve -p $HGPORT -d --pid-file=hg.pid
170 170 $ cat hg.pid > $DAEMON_PIDS
171 171 $ cd ..
172 172
173 173 Check local clone
174 174 ==================
175 175
176 176 The logic is close enough of uncompressed.
177 177 This is present here to reuse the testing around file with "special" names.
178 178
179 179 $ hg clone server local-clone
180 180 updating to branch default
181 181 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 182
183 183 Check that the clone went well
184 184
185 185 $ hg verify -R local-clone
186 186 checking changesets
187 187 checking manifests
188 188 crosschecking files in changesets and manifests
189 189 checking files
190 190 checked 3 changesets with 1088 changes to 1088 files
191 191
192 192 Check uncompressed
193 193 ==================
194 194
195 195 Cannot stream clone when server.uncompressed is set
196 196
197 197 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
198 198 200 Script output follows
199 199
200 200 1
201 201
202 202 #if stream-legacy
203 203 $ hg debugcapabilities http://localhost:$HGPORT
204 204 Main capabilities:
205 205 batch
206 206 branchmap
207 207 $USUAL_BUNDLE2_CAPS_SERVER$
208 208 changegroupsubset
209 209 compression=$BUNDLE2_COMPRESSIONS$
210 210 getbundle
211 211 httpheader=1024
212 212 httpmediatype=0.1rx,0.1tx,0.2tx
213 213 known
214 214 lookup
215 215 pushkey
216 216 unbundle=HG10GZ,HG10BZ,HG10UN
217 217 unbundlehash
218 218 Bundle2 capabilities:
219 219 HG20
220 220 bookmarks
221 221 changegroup
222 222 01
223 223 02
224 224 checkheads
225 225 related
226 226 digests
227 227 md5
228 228 sha1
229 229 sha512
230 230 error
231 231 abort
232 232 unsupportedcontent
233 233 pushraced
234 234 pushkey
235 235 hgtagsfnodes
236 236 listkeys
237 237 phases
238 238 heads
239 239 pushkey
240 240 remote-changegroup
241 241 http
242 242 https
243 243
244 244 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
245 245 warning: stream clone requested but server has them disabled
246 246 requesting all changes
247 247 adding changesets
248 248 adding manifests
249 249 adding file changes
250 250 added 3 changesets with 1088 changes to 1088 files
251 251 new changesets 96ee1d7354c4:5223b5e3265f
252 252
253 253 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
254 254 200 Script output follows
255 255 content-type: application/mercurial-0.2
256 256
257 257
258 258 $ f --size body --hexdump --bytes 100
259 259 body: size=232
260 260 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
261 261 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
262 262 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
263 263 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
264 264 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
265 265 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
266 266 0060: 69 73 20 66 |is f|
267 267
268 268 #endif
269 269 #if stream-bundle2
270 270 $ hg debugcapabilities http://localhost:$HGPORT
271 271 Main capabilities:
272 272 batch
273 273 branchmap
274 274 $USUAL_BUNDLE2_CAPS_SERVER$
275 275 changegroupsubset
276 276 compression=$BUNDLE2_COMPRESSIONS$
277 277 getbundle
278 278 httpheader=1024
279 279 httpmediatype=0.1rx,0.1tx,0.2tx
280 280 known
281 281 lookup
282 282 pushkey
283 283 unbundle=HG10GZ,HG10BZ,HG10UN
284 284 unbundlehash
285 285 Bundle2 capabilities:
286 286 HG20
287 287 bookmarks
288 288 changegroup
289 289 01
290 290 02
291 291 checkheads
292 292 related
293 293 digests
294 294 md5
295 295 sha1
296 296 sha512
297 297 error
298 298 abort
299 299 unsupportedcontent
300 300 pushraced
301 301 pushkey
302 302 hgtagsfnodes
303 303 listkeys
304 304 phases
305 305 heads
306 306 pushkey
307 307 remote-changegroup
308 308 http
309 309 https
310 310
311 311 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
312 312 warning: stream clone requested but server has them disabled
313 313 requesting all changes
314 314 adding changesets
315 315 adding manifests
316 316 adding file changes
317 317 added 3 changesets with 1088 changes to 1088 files
318 318 new changesets 96ee1d7354c4:5223b5e3265f
319 319
320 320 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
321 321 200 Script output follows
322 322 content-type: application/mercurial-0.2
323 323
324 324
325 325 $ f --size body --hexdump --bytes 100
326 326 body: size=232
327 327 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
328 328 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
329 329 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
330 330 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
331 331 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
332 332 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
333 333 0060: 69 73 20 66 |is f|
334 334
335 335 #endif
336 336
337 337 $ killdaemons.py
338 338 $ cd server
339 339 $ hg serve -p $HGPORT -d --pid-file=hg.pid --error errors.txt
340 340 $ cat hg.pid > $DAEMON_PIDS
341 341 $ cd ..
342 342
343 343 Basic clone
344 344
345 345 #if stream-legacy
346 346 $ hg clone --stream -U http://localhost:$HGPORT clone1
347 347 streaming all changes
348 348 1090 files to transfer, 102 KB of data (no-zstd !)
349 349 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
350 350 1090 files to transfer, 98.8 KB of data (zstd !)
351 351 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
352 352 searching for changes
353 353 no changes found
354 354 $ cat server/errors.txt
355 355 #endif
356 356 #if stream-bundle2
357 357 $ hg clone --stream -U http://localhost:$HGPORT clone1
358 358 streaming all changes
359 359 1093 files to transfer, 102 KB of data (no-zstd !)
360 360 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
361 361 1093 files to transfer, 98.9 KB of data (zstd !)
362 362 transferred 98.9 KB in * seconds (* */sec) (glob) (zstd !)
363 363
364 364 $ ls -1 clone1/.hg/cache
365 365 branch2-base
366 366 branch2-immutable
367 367 branch2-served
368 368 branch2-served.hidden
369 369 branch2-visible
370 370 branch2-visible-hidden
371 371 rbc-names-v1
372 372 rbc-revs-v1
373 373 tags2
374 374 tags2-served
375 375 $ cat server/errors.txt
376 376 #endif
377 377
378 378 getbundle requests with stream=1 are uncompressed
379 379
380 380 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto '0.1 0.2 comp=zlib,none' --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
381 381 200 Script output follows
382 382 content-type: application/mercurial-0.2
383 383
384 384
385 385 #if no-zstd no-rust
386 386 $ f --size --hex --bytes 256 body
387 387 body: size=119153
388 388 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
389 389 0010: 80 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
390 390 0020: 06 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 31 30 |....Dbytecount10|
391 391 0030: 34 31 31 35 66 69 6c 65 63 6f 75 6e 74 31 30 39 |4115filecount109|
392 392 0040: 33 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |3requirementsdot|
393 393 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache|
394 394 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%|
395 395 0070: 32 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 |2Crevlogv1%2Cspa|
396 396 0080: 72 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 |rserevlog%2Cstor|
397 397 0090: 65 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 |e....s.Bdata/0.i|
398 398 00a0: 00 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 |................|
399 399 00b0: 00 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff |................|
400 400 00c0: 80 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c |.)c.I.#....Vg.g,|
401 401 00d0: 69 d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 |i..9............|
402 402 00e0: 75 30 73 26 45 64 61 74 61 2f 30 30 63 68 61 6e |u0s&Edata/00chan|
403 403 00f0: 67 65 6c 6f 67 2d 61 62 33 34 39 31 38 30 61 30 |gelog-ab349180a0|
404 404 #endif
405 405 #if zstd no-rust
406 406 $ f --size --hex --bytes 256 body
407 body: size=116340
407 body: size=116340 (no-bigendian !)
408 body: size=116335 (bigendian !)
408 409 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
409 410 0010: 9a 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
410 411 0020: 06 09 04 0c 5e 62 79 74 65 63 6f 75 6e 74 31 30 |....^bytecount10|
411 0030: 31 32 37 36 66 69 6c 65 63 6f 75 6e 74 31 30 39 |1276filecount109|
412 0030: 31 32 37 36 66 69 6c 65 63 6f 75 6e 74 31 30 39 |1276filecount109| (no-bigendian !)
413 0030: 31 32 37 31 66 69 6c 65 63 6f 75 6e 74 31 30 39 |1271filecount109| (bigendian !)
412 414 0040: 33 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |3requirementsdot|
413 415 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache|
414 416 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%|
415 417 0070: 32 43 72 65 76 6c 6f 67 2d 63 6f 6d 70 72 65 73 |2Crevlog-compres|
416 418 0080: 73 69 6f 6e 2d 7a 73 74 64 25 32 43 72 65 76 6c |sion-zstd%2Crevl|
417 419 0090: 6f 67 76 31 25 32 43 73 70 61 72 73 65 72 65 76 |ogv1%2Csparserev|
418 420 00a0: 6c 6f 67 25 32 43 73 74 6f 72 65 00 00 80 00 73 |log%2Cstore....s|
419 421 00b0: 08 42 64 61 74 61 2f 30 2e 69 00 03 00 01 00 00 |.Bdata/0.i......|
420 422 00c0: 00 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 |................|
421 423 00d0: 00 01 ff ff ff ff ff ff ff ff 80 29 63 a0 49 d3 |...........)c.I.|
422 424 00e0: 23 87 bf ce fe 56 67 92 67 2c 69 d1 ec 39 00 00 |#....Vg.g,i..9..|
423 425 00f0: 00 00 00 00 00 00 00 00 00 00 75 30 73 26 45 64 |..........u0s&Ed|
424 426 #endif
425 427 #if zstd rust no-dirstate-v2
426 428 $ f --size --hex --bytes 256 body
427 429 body: size=116361
428 430 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
429 431 0010: af 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
430 432 0020: 06 09 04 0c 73 62 79 74 65 63 6f 75 6e 74 31 30 |....sbytecount10|
431 433 0030: 31 32 37 36 66 69 6c 65 63 6f 75 6e 74 31 30 39 |1276filecount109|
432 434 0040: 33 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |3requirementsdot|
433 435 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache|
434 436 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%|
435 437 0070: 32 43 70 65 72 73 69 73 74 65 6e 74 2d 6e 6f 64 |2Cpersistent-nod|
436 438 0080: 65 6d 61 70 25 32 43 72 65 76 6c 6f 67 2d 63 6f |emap%2Crevlog-co|
437 439 0090: 6d 70 72 65 73 73 69 6f 6e 2d 7a 73 74 64 25 32 |mpression-zstd%2|
438 440 00a0: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 72 |Crevlogv1%2Cspar|
439 441 00b0: 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 65 |serevlog%2Cstore|
440 442 00c0: 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 00 |....s.Bdata/0.i.|
441 443 00d0: 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 00 |................|
442 444 00e0: 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff 80 |................|
443 445 00f0: 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c 69 |)c.I.#....Vg.g,i|
444 446 #endif
445 447 #if zstd dirstate-v2
446 448 $ f --size --hex --bytes 256 body
447 449 body: size=109549
448 450 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
449 451 0010: c0 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
450 452 0020: 05 09 04 0c 85 62 79 74 65 63 6f 75 6e 74 39 35 |.....bytecount95|
451 453 0030: 38 39 37 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |897filecount1030|
452 454 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
453 455 0050: 6e 63 6f 64 65 25 32 43 65 78 70 2d 64 69 72 73 |ncode%2Cexp-dirs|
454 456 0060: 74 61 74 65 2d 76 32 25 32 43 66 6e 63 61 63 68 |tate-v2%2Cfncach|
455 457 0070: 65 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 |e%2Cgeneraldelta|
456 458 0080: 25 32 43 70 65 72 73 69 73 74 65 6e 74 2d 6e 6f |%2Cpersistent-no|
457 459 0090: 64 65 6d 61 70 25 32 43 72 65 76 6c 6f 67 2d 63 |demap%2Crevlog-c|
458 460 00a0: 6f 6d 70 72 65 73 73 69 6f 6e 2d 7a 73 74 64 25 |ompression-zstd%|
459 461 00b0: 32 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 |2Crevlogv1%2Cspa|
460 462 00c0: 72 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 |rserevlog%2Cstor|
461 463 00d0: 65 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 |e....s.Bdata/0.i|
462 464 00e0: 00 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 |................|
463 465 00f0: 00 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff |................|
464 466 #endif
465 467
466 468 --uncompressed is an alias to --stream
467 469
468 470 #if stream-legacy
469 471 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
470 472 streaming all changes
471 473 1090 files to transfer, 102 KB of data (no-zstd !)
472 474 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
473 475 1090 files to transfer, 98.8 KB of data (zstd !)
474 476 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
475 477 searching for changes
476 478 no changes found
477 479 #endif
478 480 #if stream-bundle2
479 481 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
480 482 streaming all changes
481 483 1093 files to transfer, 102 KB of data (no-zstd !)
482 484 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
483 485 1093 files to transfer, 98.9 KB of data (zstd !)
484 486 transferred 98.9 KB in * seconds (* */sec) (glob) (zstd !)
485 487 #endif
486 488
487 489 Clone with background file closing enabled
488 490
489 491 #if stream-legacy
490 492 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
491 493 using http://localhost:$HGPORT/
492 494 sending capabilities command
493 495 sending branchmap command
494 496 streaming all changes
495 497 sending stream_out command
496 498 1090 files to transfer, 102 KB of data (no-zstd !)
497 499 1090 files to transfer, 98.8 KB of data (zstd !)
498 500 starting 4 threads for background file closing
499 501 updating the branch cache
500 502 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
501 503 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
502 504 query 1; heads
503 505 sending batch command
504 506 searching for changes
505 507 all remote heads known locally
506 508 no changes found
507 509 sending getbundle command
508 510 bundle2-input-bundle: with-transaction
509 511 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
510 512 bundle2-input-part: "phase-heads" supported
511 513 bundle2-input-part: total payload size 24
512 514 bundle2-input-bundle: 2 parts total
513 515 checking for updated bookmarks
514 516 updating the branch cache
515 517 (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
516 518 #endif
517 519 #if stream-bundle2
518 520 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
519 521 using http://localhost:$HGPORT/
520 522 sending capabilities command
521 523 query 1; heads
522 524 sending batch command
523 525 streaming all changes
524 526 sending getbundle command
525 527 bundle2-input-bundle: with-transaction
526 528 bundle2-input-part: "stream2" (params: 3 mandatory) supported
527 529 applying stream bundle
528 530 1093 files to transfer, 102 KB of data (no-zstd !)
529 531 1093 files to transfer, 98.9 KB of data (zstd !)
530 532 starting 4 threads for background file closing
531 533 starting 4 threads for background file closing
532 534 updating the branch cache
533 535 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
534 536 bundle2-input-part: total payload size 118984 (no-zstd !)
535 537 transferred 98.9 KB in * seconds (* */sec) (glob) (zstd !)
536 bundle2-input-part: total payload size 116145 (zstd !)
538 bundle2-input-part: total payload size 116145 (zstd no-bigendian !)
539 bundle2-input-part: total payload size 116140 (zstd bigendian !)
537 540 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
538 541 bundle2-input-bundle: 2 parts total
539 542 checking for updated bookmarks
540 543 updating the branch cache
541 544 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
542 545 #endif
543 546
544 547 Cannot stream clone when there are secret changesets
545 548
546 549 $ hg -R server phase --force --secret -r tip
547 550 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
548 551 warning: stream clone requested but server has them disabled
549 552 requesting all changes
550 553 adding changesets
551 554 adding manifests
552 555 adding file changes
553 556 added 2 changesets with 1025 changes to 1025 files
554 557 new changesets 96ee1d7354c4:c17445101a72
555 558
556 559 $ killdaemons.py
557 560
558 561 Streaming of secrets can be overridden by server config
559 562
560 563 $ cd server
561 564 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
562 565 $ cat hg.pid > $DAEMON_PIDS
563 566 $ cd ..
564 567
565 568 #if stream-legacy
566 569 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
567 570 streaming all changes
568 571 1090 files to transfer, 102 KB of data (no-zstd !)
569 572 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
570 573 1090 files to transfer, 98.8 KB of data (zstd !)
571 574 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
572 575 searching for changes
573 576 no changes found
574 577 #endif
575 578 #if stream-bundle2
576 579 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
577 580 streaming all changes
578 581 1093 files to transfer, 102 KB of data (no-zstd !)
579 582 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
580 583 1093 files to transfer, 98.9 KB of data (zstd !)
581 584 transferred 98.9 KB in * seconds (* */sec) (glob) (zstd !)
582 585 #endif
583 586
584 587 $ killdaemons.py
585 588
586 589 Verify interaction between preferuncompressed and secret presence
587 590
588 591 $ cd server
589 592 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
590 593 $ cat hg.pid > $DAEMON_PIDS
591 594 $ cd ..
592 595
593 596 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
594 597 requesting all changes
595 598 adding changesets
596 599 adding manifests
597 600 adding file changes
598 601 added 2 changesets with 1025 changes to 1025 files
599 602 new changesets 96ee1d7354c4:c17445101a72
600 603
601 604 $ killdaemons.py
602 605
603 606 Clone not allowed when full bundles disabled and can't serve secrets
604 607
605 608 $ cd server
606 609 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
607 610 $ cat hg.pid > $DAEMON_PIDS
608 611 $ cd ..
609 612
610 613 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
611 614 warning: stream clone requested but server has them disabled
612 615 requesting all changes
613 616 remote: abort: server has pull-based clones disabled
614 617 abort: pull failed on remote
615 618 (remove --pull if specified or upgrade Mercurial)
616 619 [100]
617 620
618 621 Local stream clone with secrets involved
619 622 (This is just a test over behavior: if you have access to the repo's files,
620 623 there is no security so it isn't important to prevent a clone here.)
621 624
622 625 $ hg clone -U --stream server local-secret
623 626 warning: stream clone requested but server has them disabled
624 627 requesting all changes
625 628 adding changesets
626 629 adding manifests
627 630 adding file changes
628 631 added 2 changesets with 1025 changes to 1025 files
629 632 new changesets 96ee1d7354c4:c17445101a72
630 633
631 634 Stream clone while repo is changing:
632 635
633 636 $ mkdir changing
634 637 $ cd changing
635 638
636 639 extension for delaying the server process so we reliably can modify the repo
637 640 while cloning
638 641
639 642 $ cat > stream_steps.py <<EOF
640 643 > import os
641 644 > import sys
642 645 > from mercurial import (
643 646 > encoding,
644 647 > extensions,
645 648 > streamclone,
646 649 > testing,
647 650 > )
648 651 > WALKED_FILE_1 = encoding.environ[b'HG_TEST_STREAM_WALKED_FILE_1']
649 652 > WALKED_FILE_2 = encoding.environ[b'HG_TEST_STREAM_WALKED_FILE_2']
650 653 >
651 654 > def _test_sync_point_walk_1(orig, repo):
652 655 > testing.write_file(WALKED_FILE_1)
653 656 >
654 657 > def _test_sync_point_walk_2(orig, repo):
655 658 > assert repo._currentlock(repo._lockref) is None
656 659 > testing.wait_file(WALKED_FILE_2)
657 660 >
658 661 > extensions.wrapfunction(
659 662 > streamclone,
660 663 > '_test_sync_point_walk_1',
661 664 > _test_sync_point_walk_1
662 665 > )
663 666 > extensions.wrapfunction(
664 667 > streamclone,
665 668 > '_test_sync_point_walk_2',
666 669 > _test_sync_point_walk_2
667 670 > )
668 671 > EOF
669 672
670 673 prepare repo with small and big file to cover both code paths in emitrevlogdata
671 674
672 675 $ hg init repo
673 676 $ touch repo/f1
674 677 $ $TESTDIR/seq.py 50000 > repo/f2
675 678 $ hg -R repo ci -Aqm "0"
676 679 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
677 680 $ export HG_TEST_STREAM_WALKED_FILE_1
678 681 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
679 682 $ export HG_TEST_STREAM_WALKED_FILE_2
680 683 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
681 684 $ export HG_TEST_STREAM_WALKED_FILE_3
682 685 # $ cat << EOF >> $HGRCPATH
683 686 # > [hooks]
684 687 # > pre-clone=rm -f "$TESTTMP/sync_file_walked_*"
685 688 # > EOF
686 689 $ hg serve -R repo -p $HGPORT1 -d --error errors.log --pid-file=hg.pid --config extensions.stream_steps="$RUNTESTDIR/testlib/ext-stream-clone-steps.py"
687 690 $ cat hg.pid >> $DAEMON_PIDS
688 691
689 692 clone while modifying the repo between stating file with write lock and
690 693 actually serving file content
691 694
692 695 $ (hg clone -q --stream -U http://localhost:$HGPORT1 clone; touch "$HG_TEST_STREAM_WALKED_FILE_3") &
693 696 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
694 697 $ echo >> repo/f1
695 698 $ echo >> repo/f2
696 699 $ hg -R repo ci -m "1" --config ui.timeout.warn=-1
697 700 $ touch $HG_TEST_STREAM_WALKED_FILE_2
698 701 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
699 702 $ hg -R clone id
700 703 000000000000
701 704 $ cat errors.log
702 705 $ cd ..
703 706
704 707 Stream repository with bookmarks
705 708 --------------------------------
706 709
707 710 (revert introduction of secret changeset)
708 711
709 712 $ hg -R server phase --draft 'secret()'
710 713
711 714 add a bookmark
712 715
713 716 $ hg -R server bookmark -r tip some-bookmark
714 717
715 718 clone it
716 719
717 720 #if stream-legacy
718 721 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
719 722 streaming all changes
720 723 1090 files to transfer, 102 KB of data (no-zstd !)
721 724 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
722 725 1090 files to transfer, 98.8 KB of data (zstd !)
723 726 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
724 727 searching for changes
725 728 no changes found
726 729 updating to branch default
727 730 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
728 731 #endif
729 732 #if stream-bundle2
730 733 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
731 734 streaming all changes
732 735 1096 files to transfer, 102 KB of data (no-zstd !)
733 736 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
734 737 1096 files to transfer, 99.1 KB of data (zstd !)
735 738 transferred 99.1 KB in * seconds (* */sec) (glob) (zstd !)
736 739 updating to branch default
737 740 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
738 741 #endif
739 742 $ hg verify -R with-bookmarks
740 743 checking changesets
741 744 checking manifests
742 745 crosschecking files in changesets and manifests
743 746 checking files
744 747 checked 3 changesets with 1088 changes to 1088 files
745 748 $ hg -R with-bookmarks bookmarks
746 749 some-bookmark 2:5223b5e3265f
747 750
748 751 Stream repository with phases
749 752 -----------------------------
750 753
751 754 Clone as publishing
752 755
753 756 $ hg -R server phase -r 'all()'
754 757 0: draft
755 758 1: draft
756 759 2: draft
757 760
758 761 #if stream-legacy
759 762 $ hg clone --stream http://localhost:$HGPORT phase-publish
760 763 streaming all changes
761 764 1090 files to transfer, 102 KB of data (no-zstd !)
762 765 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
763 766 1090 files to transfer, 98.8 KB of data (zstd !)
764 767 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
765 768 searching for changes
766 769 no changes found
767 770 updating to branch default
768 771 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
769 772 #endif
770 773 #if stream-bundle2
771 774 $ hg clone --stream http://localhost:$HGPORT phase-publish
772 775 streaming all changes
773 776 1096 files to transfer, 102 KB of data (no-zstd !)
774 777 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
775 778 1096 files to transfer, 99.1 KB of data (zstd !)
776 779 transferred 99.1 KB in * seconds (* */sec) (glob) (zstd !)
777 780 updating to branch default
778 781 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
779 782 #endif
780 783 $ hg verify -R phase-publish
781 784 checking changesets
782 785 checking manifests
783 786 crosschecking files in changesets and manifests
784 787 checking files
785 788 checked 3 changesets with 1088 changes to 1088 files
786 789 $ hg -R phase-publish phase -r 'all()'
787 790 0: public
788 791 1: public
789 792 2: public
790 793
791 794 Clone as non publishing
792 795
793 796 $ cat << EOF >> server/.hg/hgrc
794 797 > [phases]
795 798 > publish = False
796 799 > EOF
797 800 $ killdaemons.py
798 801 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
799 802 $ cat hg.pid > $DAEMON_PIDS
800 803
801 804 #if stream-legacy
802 805
803 806 With v1 of the stream protocol, changeset are always cloned as public. It make
804 807 stream v1 unsuitable for non-publishing repository.
805 808
806 809 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
807 810 streaming all changes
808 811 1090 files to transfer, 102 KB of data (no-zstd !)
809 812 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
810 813 1090 files to transfer, 98.8 KB of data (zstd !)
811 814 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
812 815 searching for changes
813 816 no changes found
814 817 updating to branch default
815 818 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
816 819 $ hg -R phase-no-publish phase -r 'all()'
817 820 0: public
818 821 1: public
819 822 2: public
820 823 #endif
821 824 #if stream-bundle2
822 825 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
823 826 streaming all changes
824 827 1097 files to transfer, 102 KB of data (no-zstd !)
825 828 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
826 829 1097 files to transfer, 99.1 KB of data (zstd !)
827 830 transferred 99.1 KB in * seconds (* */sec) (glob) (zstd !)
828 831 updating to branch default
829 832 1088 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 833 $ hg -R phase-no-publish phase -r 'all()'
831 834 0: draft
832 835 1: draft
833 836 2: draft
834 837 #endif
835 838 $ hg verify -R phase-no-publish
836 839 checking changesets
837 840 checking manifests
838 841 crosschecking files in changesets and manifests
839 842 checking files
840 843 checked 3 changesets with 1088 changes to 1088 files
841 844
842 845 $ killdaemons.py
843 846
844 847 #if stream-legacy
845 848
846 849 With v1 of the stream protocol, changeset are always cloned as public. There's
847 850 no obsolescence markers exchange in stream v1.
848 851
849 852 #endif
850 853 #if stream-bundle2
851 854
852 855 Stream repository with obsolescence
853 856 -----------------------------------
854 857
855 858 Clone non-publishing with obsolescence
856 859
857 860 $ cat >> $HGRCPATH << EOF
858 861 > [experimental]
859 862 > evolution=all
860 863 > EOF
861 864
862 865 $ cd server
863 866 $ echo foo > foo
864 867 $ hg -q commit -m 'about to be pruned'
865 868 $ hg debugobsolete `hg log -r . -T '{node}'` -d '0 0' -u test --record-parents
866 869 1 new obsolescence markers
867 870 obsoleted 1 changesets
868 871 $ hg up null -q
869 872 $ hg log -T '{rev}: {phase}\n'
870 873 2: draft
871 874 1: draft
872 875 0: draft
873 876 $ hg serve -p $HGPORT -d --pid-file=hg.pid
874 877 $ cat hg.pid > $DAEMON_PIDS
875 878 $ cd ..
876 879
877 880 $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
878 881 streaming all changes
879 882 1098 files to transfer, 102 KB of data (no-zstd !)
880 883 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
881 884 1098 files to transfer, 99.5 KB of data (zstd !)
882 885 transferred 99.5 KB in * seconds (* */sec) (glob) (zstd !)
883 886 $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
884 887 2: draft
885 888 1: draft
886 889 0: draft
887 890 $ hg debugobsolete -R with-obsolescence
888 891 8c206a663911c1f97f2f9d7382e417ae55872cfa 0 {5223b5e3265f0df40bb743da62249413d74ac70f} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
889 892 $ hg verify -R with-obsolescence
890 893 checking changesets
891 894 checking manifests
892 895 crosschecking files in changesets and manifests
893 896 checking files
894 897 checked 4 changesets with 1089 changes to 1088 files
895 898
896 899 $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution
897 900 streaming all changes
898 901 remote: abort: server has obsolescence markers, but client cannot receive them via stream clone
899 902 abort: pull failed on remote
900 903 [100]
901 904
902 905 $ killdaemons.py
903 906
904 907 #endif
@@ -1,435 +1,441
1 1 #require no-reposimplestore
2 2
3 3 Check whether size of generaldelta revlog is not bigger than its
4 4 regular equivalent. Test would fail if generaldelta was naive
5 5 implementation of parentdelta: third manifest revision would be fully
6 6 inserted due to big distance from its paren revision (zero).
7 7
8 8 $ cat << EOF >> $HGRCPATH
9 9 > [format]
10 10 > sparse-revlog = no
11 11 > EOF
12 12
13 13 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
14 14 $ cd repo
15 15 $ echo foo > foo
16 16 $ echo bar > bar
17 17 $ echo baz > baz
18 18 $ hg commit -q -Am boo
19 19 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
20 20 $ for r in 1 2 3; do
21 21 > echo $r > foo
22 22 > hg commit -q -m $r
23 23 > hg up -q -r 0
24 24 > hg pull . -q -r $r -R ../gdrepo
25 25 > done
26 26
27 27 $ cd ..
28 28 >>> from __future__ import print_function
29 29 >>> import os
30 30 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
31 31 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
32 32 >>> if regsize < gdsize:
33 33 ... print('generaldata increased size of manifest')
34 34
35 35 Verify rev reordering doesnt create invalid bundles (issue4462)
36 36 This requires a commit tree that when pulled will reorder manifest revs such
37 37 that the second manifest to create a file rev will be ordered before the first
38 38 manifest to create that file rev. We also need to do a partial pull to ensure
39 39 reordering happens. At the end we verify the linkrev points at the earliest
40 40 commit.
41 41
42 42 $ hg init server --config format.generaldelta=True
43 43 $ cd server
44 44 $ touch a
45 45 $ hg commit -Aqm a
46 46 $ echo x > x
47 47 $ echo y > y
48 48 $ hg commit -Aqm xy
49 49 $ hg up -q '.^'
50 50 $ echo x > x
51 51 $ echo z > z
52 52 $ hg commit -Aqm xz
53 53 $ hg up -q 1
54 54 $ echo b > b
55 55 $ hg commit -Aqm b
56 56 $ hg merge -q 2
57 57 $ hg commit -Aqm merge
58 58 $ echo c > c
59 59 $ hg commit -Aqm c
60 60 $ hg log -G -T '{rev} {shortest(node)} {desc}'
61 61 @ 5 ebb8 c
62 62 |
63 63 o 4 baf7 merge
64 64 |\
65 65 | o 3 a129 b
66 66 | |
67 67 o | 2 958c xz
68 68 | |
69 69 | o 1 f00c xy
70 70 |/
71 71 o 0 3903 a
72 72
73 73 $ cd ..
74 74 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
75 75 $ cd client
76 76 $ hg pull -q ../server -r 4
77 77 $ hg debugdeltachain x
78 78 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
79 79 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
80 80
81 81 $ cd ..
82 82
83 83 Test "usegeneraldelta" config
84 84 (repo are general delta, but incoming bundle are not re-deltafied)
85 85
86 86 delta coming from the server base delta server are not recompressed.
87 87 (also include the aggressive version for comparison)
88 88
89 89 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
90 90 requesting all changes
91 91 adding changesets
92 92 adding manifests
93 93 adding file changes
94 94 added 4 changesets with 6 changes to 3 files (+2 heads)
95 95 new changesets 0ea3fcf9d01d:bba78d330d9c
96 96 updating to branch default
97 97 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 98 $ hg clone repo --pull --config format.generaldelta=1 full
99 99 requesting all changes
100 100 adding changesets
101 101 adding manifests
102 102 adding file changes
103 103 added 4 changesets with 6 changes to 3 files (+2 heads)
104 104 new changesets 0ea3fcf9d01d:bba78d330d9c
105 105 updating to branch default
106 106 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 107 $ hg -R repo debugdeltachain -m
108 108 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
109 109 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000 (no-zstd !)
110 110 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000 (no-zstd !)
111 111 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000 (no-zstd !)
112 112 0 1 1 -1 base 107 135 107 0.79259 107 0 0.00000 (zstd !)
113 113 1 1 2 0 prev 57 135 164 1.21481 164 0 0.00000 (zstd !)
114 114 2 1 3 1 prev 57 135 221 1.63704 221 0 0.00000 (zstd !)
115 115 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
116 116 $ hg -R usegd debugdeltachain -m
117 117 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
118 118 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000 (no-zstd !)
119 119 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000 (no-zstd !)
120 120 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000 (no-zstd !)
121 121 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807 (no-zstd !)
122 122 0 1 1 -1 base 107 135 107 0.79259 107 0 0.00000 (zstd !)
123 123 1 1 2 0 p1 57 135 164 1.21481 164 0 0.00000 (zstd !)
124 124 2 1 3 1 prev 57 135 221 1.63704 221 0 0.00000 (zstd !)
125 125 3 1 2 0 p1 57 135 164 1.21481 278 114 0.69512 (zstd !)
126 126 $ hg -R full debugdeltachain -m
127 127 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
128 128 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000 (no-zstd !)
129 129 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000 (no-zstd !)
130 130 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404 (no-zstd !)
131 131 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807 (no-zstd !)
132 132 0 1 1 -1 base 107 135 107 0.79259 107 0 0.00000 (zstd !)
133 133 1 1 2 0 p1 57 135 164 1.21481 164 0 0.00000 (zstd !)
134 134 2 1 2 0 p1 57 135 164 1.21481 221 57 0.34756 (zstd !)
135 135 3 1 2 0 p1 57 135 164 1.21481 278 114 0.69512 (zstd !)
136 136
137 137 Test revlog.optimize-delta-parent-choice
138 138
139 139 $ hg init --config format.generaldelta=1 aggressive
140 140 $ cd aggressive
141 141 $ cat << EOF >> .hg/hgrc
142 142 > [format]
143 143 > generaldelta = 1
144 144 > EOF
145 145 $ touch a b c d e
146 146 $ hg commit -Aqm side1
147 147 $ hg up -q null
148 148 $ touch x y
149 149 $ hg commit -Aqm side2
150 150
151 151 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
152 152 $ hg merge -q 0
153 153 $ hg commit -q -m merge
154 154 $ hg debugdeltachain -m
155 155 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
156 156 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000 (no-zstd !)
157 157 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000 (no-zstd !)
158 158 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413 (no-zstd !)
159 159 0 1 1 -1 base 68 215 68 0.31628 68 0 0.00000 (zstd !)
160 160 1 1 2 0 prev 70 86 138 1.60465 138 0 0.00000 (zstd !)
161 161 2 1 2 0 p2 68 301 136 0.45183 206 70 0.51471 (zstd !)
162 162
163 163 $ hg strip -q -r . --config extensions.strip=
164 164
165 165 - Verify aggressive merge uses p2 (commit 0) as delta parent
166 166 $ hg up -q -C 1
167 167 $ hg merge -q 0
168 168 $ hg commit -q -m merge --config storage.revlog.optimize-delta-parent-choice=yes
169 169 $ hg debugdeltachain -m
170 170 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
171 171 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000 (no-zstd !)
172 172 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000 (no-zstd !)
173 173 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413 (no-zstd !)
174 174 0 1 1 -1 base 68 215 68 0.31628 68 0 0.00000 (zstd !)
175 175 1 1 2 0 prev 70 86 138 1.60465 138 0 0.00000 (zstd !)
176 176 2 1 2 0 p2 68 301 136 0.45183 206 70 0.51471 (zstd !)
177 177
178 178 Test that strip bundle use bundle2
179 179 $ hg --config extensions.strip= strip .
180 180 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
181 181 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
182 182 $ hg debugbundle .hg/strip-backup/*
183 183 Stream params: {Compression: BZ}
184 184 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
185 185 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
186 186 cache:rev-branch-cache -- {} (mandatory: False)
187 187 phase-heads -- {} (mandatory: True)
188 188 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
189 189
190 190 $ cd ..
191 191
192 192 test maxdeltachainspan
193 193
194 194 $ hg init source-repo
195 195 $ cd source-repo
196 196 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
197 197 # add an empty revision somewhere
198 198 $ hg up tip
199 199 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 200 $ hg rm .
201 201 removing nf10
202 202 removing nf11
203 203 removing nf12
204 204 removing nf13
205 205 removing nf14
206 206 removing nf15
207 207 removing nf16
208 208 removing nf17
209 209 removing nf51
210 210 removing nf52
211 211 removing nf6
212 212 removing nf7
213 213 removing nf8
214 214 removing nf9
215 215 $ hg commit -m 'empty all'
216 216 $ hg revert --all --rev 'p1(.)'
217 217 adding nf10
218 218 adding nf11
219 219 adding nf12
220 220 adding nf13
221 221 adding nf14
222 222 adding nf15
223 223 adding nf16
224 224 adding nf17
225 225 adding nf51
226 226 adding nf52
227 227 adding nf6
228 228 adding nf7
229 229 adding nf8
230 230 adding nf9
231 231 $ hg commit -m 'restore all'
232 232 $ hg up null
233 233 0 files updated, 0 files merged, 14 files removed, 0 files unresolved
234 234 $
235 235 $ cd ..
236 236 $ hg -R source-repo debugdeltachain -m
237 237 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
238 238 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
239 239 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
240 240 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
241 241 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
242 242 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
243 243 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
244 244 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
245 245 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
246 246 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
247 247 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
248 248 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
249 249 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
250 250 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
251 251 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
252 252 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
253 253 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
254 254 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
255 255 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
256 256 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
257 257 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
258 258 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
259 259 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
260 260 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
261 261 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
262 262 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
263 263 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
264 264 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
265 265 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
266 266 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
267 267 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
268 268 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
269 269 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
270 270 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
271 271 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
272 272 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
273 273 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
274 274 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
275 275 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
276 276 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
277 277 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
278 278 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
279 279 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
280 280 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
281 281 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
282 282 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
283 283 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
284 284 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
285 285 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
286 286 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
287 287 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000 (no-zstd !)
288 288 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000 (no-zstd !)
289 289 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000 (no-zstd !)
290 290 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000 (no-zstd !)
291 291 49 4 1 -1 base 205 316 205 0.64873 205 0 0.00000 (zstd !)
292 292 50 4 2 49 p1 58 362 263 0.72652 263 0 0.00000 (zstd !)
293 51 4 3 50 prev 366 594 629 1.05892 629 0 0.00000 (zstd !)
294 52 4 4 51 p1 58 640 687 1.07344 687 0 0.00000 (zstd !)
293 51 4 3 50 prev 366 594 629 1.05892 629 0 0.00000 (zstd no-bigendian !)
294 52 4 4 51 p1 58 640 687 1.07344 687 0 0.00000 (zstd no-bigendian !)
295 51 4 3 50 prev 367 594 630 1.06061 630 0 0.00000 (zstd bigendian !)
296 52 4 4 51 p1 58 640 688 1.07500 688 0 0.00000 (zstd bigendian !)
295 297 53 5 1 -1 base 0 0 0 0.00000 0 0 0.00000
296 298 54 6 1 -1 base 369 640 369 0.57656 369 0 0.00000 (no-zstd !)
297 54 6 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd !)
299 54 6 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd no-bigendian !)
300 54 6 1 -1 base 376 640 376 0.58750 376 0 0.00000 (zstd bigendian !)
298 301 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
299 302 requesting all changes
300 303 adding changesets
301 304 adding manifests
302 305 adding file changes
303 306 added 55 changesets with 53 changes to 53 files (+2 heads)
304 307 new changesets 61246295ee1e:c930ac4a5b32
305 308 updating to branch default
306 309 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
307 310 $ hg -R relax-chain debugdeltachain -m
308 311 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
309 312 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
310 313 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
311 314 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
312 315 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
313 316 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
314 317 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
315 318 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
316 319 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
317 320 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
318 321 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
319 322 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
320 323 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
321 324 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
322 325 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
323 326 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
324 327 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
325 328 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
326 329 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
327 330 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
328 331 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
329 332 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
330 333 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
331 334 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
332 335 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
333 336 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
334 337 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
335 338 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
336 339 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
337 340 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
338 341 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
339 342 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
340 343 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
341 344 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
342 345 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
343 346 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
344 347 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
345 348 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
346 349 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
347 350 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
348 351 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
349 352 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
350 353 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
351 354 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
352 355 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
353 356 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
354 357 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
355 358 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
356 359 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
357 360 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
358 361 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000 (no-zstd !)
359 362 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000 (no-zstd !)
360 363 51 2 13 17 p1 58 594 739 1.24411 2781 2042 2.76319 (no-zstd !)
361 364 52 5 1 -1 base 369 640 369 0.57656 369 0 0.00000 (no-zstd !)
362 365 49 4 1 -1 base 205 316 205 0.64873 205 0 0.00000 (zstd !)
363 366 50 4 2 49 p1 58 362 263 0.72652 263 0 0.00000 (zstd !)
364 367 51 2 13 17 p1 58 594 739 1.24411 2789 2050 2.77402 (zstd !)
365 52 5 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd !)
368 52 5 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd no-bigendian !)
369 52 5 1 -1 base 376 640 376 0.58750 376 0 0.00000 (zstd bigendian !)
366 370 53 6 1 -1 base 0 0 0 0.00000 0 0 0.00000
367 371 54 7 1 -1 base 369 640 369 0.57656 369 0 0.00000 (no-zstd !)
368 54 7 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd !)
372 54 7 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd no-bigendian !)
373 54 7 1 -1 base 376 640 376 0.58750 376 0 0.00000 (zstd bigendian !)
369 374 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.usegeneraldelta=yes --config storage.revlog.reuse-external-delta-parent=no
370 375 requesting all changes
371 376 adding changesets
372 377 adding manifests
373 378 adding file changes
374 379 added 55 changesets with 53 changes to 53 files (+2 heads)
375 380 new changesets 61246295ee1e:c930ac4a5b32
376 381 updating to branch default
377 382 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 383 $ hg -R noconst-chain debugdeltachain -m
379 384 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
380 385 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
381 386 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
382 387 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
383 388 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
384 389 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
385 390 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
386 391 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
387 392 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
388 393 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
389 394 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
390 395 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
391 396 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
392 397 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
393 398 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
394 399 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
395 400 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
396 401 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
397 402 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
398 403 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
399 404 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
400 405 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
401 406 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
402 407 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
403 408 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
404 409 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
405 410 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
406 411 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
407 412 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
408 413 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
409 414 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
410 415 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
411 416 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
412 417 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
413 418 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
414 419 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
415 420 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
416 421 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
417 422 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
418 423 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
419 424 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
420 425 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
421 426 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
422 427 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
423 428 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
424 429 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
425 430 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
426 431 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
427 432 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
428 433 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
429 434 49 1 7 5 p1 58 316 389 1.23101 2857 2468 6.34447
430 435 50 1 8 49 p1 58 362 447 1.23481 2915 2468 5.52125
431 436 51 2 13 17 p1 58 594 739 1.24411 2642 1903 2.57510
432 437 52 2 14 51 p1 58 640 797 1.24531 2700 1903 2.38770
433 438 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
434 439 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000 (no-zstd !)
435 54 5 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd !)
440 54 5 1 -1 base 375 640 375 0.58594 375 0 0.00000 (zstd no-bigendian !)
441 54 5 1 -1 base 376 640 376 0.58750 376 0 0.00000 (zstd bigendian !)
@@ -1,1256 +1,1262
1 1 ===================================
2 2 Test the persistent on-disk nodemap
3 3 ===================================
4 4
5 5
6 6 $ cat << EOF >> $HGRCPATH
7 7 > [format]
8 8 > use-share-safe=yes
9 9 > [extensions]
10 10 > share=
11 11 > EOF
12 12
13 13 #if no-rust
14 14
15 15 $ cat << EOF >> $HGRCPATH
16 16 > [format]
17 17 > use-persistent-nodemap=yes
18 18 > [devel]
19 19 > persistent-nodemap=yes
20 20 > EOF
21 21
22 22 #endif
23 23
24 24 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
25 25 $ cd test-repo
26 26
27 27 Check handling of the default slow-path value
28 28
29 29 #if no-pure no-rust
30 30
31 31 $ hg id
32 32 abort: accessing `persistent-nodemap` repository without associated fast implementation.
33 33 (check `hg help config.format.use-persistent-nodemap` for details)
34 34 [255]
35 35
36 36 Unlock further check (we are here to test the feature)
37 37
38 38 $ cat << EOF >> $HGRCPATH
39 39 > [storage]
40 40 > # to avoid spamming the test
41 41 > revlog.persistent-nodemap.slow-path=allow
42 42 > EOF
43 43
44 44 #endif
45 45
46 46 #if rust
47 47
48 48 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
49 49 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
50 50 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
51 51 incorrectly used `libc::c_int` (32 bits).
52 52 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
53 53
54 54 $ hg log -r 00000000
55 55 changeset: -1:000000000000
56 56 tag: tip
57 57 user:
58 58 date: Thu Jan 01 00:00:00 1970 +0000
59 59
60 60
61 61 #endif
62 62
63 63
64 64 $ hg debugformat
65 65 format-variant repo
66 66 fncache: yes
67 67 dirstate-v2: no
68 68 dotencode: yes
69 69 generaldelta: yes
70 70 share-safe: yes
71 71 sparserevlog: yes
72 72 persistent-nodemap: yes
73 73 copies-sdc: no
74 74 revlog-v2: no
75 75 changelog-v2: no
76 76 plain-cl-delta: yes
77 77 compression: zlib (no-zstd !)
78 78 compression: zstd (zstd !)
79 79 compression-level: default
80 80 $ hg debugbuilddag .+5000 --new-file
81 81
82 82 $ hg debugnodemap --metadata
83 83 uid: ???????? (glob)
84 84 tip-rev: 5000
85 85 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
86 86 data-length: 121088
87 87 data-unused: 0
88 88 data-unused: 0.000%
89 89 $ f --size .hg/store/00changelog.n
90 90 .hg/store/00changelog.n: size=62
91 91
92 92 Simple lookup works
93 93
94 94 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
95 95 $ hg log -r "$ANYNODE" --template '{rev}\n'
96 96 5000
97 97
98 98
99 99 #if rust
100 100
101 101 $ f --sha256 .hg/store/00changelog-*.nd
102 102 .hg/store/00changelog-????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
103 103
104 104 $ f --sha256 .hg/store/00manifest-*.nd
105 105 .hg/store/00manifest-????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
106 106 $ hg debugnodemap --dump-new | f --sha256 --size
107 107 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
108 108 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
109 109 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
110 110 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
111 111 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
112 112 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
113 113 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
114 114 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
115 115 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
116 116 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
117 117 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
118 118 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
119 119 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
120 120 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
121 121 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
122 122 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
123 123 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
124 124 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
125 125 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
126 126
127 127
128 128 #else
129 129
130 130 $ f --sha256 .hg/store/00changelog-*.nd
131 131 .hg/store/00changelog-????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
132 132 $ hg debugnodemap --dump-new | f --sha256 --size
133 133 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
134 134 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
135 135 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
136 136 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
137 137 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
138 138 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
139 139 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
140 140 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
141 141 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
142 142 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
143 143 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
144 144 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
145 145 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
146 146 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
147 147 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
148 148 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
149 149 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
150 150 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
151 151 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
152 152
153 153 #endif
154 154
155 155 $ hg debugnodemap --check
156 156 revision in index: 5001
157 157 revision in nodemap: 5001
158 158
159 159 add a new commit
160 160
161 161 $ hg up
162 162 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 163 $ echo foo > foo
164 164 $ hg add foo
165 165
166 166
167 167 Check slow-path config value handling
168 168 -------------------------------------
169 169
170 170 #if no-pure no-rust
171 171
172 172 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
173 173 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
174 174 falling back to default value: abort
175 175 abort: accessing `persistent-nodemap` repository without associated fast implementation.
176 176 (check `hg help config.format.use-persistent-nodemap` for details)
177 177 [255]
178 178
179 179 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
180 180 warning: accessing `persistent-nodemap` repository without associated fast implementation.
181 181 (check `hg help config.format.use-persistent-nodemap` for details)
182 182 changeset: 5000:6b02b8c7b966
183 183 tag: tip
184 184 user: debugbuilddag
185 185 date: Thu Jan 01 01:23:20 1970 +0000
186 186 summary: r5000
187 187
188 188 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
189 189 abort: accessing `persistent-nodemap` repository without associated fast implementation.
190 190 (check `hg help config.format.use-persistent-nodemap` for details)
191 191 [255]
192 192
193 193 #else
194 194
195 195 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
196 196 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
197 197 falling back to default value: abort
198 198 6b02b8c7b966+ tip
199 199
200 200 #endif
201 201
202 202 $ hg ci -m 'foo'
203 203
204 204 #if no-pure no-rust
205 205 $ hg debugnodemap --metadata
206 206 uid: ???????? (glob)
207 207 tip-rev: 5001
208 208 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
209 209 data-length: 121088
210 210 data-unused: 0
211 211 data-unused: 0.000%
212 212 #else
213 213 $ hg debugnodemap --metadata
214 214 uid: ???????? (glob)
215 215 tip-rev: 5001
216 216 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
217 217 data-length: 121344
218 218 data-unused: 256
219 219 data-unused: 0.211%
220 220 #endif
221 221
222 222 $ f --size .hg/store/00changelog.n
223 223 .hg/store/00changelog.n: size=62
224 224
225 225 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
226 226
227 227 #if pure
228 228 $ f --sha256 .hg/store/00changelog-*.nd --size
229 229 .hg/store/00changelog-????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
230 230 #endif
231 231
232 232 #if rust
233 233 $ f --sha256 .hg/store/00changelog-*.nd --size
234 234 .hg/store/00changelog-????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
235 235 #endif
236 236
237 237 #if no-pure no-rust
238 238 $ f --sha256 .hg/store/00changelog-*.nd --size
239 239 .hg/store/00changelog-????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
240 240 #endif
241 241
242 242 $ hg debugnodemap --check
243 243 revision in index: 5002
244 244 revision in nodemap: 5002
245 245
246 246 Test code path without mmap
247 247 ---------------------------
248 248
249 249 $ echo bar > bar
250 250 $ hg add bar
251 251 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
252 252
253 253 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
254 254 revision in index: 5003
255 255 revision in nodemap: 5003
256 256 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
257 257 revision in index: 5003
258 258 revision in nodemap: 5003
259 259
260 260
261 261 #if pure
262 262 $ hg debugnodemap --metadata
263 263 uid: ???????? (glob)
264 264 tip-rev: 5002
265 265 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
266 266 data-length: 121600
267 267 data-unused: 512
268 268 data-unused: 0.421%
269 269 $ f --sha256 .hg/store/00changelog-*.nd --size
270 270 .hg/store/00changelog-????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
271 271 #endif
272 272 #if rust
273 273 $ hg debugnodemap --metadata
274 274 uid: ???????? (glob)
275 275 tip-rev: 5002
276 276 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
277 277 data-length: 121600
278 278 data-unused: 512
279 279 data-unused: 0.421%
280 280 $ f --sha256 .hg/store/00changelog-*.nd --size
281 281 .hg/store/00changelog-????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
282 282 #endif
283 283 #if no-pure no-rust
284 284 $ hg debugnodemap --metadata
285 285 uid: ???????? (glob)
286 286 tip-rev: 5002
287 287 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
288 288 data-length: 121088
289 289 data-unused: 0
290 290 data-unused: 0.000%
291 291 $ f --sha256 .hg/store/00changelog-*.nd --size
292 292 .hg/store/00changelog-????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
293 293 #endif
294 294
295 295 Test force warming the cache
296 296
297 297 $ rm .hg/store/00changelog.n
298 298 $ hg debugnodemap --metadata
299 299 $ hg debugupdatecache
300 300 #if pure
301 301 $ hg debugnodemap --metadata
302 302 uid: ???????? (glob)
303 303 tip-rev: 5002
304 304 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
305 305 data-length: 121088
306 306 data-unused: 0
307 307 data-unused: 0.000%
308 308 #else
309 309 $ hg debugnodemap --metadata
310 310 uid: ???????? (glob)
311 311 tip-rev: 5002
312 312 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
313 313 data-length: 121088
314 314 data-unused: 0
315 315 data-unused: 0.000%
316 316 #endif
317 317
318 318 Check out of sync nodemap
319 319 =========================
320 320
321 321 First copy old data on the side.
322 322
323 323 $ mkdir ../tmp-copies
324 324 $ cp .hg/store/00changelog-????????.nd .hg/store/00changelog.n ../tmp-copies
325 325
326 326 Nodemap lagging behind
327 327 ----------------------
328 328
329 329 make a new commit
330 330
331 331 $ echo bar2 > bar
332 332 $ hg ci -m 'bar2'
333 333 $ NODE=`hg log -r tip -T '{node}\n'`
334 334 $ hg log -r "$NODE" -T '{rev}\n'
335 335 5003
336 336
337 337 If the nodemap is lagging behind, it can catch up fine
338 338
339 339 $ hg debugnodemap --metadata
340 340 uid: ???????? (glob)
341 341 tip-rev: 5003
342 342 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
343 343 data-length: 121344 (pure !)
344 344 data-length: 121344 (rust !)
345 345 data-length: 121152 (no-rust no-pure !)
346 346 data-unused: 192 (pure !)
347 347 data-unused: 192 (rust !)
348 348 data-unused: 0 (no-rust no-pure !)
349 349 data-unused: 0.158% (pure !)
350 350 data-unused: 0.158% (rust !)
351 351 data-unused: 0.000% (no-rust no-pure !)
352 352 $ cp -f ../tmp-copies/* .hg/store/
353 353 $ hg debugnodemap --metadata
354 354 uid: ???????? (glob)
355 355 tip-rev: 5002
356 356 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
357 357 data-length: 121088
358 358 data-unused: 0
359 359 data-unused: 0.000%
360 360 $ hg log -r "$NODE" -T '{rev}\n'
361 361 5003
362 362
363 363 changelog altered
364 364 -----------------
365 365
366 366 If the nodemap is not gated behind a requirements, an unaware client can alter
367 367 the repository so the revlog used to generate the nodemap is not longer
368 368 compatible with the persistent nodemap. We need to detect that.
369 369
370 370 $ hg up "$NODE~5"
371 371 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
372 372 $ echo bar > babar
373 373 $ hg add babar
374 374 $ hg ci -m 'babar'
375 375 created new head
376 376 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
377 377 $ hg log -r "$OTHERNODE" -T '{rev}\n'
378 378 5004
379 379
380 380 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
381 381
382 382 the nodemap should detect the changelog have been tampered with and recover.
383 383
384 384 $ hg debugnodemap --metadata
385 385 uid: ???????? (glob)
386 386 tip-rev: 5002
387 387 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
388 388 data-length: 121536 (pure !)
389 389 data-length: 121088 (rust !)
390 390 data-length: 121088 (no-pure no-rust !)
391 391 data-unused: 448 (pure !)
392 392 data-unused: 0 (rust !)
393 393 data-unused: 0 (no-pure no-rust !)
394 394 data-unused: 0.000% (rust !)
395 395 data-unused: 0.369% (pure !)
396 396 data-unused: 0.000% (no-pure no-rust !)
397 397
398 398 $ cp -f ../tmp-copies/* .hg/store/
399 399 $ hg debugnodemap --metadata
400 400 uid: ???????? (glob)
401 401 tip-rev: 5002
402 402 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
403 403 data-length: 121088
404 404 data-unused: 0
405 405 data-unused: 0.000%
406 406 $ hg log -r "$OTHERNODE" -T '{rev}\n'
407 407 5002
408 408
409 409 missing data file
410 410 -----------------
411 411
412 412 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
413 413 > sed 's/uid: //'`
414 414 $ FILE=.hg/store/00changelog-"${UUID}".nd
415 415 $ mv $FILE ../tmp-data-file
416 416 $ cp .hg/store/00changelog.n ../tmp-docket
417 417
418 418 mercurial don't crash
419 419
420 420 $ hg log -r .
421 421 changeset: 5002:b355ef8adce0
422 422 tag: tip
423 423 parent: 4998:d918ad6d18d3
424 424 user: test
425 425 date: Thu Jan 01 00:00:00 1970 +0000
426 426 summary: babar
427 427
428 428 $ hg debugnodemap --metadata
429 429
430 430 $ hg debugupdatecache
431 431 $ hg debugnodemap --metadata
432 432 uid: * (glob)
433 433 tip-rev: 5002
434 434 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
435 435 data-length: 121088
436 436 data-unused: 0
437 437 data-unused: 0.000%
438 438 $ mv ../tmp-data-file $FILE
439 439 $ mv ../tmp-docket .hg/store/00changelog.n
440 440
441 441 Check transaction related property
442 442 ==================================
443 443
444 444 An up to date nodemap should be available to shell hooks,
445 445
446 446 $ echo dsljfl > a
447 447 $ hg add a
448 448 $ hg ci -m a
449 449 $ hg debugnodemap --metadata
450 450 uid: ???????? (glob)
451 451 tip-rev: 5003
452 452 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
453 453 data-length: 121088
454 454 data-unused: 0
455 455 data-unused: 0.000%
456 456 $ echo babar2 > babar
457 457 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
458 458 uid: ???????? (glob)
459 459 tip-rev: 5004
460 460 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
461 461 data-length: 121280 (pure !)
462 462 data-length: 121280 (rust !)
463 463 data-length: 121088 (no-pure no-rust !)
464 464 data-unused: 192 (pure !)
465 465 data-unused: 192 (rust !)
466 466 data-unused: 0 (no-pure no-rust !)
467 467 data-unused: 0.158% (pure !)
468 468 data-unused: 0.158% (rust !)
469 469 data-unused: 0.000% (no-pure no-rust !)
470 470 $ hg debugnodemap --metadata
471 471 uid: ???????? (glob)
472 472 tip-rev: 5004
473 473 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
474 474 data-length: 121280 (pure !)
475 475 data-length: 121280 (rust !)
476 476 data-length: 121088 (no-pure no-rust !)
477 477 data-unused: 192 (pure !)
478 478 data-unused: 192 (rust !)
479 479 data-unused: 0 (no-pure no-rust !)
480 480 data-unused: 0.158% (pure !)
481 481 data-unused: 0.158% (rust !)
482 482 data-unused: 0.000% (no-pure no-rust !)
483 483
484 484 Another process does not see the pending nodemap content during run.
485 485
486 486 $ echo qpoasp > a
487 487 $ hg ci -m a2 \
488 488 > --config "hooks.pretxnclose=sh \"$RUNTESTDIR/testlib/wait-on-file\" 20 sync-repo-read sync-txn-pending" \
489 489 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
490 490
491 491 (read the repository while the commit transaction is pending)
492 492
493 493 $ sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-pending && \
494 494 > hg debugnodemap --metadata && \
495 495 > sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-close sync-repo-read
496 496 uid: ???????? (glob)
497 497 tip-rev: 5004
498 498 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
499 499 data-length: 121280 (pure !)
500 500 data-length: 121280 (rust !)
501 501 data-length: 121088 (no-pure no-rust !)
502 502 data-unused: 192 (pure !)
503 503 data-unused: 192 (rust !)
504 504 data-unused: 0 (no-pure no-rust !)
505 505 data-unused: 0.158% (pure !)
506 506 data-unused: 0.158% (rust !)
507 507 data-unused: 0.000% (no-pure no-rust !)
508 508 $ hg debugnodemap --metadata
509 509 uid: ???????? (glob)
510 510 tip-rev: 5005
511 511 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
512 512 data-length: 121536 (pure !)
513 513 data-length: 121536 (rust !)
514 514 data-length: 121088 (no-pure no-rust !)
515 515 data-unused: 448 (pure !)
516 516 data-unused: 448 (rust !)
517 517 data-unused: 0 (no-pure no-rust !)
518 518 data-unused: 0.369% (pure !)
519 519 data-unused: 0.369% (rust !)
520 520 data-unused: 0.000% (no-pure no-rust !)
521 521
522 522 $ cat output.txt
523 523
524 524 Check that a failing transaction will properly revert the data
525 525
526 526 $ echo plakfe > a
527 527 $ f --size --sha256 .hg/store/00changelog-*.nd
528 528 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
529 529 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
530 530 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
531 531 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
532 532 transaction abort!
533 533 rollback completed
534 534 abort: This is a late abort
535 535 [255]
536 536 $ hg debugnodemap --metadata
537 537 uid: ???????? (glob)
538 538 tip-rev: 5005
539 539 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
540 540 data-length: 121536 (pure !)
541 541 data-length: 121536 (rust !)
542 542 data-length: 121088 (no-pure no-rust !)
543 543 data-unused: 448 (pure !)
544 544 data-unused: 448 (rust !)
545 545 data-unused: 0 (no-pure no-rust !)
546 546 data-unused: 0.369% (pure !)
547 547 data-unused: 0.369% (rust !)
548 548 data-unused: 0.000% (no-pure no-rust !)
549 549 $ f --size --sha256 .hg/store/00changelog-*.nd
550 550 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
551 551 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
552 552 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
553 553
554 554 Check that removing content does not confuse the nodemap
555 555 --------------------------------------------------------
556 556
557 557 removing data with rollback
558 558
559 559 $ echo aso > a
560 560 $ hg ci -m a4
561 561 $ hg rollback
562 562 repository tip rolled back to revision 5005 (undo commit)
563 563 working directory now based on revision 5005
564 564 $ hg id -r .
565 565 90d5d3ba2fc4 tip
566 566
567 567 removing data with strip
568 568
569 569 $ echo aso > a
570 570 $ hg ci -m a4
571 571 $ hg --config extensions.strip= strip -r . --no-backup
572 572 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
573 573 $ hg id -r . --traceback
574 574 90d5d3ba2fc4 tip
575 575
576 576 (be a good citizen and regenerate the nodemap)
577 577 $ hg debugupdatecaches
578 578 $ hg debugnodemap --metadata
579 579 uid: * (glob)
580 580 tip-rev: 5005
581 581 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
582 582 data-length: 121088
583 583 data-unused: 0
584 584 data-unused: 0.000%
585 585
586 586 Check race condition when multiple process write new data to the repository
587 587 ---------------------------------------------------------------------------
588 588
589 589 In this test, we check that two writers touching the repositories will not
590 590 overwrite each other data. This test is prompted by the existent of issue6554.
591 591 Where a writer ended up using and outdated docket to update the repository. See
592 592 the dedicated extension for details on the race windows and read/write schedule
593 593 necessary to end up in this situation: testlib/persistent-nodemap-race-ext.py
594 594
595 595 The issue was initially observed on a server with a high push trafic, but it
596 596 can be reproduced using a share and two commiting process which seems simpler.
597 597
598 598 The test is Rust only as the other implementation does not use the same
599 599 read/write patterns.
600 600
601 601 $ cd ..
602 602
603 603 #if rust
604 604
605 605 $ cp -R test-repo race-repo
606 606 $ hg share race-repo ./other-wc --config format.use-share-safe=yes
607 607 updating working directory
608 608 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
609 609 $ hg debugformat -R ./race-repo | egrep 'share-safe|persistent-nodemap'
610 610 share-safe: yes
611 611 persistent-nodemap: yes
612 612 $ hg debugformat -R ./other-wc/ | egrep 'share-safe|persistent-nodemap'
613 613 share-safe: yes
614 614 persistent-nodemap: yes
615 615 $ hg -R ./other-wc update 'min(head())'
616 616 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
617 617 $ hg -R ./race-repo debugnodemap --metadata
618 618 uid: 43c37dde
619 619 tip-rev: 5005
620 620 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
621 621 data-length: 121088
622 622 data-unused: 0
623 623 data-unused: 0.000%
624 624 $ hg -R ./race-repo log -G -r 'head()'
625 625 @ changeset: 5005:90d5d3ba2fc4
626 626 | tag: tip
627 627 ~ user: test
628 628 date: Thu Jan 01 00:00:00 1970 +0000
629 629 summary: a2
630 630
631 631 o changeset: 5001:16395c3cf7e2
632 632 | user: test
633 633 ~ date: Thu Jan 01 00:00:00 1970 +0000
634 634 summary: foo
635 635
636 636 $ hg -R ./other-wc log -G -r 'head()'
637 637 o changeset: 5005:90d5d3ba2fc4
638 638 | tag: tip
639 639 ~ user: test
640 640 date: Thu Jan 01 00:00:00 1970 +0000
641 641 summary: a2
642 642
643 643 @ changeset: 5001:16395c3cf7e2
644 644 | user: test
645 645 ~ date: Thu Jan 01 00:00:00 1970 +0000
646 646 summary: foo
647 647
648 648 $ echo left-side-race > race-repo/left-side-race
649 649 $ hg -R ./race-repo/ add race-repo/left-side-race
650 650
651 651 $ echo right-side-race > ./other-wc/right-side-race
652 652 $ hg -R ./other-wc/ add ./other-wc/right-side-race
653 653
654 654 $ mkdir sync-files
655 655 $ mkdir outputs
656 656 $ (
657 657 > hg -R ./race-repo/ commit -m left-side-commit \
658 658 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
659 659 > --config 'devel.nodemap-race.role=left';
660 660 > touch sync-files/left-done
661 661 > ) > outputs/left.txt 2>&1 &
662 662 $ (
663 663 > hg -R ./other-wc/ commit -m right-side-commit \
664 664 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
665 665 > --config 'devel.nodemap-race.role=right';
666 666 > touch sync-files/right-done
667 667 > ) > outputs/right.txt 2>&1 &
668 668 $ (
669 669 > hg -R ./race-repo/ check-nodemap-race \
670 670 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
671 671 > --config 'devel.nodemap-race.role=reader';
672 672 > touch sync-files/reader-done
673 673 > ) > outputs/reader.txt 2>&1 &
674 674 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/left-done
675 675 $ cat outputs/left.txt
676 676 docket-details:
677 677 uid: 43c37dde
678 678 actual-tip: 5005
679 679 tip-rev: 5005
680 680 data-length: 121088
681 681 nodemap-race: left side locked and ready to commit
682 682 docket-details:
683 683 uid: 43c37dde
684 684 actual-tip: 5005
685 685 tip-rev: 5005
686 686 data-length: 121088
687 687 finalized changelog write
688 688 persisting changelog nodemap
689 689 new data start at 121088
690 690 persisted changelog nodemap
691 691 docket-details:
692 692 uid: 43c37dde
693 693 actual-tip: 5006
694 694 tip-rev: 5006
695 695 data-length: 121280
696 696 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/right-done
697 697 $ cat outputs/right.txt
698 698 nodemap-race: right side start of the locking sequence
699 699 nodemap-race: right side reading changelog
700 700 nodemap-race: right side reading of changelog is done
701 701 docket-details:
702 702 uid: 43c37dde
703 703 actual-tip: 5006
704 704 tip-rev: 5005
705 705 data-length: 121088
706 706 nodemap-race: right side ready to wait for the lock
707 707 nodemap-race: right side locked and ready to commit
708 708 docket-details:
709 709 uid: 43c37dde
710 710 actual-tip: 5006
711 711 tip-rev: 5006
712 712 data-length: 121280
713 713 right ready to write, waiting for reader
714 714 right proceeding with writing its changelog index and nodemap
715 715 finalized changelog write
716 716 persisting changelog nodemap
717 717 new data start at 121280
718 718 persisted changelog nodemap
719 719 docket-details:
720 720 uid: 43c37dde
721 721 actual-tip: 5007
722 722 tip-rev: 5007
723 723 data-length: 121536
724 724 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/reader-done
725 725 $ cat outputs/reader.txt
726 726 reader: reading changelog
727 727 reader ready to read the changelog, waiting for right
728 728 reader: nodemap docket read
729 729 record-data-length: 121280
730 730 actual-data-length: 121280
731 731 file-actual-length: 121536
732 732 reader: changelog read
733 733 docket-details:
734 734 uid: 43c37dde
735 735 actual-tip: 5006
736 736 tip-rev: 5006
737 737 data-length: 121280
738 738 tip-rev: 5006
739 739 tip-node: 492901161367
740 740 node-rev: 5006
741 741
742 742 $ hg -R ./race-repo log -G -r 'head()'
743 743 o changeset: 5007:ac4a2abde241
744 744 | tag: tip
745 745 ~ parent: 5001:16395c3cf7e2
746 746 user: test
747 747 date: Thu Jan 01 00:00:00 1970 +0000
748 748 summary: right-side-commit
749 749
750 750 @ changeset: 5006:492901161367
751 751 | user: test
752 752 ~ date: Thu Jan 01 00:00:00 1970 +0000
753 753 summary: left-side-commit
754 754
755 755 $ hg -R ./other-wc log -G -r 'head()'
756 756 @ changeset: 5007:ac4a2abde241
757 757 | tag: tip
758 758 ~ parent: 5001:16395c3cf7e2
759 759 user: test
760 760 date: Thu Jan 01 00:00:00 1970 +0000
761 761 summary: right-side-commit
762 762
763 763 o changeset: 5006:492901161367
764 764 | user: test
765 765 ~ date: Thu Jan 01 00:00:00 1970 +0000
766 766 summary: left-side-commit
767 767
768 768 #endif
769 769
770 770 Test upgrade / downgrade
771 771 ========================
772 772
773 773 $ cd ./test-repo/
774 774
775 775 downgrading
776 776
777 777 $ cat << EOF >> .hg/hgrc
778 778 > [format]
779 779 > use-persistent-nodemap=no
780 780 > EOF
781 781 $ hg debugformat -v
782 782 format-variant repo config default
783 783 fncache: yes yes yes
784 784 dirstate-v2: no no no
785 785 dotencode: yes yes yes
786 786 generaldelta: yes yes yes
787 787 share-safe: yes yes no
788 788 sparserevlog: yes yes yes
789 789 persistent-nodemap: yes no no
790 790 copies-sdc: no no no
791 791 revlog-v2: no no no
792 792 changelog-v2: no no no
793 793 plain-cl-delta: yes yes yes
794 794 compression: zlib zlib zlib (no-zstd !)
795 795 compression: zstd zstd zstd (zstd !)
796 796 compression-level: default default default
797 797 $ hg debugupgraderepo --run --no-backup --quiet
798 798 upgrade will perform the following actions:
799 799
800 800 requirements
801 801 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
802 802 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
803 803 preserved: dotencode, exp-rc-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
804 804 removed: persistent-nodemap
805 805
806 806 processed revlogs:
807 807 - all-filelogs
808 808 - changelog
809 809 - manifest
810 810
811 811 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
812 812 00changelog-*.nd (glob)
813 813 00manifest-*.nd (glob)
814 814 undo.backup.00changelog.n
815 815 undo.backup.00manifest.n
816 816 $ hg debugnodemap --metadata
817 817
818 818
819 819 upgrading
820 820
821 821 $ cat << EOF >> .hg/hgrc
822 822 > [format]
823 823 > use-persistent-nodemap=yes
824 824 > EOF
825 825 $ hg debugformat -v
826 826 format-variant repo config default
827 827 fncache: yes yes yes
828 828 dirstate-v2: no no no
829 829 dotencode: yes yes yes
830 830 generaldelta: yes yes yes
831 831 share-safe: yes yes no
832 832 sparserevlog: yes yes yes
833 833 persistent-nodemap: no yes no
834 834 copies-sdc: no no no
835 835 revlog-v2: no no no
836 836 changelog-v2: no no no
837 837 plain-cl-delta: yes yes yes
838 838 compression: zlib zlib zlib (no-zstd !)
839 839 compression: zstd zstd zstd (zstd !)
840 840 compression-level: default default default
841 841 $ hg debugupgraderepo --run --no-backup --quiet
842 842 upgrade will perform the following actions:
843 843
844 844 requirements
845 845 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
846 846 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
847 847 preserved: dotencode, exp-rc-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
848 848 added: persistent-nodemap
849 849
850 850 processed revlogs:
851 851 - all-filelogs
852 852 - changelog
853 853 - manifest
854 854
855 855 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
856 856 00changelog-*.nd (glob)
857 857 00changelog.n
858 858 00manifest-*.nd (glob)
859 859 00manifest.n
860 860 undo.backup.00changelog.n
861 861 undo.backup.00manifest.n
862 862
863 863 $ hg debugnodemap --metadata
864 864 uid: * (glob)
865 865 tip-rev: 5005
866 866 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
867 867 data-length: 121088
868 868 data-unused: 0
869 869 data-unused: 0.000%
870 870
871 871 Running unrelated upgrade
872 872
873 873 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
874 874 upgrade will perform the following actions:
875 875
876 876 requirements
877 877 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
878 878 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
879 879 preserved: dotencode, exp-rc-dirstate-v2, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
880 880
881 881 optimisations: re-delta-all
882 882
883 883 processed revlogs:
884 884 - all-filelogs
885 885 - changelog
886 886 - manifest
887 887
888 888 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
889 889 00changelog-*.nd (glob)
890 890 00changelog.n
891 891 00manifest-*.nd (glob)
892 892 00manifest.n
893 893
894 894 $ hg debugnodemap --metadata
895 895 uid: * (glob)
896 896 tip-rev: 5005
897 897 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
898 898 data-length: 121088
899 899 data-unused: 0
900 900 data-unused: 0.000%
901 901
902 902 Persistent nodemap and local/streaming clone
903 903 ============================================
904 904
905 905 $ cd ..
906 906
907 907 standard clone
908 908 --------------
909 909
910 910 The persistent nodemap should exist after a streaming clone
911 911
912 912 $ hg clone --pull --quiet -U test-repo standard-clone
913 913 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
914 914 00changelog-*.nd (glob)
915 915 00changelog.n
916 916 00manifest-*.nd (glob)
917 917 00manifest.n
918 918 $ hg -R standard-clone debugnodemap --metadata
919 919 uid: * (glob)
920 920 tip-rev: 5005
921 921 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
922 922 data-length: 121088
923 923 data-unused: 0
924 924 data-unused: 0.000%
925 925
926 926
927 927 local clone
928 928 ------------
929 929
930 930 The persistent nodemap should exist after a streaming clone
931 931
932 932 $ hg clone -U test-repo local-clone
933 933 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
934 934 00changelog-*.nd (glob)
935 935 00changelog.n
936 936 00manifest-*.nd (glob)
937 937 00manifest.n
938 938 $ hg -R local-clone debugnodemap --metadata
939 939 uid: * (glob)
940 940 tip-rev: 5005
941 941 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
942 942 data-length: 121088
943 943 data-unused: 0
944 944 data-unused: 0.000%
945 945
946 946 Test various corruption case
947 947 ============================
948 948
949 949 Missing datafile
950 950 ----------------
951 951
952 952 Test behavior with a missing datafile
953 953
954 954 $ hg clone --quiet --pull test-repo corruption-test-repo
955 955 $ ls -1 corruption-test-repo/.hg/store/00changelog*
956 956 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
957 957 corruption-test-repo/.hg/store/00changelog.d
958 958 corruption-test-repo/.hg/store/00changelog.i
959 959 corruption-test-repo/.hg/store/00changelog.n
960 960 $ rm corruption-test-repo/.hg/store/00changelog*.nd
961 961 $ hg log -R corruption-test-repo -r .
962 962 changeset: 5005:90d5d3ba2fc4
963 963 tag: tip
964 964 user: test
965 965 date: Thu Jan 01 00:00:00 1970 +0000
966 966 summary: a2
967 967
968 968 $ ls -1 corruption-test-repo/.hg/store/00changelog*
969 969 corruption-test-repo/.hg/store/00changelog.d
970 970 corruption-test-repo/.hg/store/00changelog.i
971 971 corruption-test-repo/.hg/store/00changelog.n
972 972
973 973 Truncated data file
974 974 -------------------
975 975
976 976 Test behavior with a too short datafile
977 977
978 978 rebuild the missing data
979 979 $ hg -R corruption-test-repo debugupdatecache
980 980 $ ls -1 corruption-test-repo/.hg/store/00changelog*
981 981 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
982 982 corruption-test-repo/.hg/store/00changelog.d
983 983 corruption-test-repo/.hg/store/00changelog.i
984 984 corruption-test-repo/.hg/store/00changelog.n
985 985
986 986 truncate the file
987 987
988 988 $ datafilepath=`ls corruption-test-repo/.hg/store/00changelog*.nd`
989 989 $ f -s $datafilepath
990 990 corruption-test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
991 991 $ dd if=$datafilepath bs=1000 count=10 of=$datafilepath-tmp
992 992 10+0 records in
993 993 10+0 records out
994 994 * bytes * (glob)
995 995 $ mv $datafilepath-tmp $datafilepath
996 996 $ f -s $datafilepath
997 997 corruption-test-repo/.hg/store/00changelog-*.nd: size=10000 (glob)
998 998
999 999 Check that Mercurial reaction to this event
1000 1000
1001 1001 $ hg -R corruption-test-repo log -r . --traceback
1002 1002 changeset: 5005:90d5d3ba2fc4
1003 1003 tag: tip
1004 1004 user: test
1005 1005 date: Thu Jan 01 00:00:00 1970 +0000
1006 1006 summary: a2
1007 1007
1008 1008
1009 1009
1010 1010 stream clone
1011 1011 ============
1012 1012
1013 1013 The persistent nodemap should exist after a streaming clone
1014 1014
1015 1015 Simple case
1016 1016 -----------
1017 1017
1018 1018 No race condition
1019 1019
1020 1020 $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
1021 1021 adding [s] 00manifest.n (62 bytes)
1022 1022 adding [s] 00manifest-*.nd (118 KB) (glob)
1023 1023 adding [s] 00changelog.n (62 bytes)
1024 1024 adding [s] 00changelog-*.nd (118 KB) (glob)
1025 1025 adding [s] 00manifest.d (452 KB) (no-zstd !)
1026 adding [s] 00manifest.d (491 KB) (zstd !)
1026 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1027 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1027 1028 adding [s] 00changelog.d (360 KB) (no-zstd !)
1028 1029 adding [s] 00changelog.d (368 KB) (zstd !)
1029 1030 adding [s] 00manifest.i (313 KB)
1030 1031 adding [s] 00changelog.i (313 KB)
1031 1032 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
1032 1033 00changelog-*.nd (glob)
1033 1034 00changelog.n
1034 1035 00manifest-*.nd (glob)
1035 1036 00manifest.n
1036 1037 $ hg -R stream-clone debugnodemap --metadata
1037 1038 uid: * (glob)
1038 1039 tip-rev: 5005
1039 1040 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1040 1041 data-length: 121088
1041 1042 data-unused: 0
1042 1043 data-unused: 0.000%
1043 1044
1044 1045 new data appened
1045 1046 -----------------
1046 1047
1047 1048 Other commit happening on the server during the stream clone
1048 1049
1049 1050 setup the step-by-step stream cloning
1050 1051
1051 1052 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
1052 1053 $ export HG_TEST_STREAM_WALKED_FILE_1
1053 1054 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
1054 1055 $ export HG_TEST_STREAM_WALKED_FILE_2
1055 1056 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
1056 1057 $ export HG_TEST_STREAM_WALKED_FILE_3
1057 1058 $ cat << EOF >> test-repo/.hg/hgrc
1058 1059 > [extensions]
1059 1060 > steps=$RUNTESTDIR/testlib/ext-stream-clone-steps.py
1060 1061 > EOF
1061 1062
1062 1063 Check and record file state beforehand
1063 1064
1064 1065 $ f --size test-repo/.hg/store/00changelog*
1065 1066 test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
1066 test-repo/.hg/store/00changelog.d: size=376891 (zstd !)
1067 test-repo/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1068 test-repo/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1067 1069 test-repo/.hg/store/00changelog.d: size=368890 (no-zstd !)
1068 1070 test-repo/.hg/store/00changelog.i: size=320384
1069 1071 test-repo/.hg/store/00changelog.n: size=62
1070 1072 $ hg -R test-repo debugnodemap --metadata | tee server-metadata.txt
1071 1073 uid: * (glob)
1072 1074 tip-rev: 5005
1073 1075 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1074 1076 data-length: 121088
1075 1077 data-unused: 0
1076 1078 data-unused: 0.000%
1077 1079
1078 1080 Prepare a commit
1079 1081
1080 1082 $ echo foo >> test-repo/foo
1081 1083 $ hg -R test-repo/ add test-repo/foo
1082 1084
1083 1085 Do a mix of clone and commit at the same time so that the file listed on disk differ at actual transfer time.
1084 1086
1085 1087 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | egrep '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1086 1088 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1087 1089 $ hg -R test-repo/ commit -m foo
1088 1090 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1089 1091 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1090 1092 $ cat clone-output
1091 1093 adding [s] 00manifest.n (62 bytes)
1092 1094 adding [s] 00manifest-*.nd (118 KB) (glob)
1093 1095 adding [s] 00changelog.n (62 bytes)
1094 1096 adding [s] 00changelog-*.nd (118 KB) (glob)
1095 1097 adding [s] 00manifest.d (452 KB) (no-zstd !)
1096 adding [s] 00manifest.d (491 KB) (zstd !)
1098 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1099 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1097 1100 adding [s] 00changelog.d (360 KB) (no-zstd !)
1098 1101 adding [s] 00changelog.d (368 KB) (zstd !)
1099 1102 adding [s] 00manifest.i (313 KB)
1100 1103 adding [s] 00changelog.i (313 KB)
1101 1104
1102 1105 Check the result state
1103 1106
1104 1107 $ f --size stream-clone-race-1/.hg/store/00changelog*
1105 1108 stream-clone-race-1/.hg/store/00changelog-*.nd: size=121088 (glob)
1106 1109 stream-clone-race-1/.hg/store/00changelog.d: size=368890 (no-zstd !)
1107 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd !)
1110 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1111 stream-clone-race-1/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1108 1112 stream-clone-race-1/.hg/store/00changelog.i: size=320384
1109 1113 stream-clone-race-1/.hg/store/00changelog.n: size=62
1110 1114
1111 1115 $ hg -R stream-clone-race-1 debugnodemap --metadata | tee client-metadata.txt
1112 1116 uid: * (glob)
1113 1117 tip-rev: 5005
1114 1118 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1115 1119 data-length: 121088
1116 1120 data-unused: 0
1117 1121 data-unused: 0.000%
1118 1122
1119 1123 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1120 1124 (ie: the following diff should be empty)
1121 1125
1122 1126 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1123 1127
1124 1128 #if no-rust no-pure
1125 1129 $ diff -u server-metadata.txt client-metadata.txt
1126 1130 --- server-metadata.txt * (glob)
1127 1131 +++ client-metadata.txt * (glob)
1128 1132 @@ -1,4 +1,4 @@
1129 1133 -uid: * (glob)
1130 1134 +uid: * (glob)
1131 1135 tip-rev: 5005
1132 1136 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1133 1137 data-length: 121088
1134 1138 [1]
1135 1139 #else
1136 1140 $ diff -u server-metadata.txt client-metadata.txt
1137 1141 #endif
1138 1142
1139 1143
1140 1144 Clean up after the test.
1141 1145
1142 1146 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_1"
1143 1147 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_2"
1144 1148 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_3"
1145 1149
1146 1150 full regeneration
1147 1151 -----------------
1148 1152
1149 1153 A full nodemap is generated
1150 1154
1151 1155 (ideally this test would append enough data to make sure the nodemap data file
1152 1156 get changed, however to make thing simpler we will force the regeneration for
1153 1157 this test.
1154 1158
1155 1159 Check the initial state
1156 1160
1157 1161 $ f --size test-repo/.hg/store/00changelog*
1158 1162 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1159 1163 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1160 1164 test-repo/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1161 test-repo/.hg/store/00changelog.d: size=376950 (zstd !)
1165 test-repo/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1166 test-repo/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1162 1167 test-repo/.hg/store/00changelog.d: size=368949 (no-zstd !)
1163 1168 test-repo/.hg/store/00changelog.i: size=320448
1164 1169 test-repo/.hg/store/00changelog.n: size=62
1165 1170 $ hg -R test-repo debugnodemap --metadata | tee server-metadata-2.txt
1166 1171 uid: * (glob)
1167 1172 tip-rev: 5006
1168 1173 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1169 1174 data-length: 121344 (rust !)
1170 1175 data-length: 121344 (pure !)
1171 1176 data-length: 121152 (no-rust no-pure !)
1172 1177 data-unused: 192 (rust !)
1173 1178 data-unused: 192 (pure !)
1174 1179 data-unused: 0 (no-rust no-pure !)
1175 1180 data-unused: 0.158% (rust !)
1176 1181 data-unused: 0.158% (pure !)
1177 1182 data-unused: 0.000% (no-rust no-pure !)
1178 1183
1179 1184 Performe the mix of clone and full refresh of the nodemap, so that the files
1180 1185 (and filenames) are different between listing time and actual transfer time.
1181 1186
1182 1187 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-2 --debug 2>> clone-output-2 | egrep '00(changelog|manifest)' >> clone-output-2; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1183 1188 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1184 1189 $ rm test-repo/.hg/store/00changelog.n
1185 1190 $ rm test-repo/.hg/store/00changelog-*.nd
1186 1191 $ hg -R test-repo/ debugupdatecache
1187 1192 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1188 1193 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1189 1194
1190 1195 (note: the stream clone code wronly pick the `undo.` files)
1191 1196
1192 1197 $ cat clone-output-2
1193 1198 adding [s] undo.backup.00manifest.n (62 bytes) (known-bad-output !)
1194 1199 adding [s] undo.backup.00changelog.n (62 bytes) (known-bad-output !)
1195 1200 adding [s] 00manifest.n (62 bytes)
1196 1201 adding [s] 00manifest-*.nd (118 KB) (glob)
1197 1202 adding [s] 00changelog.n (62 bytes)
1198 1203 adding [s] 00changelog-*.nd (118 KB) (glob)
1199 1204 adding [s] 00manifest.d (492 KB) (zstd !)
1200 1205 adding [s] 00manifest.d (452 KB) (no-zstd !)
1201 1206 adding [s] 00changelog.d (360 KB) (no-zstd !)
1202 1207 adding [s] 00changelog.d (368 KB) (zstd !)
1203 1208 adding [s] 00manifest.i (313 KB)
1204 1209 adding [s] 00changelog.i (313 KB)
1205 1210
1206 1211 Check the result.
1207 1212
1208 1213 $ f --size stream-clone-race-2/.hg/store/00changelog*
1209 1214 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1210 1215 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1211 1216 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1212 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd !)
1217 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1218 stream-clone-race-2/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1213 1219 stream-clone-race-2/.hg/store/00changelog.d: size=368949 (no-zstd !)
1214 1220 stream-clone-race-2/.hg/store/00changelog.i: size=320448
1215 1221 stream-clone-race-2/.hg/store/00changelog.n: size=62
1216 1222
1217 1223 $ hg -R stream-clone-race-2 debugnodemap --metadata | tee client-metadata-2.txt
1218 1224 uid: * (glob)
1219 1225 tip-rev: 5006
1220 1226 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1221 1227 data-length: 121344 (rust !)
1222 1228 data-unused: 192 (rust !)
1223 1229 data-unused: 0.158% (rust !)
1224 1230 data-length: 121152 (no-rust no-pure !)
1225 1231 data-unused: 0 (no-rust no-pure !)
1226 1232 data-unused: 0.000% (no-rust no-pure !)
1227 1233 data-length: 121344 (pure !)
1228 1234 data-unused: 192 (pure !)
1229 1235 data-unused: 0.158% (pure !)
1230 1236
1231 1237 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1232 1238 (ie: the following diff should be empty)
1233 1239
1234 1240 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1235 1241
1236 1242 #if no-rust no-pure
1237 1243 $ diff -u server-metadata-2.txt client-metadata-2.txt
1238 1244 --- server-metadata-2.txt * (glob)
1239 1245 +++ client-metadata-2.txt * (glob)
1240 1246 @@ -1,4 +1,4 @@
1241 1247 -uid: * (glob)
1242 1248 +uid: * (glob)
1243 1249 tip-rev: 5006
1244 1250 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1245 1251 data-length: 121152
1246 1252 [1]
1247 1253 #else
1248 1254 $ diff -u server-metadata-2.txt client-metadata-2.txt
1249 1255 #endif
1250 1256
1251 1257 Clean up after the test
1252 1258
1253 1259 $ rm -f $HG_TEST_STREAM_WALKED_FILE_1
1254 1260 $ rm -f $HG_TEST_STREAM_WALKED_FILE_2
1255 1261 $ rm -f $HG_TEST_STREAM_WALKED_FILE_3
1256 1262
General Comments 0
You need to be logged in to leave comments. Login now