test-lock: use synchronisation file instead of sleep stable
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 11 Mar 2024 16:05:28 +0100
branchstable
changeset 51497 9da3fcc5f70f
parent 51471 5633de951d34
child 51498 25055932042a
test-lock: use synchronisation file instead of sleep This will prevent the test to be flaky on load.
mercurial/configitems.toml
mercurial/localrepo.py
mercurial/lock.py
tests/test-lock-badness.t
--- a/mercurial/configitems.toml	Mon Mar 11 13:36:25 2024 +0100
+++ b/mercurial/configitems.toml	Mon Mar 11 16:05:28 2024 +0100
@@ -583,6 +583,11 @@
 
 [[items]]
 section = "devel"
+name = "lock-wait-sync-file"
+default = ""
+
+[[items]]
+section = "devel"
 name = "persistent-nodemap"
 default = false
 documentation = """When true, revlogs use a special reference version of the \
--- a/mercurial/localrepo.py	Mon Mar 11 13:36:25 2024 +0100
+++ b/mercurial/localrepo.py	Mon Mar 11 16:05:28 2024 +0100
@@ -3072,6 +3072,9 @@
             warntimeout = self.ui.configint(b"ui", b"timeout.warn")
         # internal config: ui.signal-safe-lock
         signalsafe = self.ui.configbool(b'ui', b'signal-safe-lock')
+        sync_file = self.ui.config(b'devel', b'lock-wait-sync-file')
+        if not sync_file:
+            sync_file = None
 
         l = lockmod.trylock(
             self.ui,
@@ -3083,6 +3086,7 @@
             acquirefn=acquirefn,
             desc=desc,
             signalsafe=signalsafe,
+            devel_wait_sync_file=sync_file,
         )
         return l
 
--- a/mercurial/lock.py	Mon Mar 11 13:36:25 2024 +0100
+++ b/mercurial/lock.py	Mon Mar 11 16:05:28 2024 +0100
@@ -115,6 +115,7 @@
 
     This function is responsible to issue warnings and or debug messages about
     the held lock while trying to acquires it."""
+    devel_wait_file = kwargs.pop("devel_wait_sync_file", None)
 
     def printwarning(printer, locker):
         """issue the usual "waiting on lock" message through any channel"""
@@ -150,6 +151,11 @@
             l._trylock()
             break
         except error.LockHeld as inst:
+            if devel_wait_file is not None:
+                # create the file to signal we are waiting
+                with open(devel_wait_file, 'w'):
+                    pass
+
             if delay == debugidx:
                 printwarning(ui.debug, inst.locker)
             if delay == warningidx:
--- a/tests/test-lock-badness.t	Mon Mar 11 13:36:25 2024 +0100
+++ b/tests/test-lock-badness.t	Mon Mar 11 16:05:28 2024 +0100
@@ -49,15 +49,32 @@
 
 One process waiting for another
 
-  $ cat > hooks.py << EOF
-  > import time
-  > def sleepone(**x): time.sleep(1)
-  > def sleephalf(**x): time.sleep(0.5)
+  $ SYNC_FILE_LOCKED="$TESTTMP/sync-file-locked"
+  $ export SYNC_FILE_LOCKED
+  $ SYNC_FILE_TRYING_LOCK="$TESTTMP/sync-file-trying-lock"
+  $ export SYNC_FILE_TRYING_LOCK
+  $ cat << EOF > locker.sh
+  > $RUNTESTDIR/testlib/wait-on-file 10 $SYNC_FILE_TRYING_LOCK $SYNC_FILE_LOCKED;
+  > EOF
+  $ cat << EOF > waiter.sh
+  > $RUNTESTDIR/testlib/wait-on-file 10 $SYNC_FILE_LOCKED;
   > EOF
+  $ clean_sync() {
+  >   rm -f "$SYNC_FILE_LOCKED"
+  >   rm -f "$SYNC_FILE_TRYING_LOCK"
+  > }
+
+
+  $ clean_sync
   $ echo b > b/b
-  $ hg -R b ci -A -m b --config hooks.precommit="python:`pwd`/hooks.py:sleepone" > stdout &
-  $ hg -R b up -q --config ui.timeout.warn=0 --config hooks.pre-update="python:`pwd`/hooks.py:sleephalf" \
-  > > preup-stdout 2>preup-stderr
+  $ hg -R b ci -A -m b \
+  >   --config hooks.precommit="sh $TESTTMP/locker.sh" \
+  >   > stdout &
+  $ hg -R b up -q \
+  >   --config ui.timeout.warn=0 \
+  >   --config hooks.pre-update="sh $TESTTMP/waiter.sh" \
+  >   --config devel.lock-wait-sync-file="$SYNC_FILE_TRYING_LOCK" \
+  >   > preup-stdout 2> preup-stderr
   $ wait
   $ cat preup-stdout
   $ cat preup-stderr
