changeset 50174:596a6b9b0570

branching: merge stable into default This show that the recent changes on default fixed the issue with transaction overwriting content in `test-transaction-wc-rollback-race.t`
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 22 Feb 2023 18:42:09 +0100
parents bf27727e6c78 (diff) ee63c87a0cac (current diff)
children 0ab92dabea6e
files rust/Cargo.lock rust/hg-core/Cargo.toml rust/rhg/Cargo.toml setup.py tests/test-transaction-wc-rollback-race.t
diffstat 5 files changed, 279 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/rust/Cargo.lock	Fri Feb 17 16:48:11 2023 +0000
+++ b/rust/Cargo.lock	Wed Feb 22 18:42:09 2023 +0100
@@ -1023,21 +1023,19 @@
 
 [[package]]
 name = "rayon"
-version = "1.5.3"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
 dependencies = [
- "autocfg",
- "crossbeam-deque",
  "either",
  "rayon-core",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.9.3"
+version = "1.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
--- a/rust/hg-core/Cargo.toml	Fri Feb 17 16:48:11 2023 +0000
+++ b/rust/hg-core/Cargo.toml	Wed Feb 22 18:42:09 2023 +0100
@@ -24,7 +24,7 @@
 rand = "0.8.5"
 rand_pcg = "0.3.1"
 rand_distr = "0.4.3"
-rayon = "1.5.3"
+rayon = "1.6.1"
 regex = "1.7.0"
 sha-1 = "0.10.0"
 twox-hash = "1.6.3"
--- a/rust/rhg/Cargo.toml	Fri Feb 17 16:48:11 2023 +0000
+++ b/rust/rhg/Cargo.toml	Wed Feb 22 18:42:09 2023 +0100
@@ -22,4 +22,4 @@
 format-bytes = "0.3.0"
 users = "0.11.0"
 which = "4.3.0"
-rayon = "1.5.3"
+rayon = "1.6.1"
--- a/setup.py	Fri Feb 17 16:48:11 2023 +0000
+++ b/setup.py	Wed Feb 22 18:42:09 2023 +0100
@@ -333,6 +333,8 @@
     pieces = sysstr(hg.run(cmd)).split()
     numerictags = [t for t in pieces if t[0:1].isdigit()]
     hgid = sysstr(hg.run(['id', '-i'])).strip()
+    if hgid.count('+') == 2:
+        hgid = hgid.replace("+", ".", 1)
     if not hgid:
         eprint("/!\\")
         eprint(r"/!\ Unable to determine hg version from local repository")
@@ -343,7 +345,7 @@
         if hgid.endswith('+'):  # propagate the dirty status to the tag
             version += '+'
     else:  # no tag found on the checked out revision
-        ltagcmd = ['parents', '--template', '{latesttag}']
+        ltagcmd = ['log', '--rev', 'wdir()', '--template', '{latesttag}']
         ltag = sysstr(hg.run(ltagcmd))
         if not ltag:
             eprint("/!\\")
@@ -352,7 +354,13 @@
                 r"/!\ Failed to retrieve current revision distance to lated tag"
             )
             return ''
-        changessincecmd = ['log', '-T', 'x\n', '-r', "only(.,'%s')" % ltag]
+        changessincecmd = [
+            'log',
+            '-T',
+            'x\n',
+            '-r',
+            "only(parents(),'%s')" % ltag,
+        ]
         changessince = len(hg.run(changessincecmd).splitlines())
         version = '%s+hg%s.%s' % (ltag, changessince, hgid)
     if version.endswith('+'):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-transaction-wc-rollback-race.t	Wed Feb 22 18:42:09 2023 +0100
@@ -0,0 +1,263 @@
+=======================================================================
+Check potential race condition around transaction and working copy data
+=======================================================================
+
+#testcases bookmarks-in-store bookmarks-wc-level
+
+The transaction is garanteed to run with the lock, but may runs without the
+wlock. So if the transaction backup/restore some content related to the
+working-copy and protected by the wlock, we might run into trouble if another
+process grab the wlock and modify them.
+
+This test file is testing various cases where such parallel changes happens to
+validate the transaction behavior.
+
+Other is used to get a simple pull source. As pull is a simple way to create
+transaction without the wlock.
+
+Setup
+=====
+
+Avoid long deadlock
+
+  $ cat << EOF >> $HGRCPATH
+  > [ui]
+  > timeout=10
+  > EOF
+
+#if bookmarks-in-store
+  $ cat << EOF >> $HGRCPATH
+  > [format]
+  > bookmarks-in-store = yes
+  > EOF
+#endif
+
+
+  $ hg init repo
+  $ cd repo
+  $ for filename in a b c d e f g h i j k l m; do
+  >     echo $filename > default_$filename
+  >     hg add default_$filename
+  >     hg commit --quiet --message default_$filename
+  > done
+  $ hg bookmark --rev . foo
+  $ hg branch babar
+  marked working directory as branch babar
+  (branches are permanent and global, did you want a bookmark?)
+  $ for filename in a b c d e f g h i j k l m; do
+  >     echo $filename > babar_$filename
+  >     hg add babar_$filename
+  >     hg commit --quiet --message babar_$filename
+  > done
+  $ hg bookmark --rev . bar
+  $ hg up 'desc("default_m")'
+  0 files updated, 0 files merged, 13 files removed, 0 files unresolved
+  $ hg log -G -T '[{branch}] ({bookmarks}) {desc}\n'
+  o  [babar] (bar) babar_m
+  |
+  o  [babar] () babar_l
+  |
+  o  [babar] () babar_k
+  |
+  o  [babar] () babar_j
+  |
+  o  [babar] () babar_i
+  |
+  o  [babar] () babar_h
+  |
+  o  [babar] () babar_g
+  |
+  o  [babar] () babar_f
+  |
+  o  [babar] () babar_e
+  |
+  o  [babar] () babar_d
+  |
+  o  [babar] () babar_c
+  |
+  o  [babar] () babar_b
+  |
+  o  [babar] () babar_a
+  |
+  @  [default] (foo) default_m
+  |
+  o  [default] () default_l
+  |
+  o  [default] () default_k
+  |
+  o  [default] () default_j
+  |
+  o  [default] () default_i
+  |
+  o  [default] () default_h
+  |
+  o  [default] () default_g
+  |
+  o  [default] () default_f
+  |
+  o  [default] () default_e
+  |
+  o  [default] () default_d
+  |
+  o  [default] () default_c
+  |
+  o  [default] () default_b
+  |
+  o  [default] () default_a
+  
+
+  $ cat << EOF >> ../txn-close.sh
+  > rm -f $TESTTMP/transaction-continue
+  > $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-continue $TESTTMP/transaction-waiting
+  > rm -f $TESTTMP/transaction-waiting
+  > exit 1
+  > EOF
+  $ cat << EOF >> .hg/hgrc
+  > [hooks]
+  > pretxnclose.test = sh $TESTTMP/txn-close.sh
+  > EOF
+
+Check the overall logic is working, the transaction is holding the `lock` , but
+not the `wlock`, then get aborted on a signal-file.
+
+  $ hg phase --rev 0
+  0: draft
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ echo y | hg --config ui.interactive=yes debuglock --set-wlock
+  ready to release the lock (y)?  y
+  $ echo y | hg --config ui.interactive=yes debuglock --set-lock
+  abort: lock is already held
+  [255]
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg phase --rev 0
+  0: draft
+  $ cat ../log.err
+  abort: pretxnclose.test hook exited with status 1
+
+Actual testing
+==============
+
+Changing tracked file
+---------------------
+
+  $ hg status
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg forget default_a
+  $ hg status
+  R default_a
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg status
+  R default_a
+  $ hg revert --all --quiet
+
+Changing branch from default
+----------------------------
+
+  $ hg branch
+  default
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg branch celeste
+  marked working directory as branch celeste
+  $ hg branch
+  celeste
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg branch
+  celeste
+
+Changing branch from another one
+--------------------------------
+
+  $ hg up babar --quiet
+  $ hg branch
+  babar
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg branch celeste
+  marked working directory as branch celeste
+  $ hg branch
+  celeste
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg branch
+  celeste
+
+updating working copy
+---------------------
+
+  $ hg st
+  $ hg log --rev . -T '{desc}\n'
+  babar_m
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg update "parents(.)" --quiet
+  $ hg log --rev . -T '{desc}\n'
+  babar_l
+  $ hg st
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg log --rev . -T '{desc}\n'
+  babar_l
+  $ hg st
+
+  $ hg purge --no-confirm
+  $ hg up --quiet babar
+
+Activating a bookmark
+---------------------
+(without going through the bookmark command)
+
+Show the activation/desactivation pattern that exist without taking the store
+lock.
+
+  $ hg log -r . -T '= {activebookmark} =\n'
+  =  =
+  $ hg up bar
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark bar)
+  $ hg log -r . -T '= {activebookmark} =\n'
+  = bar =
+  $ hg up .
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark bar)
+  $ hg log -r . -T '= {activebookmark} =\n'
+  =  =
+
+Activating the bookmark during a transaction
+
+  $ hg up . --quiet
+  $ hg log -r . -T '= {activebookmark} =\n'
+  =  =
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg up bar
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark bar)
+  $ hg log -r . -T '= {activebookmark} =\n'
+  = bar =
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg log -r . -T '= {activebookmark} =\n'
+  = bar =
+
+Deactivating the bookmark
+
+  $ hg up bar --quiet
+  $ hg log -r . -T '= {activebookmark} =\n'
+  = bar =
+  $ hg phase --public --rev 0 2> ../log.err &
+  $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting
+  $ hg up .
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark bar)
+  $ hg log -r . -T '= {activebookmark} =\n'
+  =  =
+  $ touch $TESTTMP/transaction-continue
+  $ wait
+  $ hg log -r . -T '= {activebookmark} =\n'
+  =  =