# HG changeset patch # User John Coomes # Date 2010-12-30 02:29:15 # Node ID c046978cc0a952b8aa590c3aeb6b749746e73595 # Parent 3f299f5d9a29b328d51d7cbb2829c55b172a3ed0 tests: check visibility of pending changesets Verify that pending changesets are seen by pretxn* hooks but not by other processes that access the destination repo while the hooks are running. diff --git a/tests/test-pending.t b/tests/test-pending.t new file mode 100755 --- /dev/null +++ b/tests/test-pending.t @@ -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 < 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 < 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 < 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 < 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