@@ -68,11 +85,16 @@
 
 On processs waiting on another, warning after a long time.
 
+  $ clean_sync
   $ echo b > b/c
-  $ hg -R b ci -A -m b --config hooks.precommit="python:`pwd`/hooks.py:sleepone" > stdout &
-  $ hg -R b up -q --config hooks.pre-update="python:`pwd`/hooks.py:sleephalf" \
-  > --config ui.timeout.warn=250 \
-  > > preup-stdout 2>preup-stderr
+  $ hg -R b ci -A -m b \
+  >   --config hooks.precommit="sh $TESTTMP/locker.sh" \
+  >   > stdout &
+  $ hg -R b up -q \
+  >   --config hooks.pre-update="sh $TESTTMP/waiter.sh" \
+  >   --config devel.lock-wait-sync-file="$SYNC_FILE_TRYING_LOCK" \
+  >   --config ui.timeout.warn=250 \
+  >   > preup-stdout 2> preup-stderr
   $ wait
   $ cat preup-stdout
   $ cat preup-stderr
@@ -81,11 +103,16 @@
 
 On processs waiting on another, warning disabled.
 
+  $ clean_sync
   $ echo b > b/d
-  $ hg -R b ci -A -m b --config hooks.precommit="python:`pwd`/hooks.py:sleepone" > stdout &
-  $ hg -R b up -q --config hooks.pre-update="python:`pwd`/hooks.py:sleephalf" \
-  > --config ui.timeout.warn=-1 \
-  > > preup-stdout 2>preup-stderr
+  $ hg -R b ci -A -m b \
+  >   --config hooks.precommit="sh $TESTTMP/locker.sh" \
+  >   > stdout &
+  $ hg -R b up -q \
+  >   --config hooks.pre-update="sh $TESTTMP/waiter.sh" \
+  >   --config devel.lock-wait-sync-file="$SYNC_FILE_TRYING_LOCK" \
+  >   --config ui.timeout.warn=-1 \
+  >   > preup-stdout 2>preup-stderr
   $ wait
   $ cat preup-stdout
   $ cat preup-stderr
@@ -96,14 +123,19 @@
 
 On processs waiting on another, warning after a long time (debug output on)
 
+  $ clean_sync
   $ echo b > b/e
-  $ hg -R b ci -A -m b --config hooks.precommit="python:`pwd`/hooks.py:sleepone" > stdout &
-  $ hg -R b up --config hooks.pre-update="python:`pwd`/hooks.py:sleephalf" \
-  > --config ui.timeout.warn=250 --debug\
-  > > preup-stdout 2>preup-stderr
+  $ hg -R b ci -A -m b \
+  >   --config hooks.precommit="sh $TESTTMP/locker.sh" \
+  >   > stdout &
+  $ hg -R b up \
+  >   --config hooks.pre-update="sh $TESTTMP/waiter.sh" \
+  >   --config devel.lock-wait-sync-file="$SYNC_FILE_TRYING_LOCK" \
+  >   --config ui.timeout.warn=250 --debug \
+  >   > preup-stdout 2>preup-stderr
   $ wait
   $ cat preup-stdout
-  calling hook pre-update: hghook_pre-update.sleephalf
+  running hook pre-update: sh $TESTTMP/waiter.sh
   waiting for lock on working directory of b held by process '*' on host '*' (glob)
   got lock after * seconds (glob)
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -113,14 +145,19 @@
 
 On processs waiting on another, warning disabled, (debug output on)
 
+  $ clean_sync
   $ echo b > b/f
-  $ hg -R b ci -A -m b --config hooks.precommit="python:`pwd`/hooks.py:sleepone" > stdout &
-  $ hg -R b up --config hooks.pre-update="python:`pwd`/hooks.py:sleephalf" \
-  > --config ui.timeout.warn=-1 --debug\
-  > > preup-stdout 2>preup-stderr
+  $ hg -R b ci -A -m b \
+  >   --config hooks.precommit="sh $TESTTMP/locker.sh" \
+  >   > stdout &
+  $ hg -R b up \
+  >   --config hooks.pre-update="sh $TESTTMP/waiter.sh" \
+  >   --config devel.lock-wait-sync-file="$SYNC_FILE_TRYING_LOCK" \
+  >   --config ui.timeout.warn=-1 --debug\
+  >   > preup-stdout 2>preup-stderr
   $ wait
   $ cat preup-stdout
-  calling hook pre-update: hghook_pre-update.sleephalf
+  running hook pre-update: sh $TESTTMP/waiter.sh
   waiting for lock on working directory of b held by process '*' on host '*' (glob)
   got lock after * seconds (glob)
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved