changeset 42349:ffab9eed3921

merge with stable
author Augie Fackler <augie@google.com>
date Mon, 20 May 2019 11:40:47 -0400
parents de65ae32b82d (current diff) 2338bdea4474 (diff)
children e0ac310bd033
files mercurial/localrepo.py
diffstat 3 files changed, 243 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Mon May 20 08:40:54 2019 +0900
+++ b/mercurial/localrepo.py	Mon May 20 11:40:47 2019 -0400
@@ -1226,7 +1226,7 @@
         return cls(self, name, visibilityexceptions)
 
     @mixedrepostorecache(('bookmarks', ''), ('bookmarks.current', ''),
-                         ('bookmarks', 'store'))
+                         ('bookmarks', 'store'), ('00changelog.i', 'store'))
     def _bookmarks(self):
         return bookmarks.bmstore(self)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-bookmarks-corner-case.t	Mon May 20 11:40:47 2019 -0400
@@ -0,0 +1,238 @@
+================================
+Test corner case around bookmark
+================================
+
+This test file is meant to gather test around bookmark that are specific
+ enough to not find a place elsewhere.
+
+Test bookmark/changelog race condition
+======================================
+
+The data from the bookmark file are filtered to only contains bookmark with
+node known to the changelog. If the cache invalidation between these two bits
+goes wrong, bookmark can be dropped.
+
+global setup
+------------
+
+  $ cat >> $HGRCPATH << EOF
+  > [ui]
+  > ssh = "$PYTHON" "$TESTDIR/dummyssh"
+  > [server]
+  > concurrent-push-mode=check-related
+  > EOF
+
+Setup
+-----
+
+initial repository setup
+
+  $ hg init bookrace-server
+  $ cd bookrace-server
+  $ echo a > a
+  $ hg add a
+  $ hg commit -m root
+  $ echo a >> a
+  $ hg bookmark book-A
+  $ hg commit -m A0
+  $ hg up 'desc(root)'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark book-A)
+  $ echo b > b
+  $ hg add b
+  $ hg bookmark book-B
+  $ hg commit -m B0
+  created new head
+  $ hg up null
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  (leaving bookmark book-B)
+  $ hg phase --public --rev 'all()'
+  $ hg log -G
+  o  changeset:   2:c79985706978
+  |  bookmark:    book-B
+  |  tag:         tip
+  |  parent:      0:6569b5a81c7e
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     B0
+  |
+  | o  changeset:   1:39c28d785860
+  |/   bookmark:    book-A
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     A0
+  |
+  o  changeset:   0:6569b5a81c7e
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     root
+  
+  $ hg book
+     book-A                    1:39c28d785860
+     book-B                    2:c79985706978
+  $ cd ..
+
+Add new changeset on each bookmark in distinct clones
+
+  $ hg clone ssh://user@dummy/bookrace-server client-A
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files (+1 heads)
+  new changesets 6569b5a81c7e:c79985706978
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R client-A update book-A
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (activating bookmark book-A)
+  $ echo a >> client-A/a
+  $ hg -R client-A commit -m A1
+  $ hg clone ssh://user@dummy/bookrace-server client-B
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files (+1 heads)
+  new changesets 6569b5a81c7e:c79985706978
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R client-B update book-B
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark book-B)
+  $ echo b >> client-B/b
+  $ hg -R client-B commit -m B1
+
+extension to reproduce the race
+-------------------------------
+
+If two process are pushing we want to make sure the following happens:
+
+* process A read changelog
+* process B to its full push
+* process A read bookmarks
+* process A proceed with rest of the push
+
+We build a server side extension for this purpose
+
+  $ cat > bookrace.py << EOF
+  > import os
+  > import time
+  > import atexit
+  > from mercurial import error, extensions, bookmarks
+  > def wrapinit(orig, self, repo):
+  >     if not os.path.exists('push-A-started'):
+  >         print('setting raced push up')
+  >         with open('push-A-started', 'w'):
+  >             pass
+  >     clock = 300
+  >     while not os.path.exists('push-B-done'):
+  >         clock -= 1
+  >         if clock <= 0:
+  >             raise error.Abort("race scenario timed out")
+  >         time.sleep(0.1)
+  >     return orig(self, repo)
+  > 
+  >     repo.__class__ = racedrepo
+  > def uisetup(ui):
+  >     extensions.wrapfunction(bookmarks.bmstore, '__init__', wrapinit)
+  > def e():
+  >     with open('push-A-done', 'w'):
+  >         pass
+  > atexit.register(e)
+  > EOF
+
+Actual test
+-----------
+
+Start the raced push.
+
+  $ cat >> bookrace-server/.hg/hgrc << EOF
+  > [extensions]
+  > bookrace=$TESTTMP/bookrace.py
+  > EOF
+  $ hg push -R client-A -r book-A >push-output.txt 2>&1 &
+
+Wait up to 30 seconds for that push to start.
+
+  $ clock=30
+  $ while [ ! -f push-A-started ] && [ $clock -gt 0 ] ; do
+  >    clock=`expr $clock - 1`
+  >    sleep 1
+  > done
+
+Do the other push.
+
+  $ cat >> bookrace-server/.hg/hgrc << EOF
+  > [extensions]
+  > bookrace=!
+  > EOF
+
+  $ hg push -R client-B -r book-B
+  pushing to ssh://user@dummy/bookrace-server
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  updating bookmark book-B
+
+Signal the raced put that we are done (it waits up to 30 seconds).
+
+  $ touch push-B-done
+
+Wait for the raced push to finish (with the remaning of the initial 30 seconds).
+
+  $ while [ ! -f push-A-done ] && [ $clock -gt 0 ] ; do
+  >    clock=`expr $clock - 1`
+  >    sleep 1
+  > done
+
+Check raced push output.
+
+  $ cat push-output.txt
+  pushing to ssh://user@dummy/bookrace-server
+  searching for changes
+  remote: setting raced push up
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  updating bookmark book-A
+
+Check result of the push.
+
+  $ hg -R bookrace-server log -G
+  o  changeset:   4:9ce3b28c16de
+  |  bookmark:    book-A
+  |  tag:         tip
+  |  parent:      1:39c28d785860
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     A1
+  |
+  | o  changeset:   3:f26c3b5167d1
+  | |  bookmark:    book-B
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     B1
+  | |
+  | o  changeset:   2:c79985706978
+  | |  parent:      0:6569b5a81c7e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     B0
+  | |
+  o |  changeset:   1:39c28d785860
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     A0
+  |
+  o  changeset:   0:6569b5a81c7e
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     root
+  
+  $ hg -R bookrace-server book
+     book-A                    4:9ce3b28c16de
+     book-B                    3:f26c3b5167d1
--- a/tests/test-repo-compengines.t	Mon May 20 08:40:54 2019 +0900
+++ b/tests/test-repo-compengines.t	Mon May 20 11:40:47 2019 -0400
@@ -111,6 +111,7 @@
   > done
 
   $ $RUNTESTDIR/f -s */.hg/store/data/*
+  default/.hg/store/data/foo.i: size=64 (pure !)
   zlib-level-1/.hg/store/data/a.i: size=4146
   zlib-level-9/.hg/store/data/a.i: size=4138
   zlib-level-default/.hg/store/data/a.i: size=4138
@@ -138,6 +139,8 @@
   abort: invalid value for `storage.revlog.zlib.level` config: 42
   [255]
 
+#if zstd
+
 checking zstd options
 =====================
 
@@ -193,3 +196,4 @@
   abort: invalid value for `storage.revlog.zstd.level` config: 42
   [255]
 
+#endif