tests/test-pending.t
changeset 13237 c046978cc0a9
child 15519 bb9ad375b51c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-pending.t	Wed Dec 29 18:29:15 2010 -0800
@@ -0,0 +1,117 @@
+Verify that pending changesets are seen by pretxn* hooks but not by other
+processes that access the destination repo while the hooks are running.
+
+The hooks (python and external) both reject changesets after some think time,
+during which another process runs pull.  Each hook creates a file ('notify') to
+indicate to the controlling process that it is running; the process removes the
+file to indicate the hook can terminate.
+
+init env vars
+
+  $ d=`pwd`
+  $ maxwait=20
+
+utility to run the test - start a push in the background and run pull
+
+  $ dotest() {
+  >     rm -f notify
+  >     printf 'push '; hg -R child-push tip --template '{node}\n'
+  >     hg -R child-push -q push > push.out 2>&1 &
+  > 
+  >     # wait for hook to create the notify file
+  >     i=$maxwait
+  >     while [ ! -f notify -a $i != 0 ]; do
+  >         sleep 1
+  >         i=`expr $i - 1`
+  >     done
+  > 
+  >     # run pull
+  >     hg -R child-pull -q pull
+  >     rc=$?
+  > 
+  >     # tell hook to finish; notify should exist.
+  >     rm notify
+  >     wait
+  > 
+  >     cat push.out
+  >     printf 'pull '; hg -R child-pull tip --template '{node}\n'
+  >     return $rc
+  > }
+
+python hook
+
+  $ cat <<EOF > reject.py
+  > import os, time
+  > from mercurial import ui, localrepo
+  > def rejecthook(ui, repo, hooktype, node, **opts):
+  >     ui.write('hook %s\\n' % repo['tip'].hex())
+  >     # create the notify file so caller knows we're running
+  >     fpath = os.path.join('$d', 'notify')
+  >     f = open(fpath, 'w')
+  >     f.close()
+  >     # wait for ack - caller should delete the notify file
+  >     i = $maxwait
+  >     while os.path.exists(fpath) and i > 0:
+  >         time.sleep(1)
+  >         i -= 1
+  >     return True # reject the changesets
+  > EOF
+
+external hook
+
+  $ cat <<EOF > reject.sh
+  > #! /bin/sh
+  > printf 'hook '; hg tip --template '{node}\\n'
+  > # create the notify file so caller knows we're running
+  > fpath=$d/notify
+  > touch \$fpath
+  > # wait for ack - caller should delete the notify file
+  > i=$maxwait
+  > while [ -f \$fpath -a \$i != 0 ]; do
+  >     sleep 1
+  >     i=\`expr \$i - 1\`
+  > done
+  > exit 1 # reject the changesets
+  > EOF
+  $ chmod +x reject.sh
+
+create repos
+
+  $ hg init parent
+  $ hg clone -q parent child-push
+  $ hg clone -q parent child-pull
+  $ echo a > child-push/a
+  $ hg -R child-push add child-push/a
+  $ hg -R child-push commit -m a -d '1000000 0'
+
+test python hook
+
+  $ cat <<EOF > parent/.hg/hgrc
+  > [extensions]
+  > reject = $d/reject.py
+  > [hooks]
+  > pretxnchangegroup = python:reject.rejecthook
+  > EOF
+
+  $ dotest
+  push 29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
+  hook 29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
+  transaction abort!
+  rollback completed
+  abort: pretxnchangegroup hook failed
+  pull 0000000000000000000000000000000000000000
+
+test external hook
+
+  $ cat <<EOF > parent/.hg/hgrc
+  > [hooks]
+  > pretxnchangegroup = $d/reject.sh
+  > EOF
+
+  $ dotest
+  push 29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
+  hook 29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
+  transaction abort!
+  rollback completed
+  abort: pretxnchangegroup hook exited with status 1
+  pull 0000000000000000000000000000000000000000