tests/test-hook
author Mads Kiilerich <mads@kiilerich.com>
Mon, 09 Aug 2010 21:43:39 +0200
branchstable
changeset 11772 423ece53380e
parent 10492 0e64d814d7d0
permissions -rwxr-xr-x
test-dispatch: Make test of removed working directory work on AIX (issue2315) AIX sh won't delete its own working directory. Removing it from another process works. Also hide the actual OS error message - operating systems returns different errors when getcwd fails.

#!/bin/sh

cp "$TESTDIR"/printenv.py .

# commit hooks can see env vars
hg init a
cd a
echo "[hooks]" > .hg/hgrc
echo 'commit = unset HG_LOCAL HG_TAG; python ../printenv.py commit' >> .hg/hgrc
echo 'commit.b = unset HG_LOCAL HG_TAG; python ../printenv.py commit.b' >> .hg/hgrc
echo 'precommit = unset HG_LOCAL HG_NODE HG_TAG; python ../printenv.py precommit' >> .hg/hgrc
echo 'pretxncommit = unset HG_LOCAL HG_TAG; python ../printenv.py pretxncommit' >> .hg/hgrc
echo 'pretxncommit.tip = hg -q tip' >> .hg/hgrc
echo 'pre-identify = python ../printenv.py pre-identify 1' >> .hg/hgrc
echo 'pre-cat = python ../printenv.py pre-cat' >> .hg/hgrc
echo 'post-cat = python ../printenv.py post-cat' >> .hg/hgrc
echo a > a
hg add a
hg commit -m a -d "1000000 0"

hg clone . ../b
cd ../b

# changegroup hooks can see env vars
echo '[hooks]' > .hg/hgrc
echo 'prechangegroup = python ../printenv.py prechangegroup' >> .hg/hgrc
echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
echo 'incoming = python ../printenv.py incoming' >> .hg/hgrc

# pretxncommit and commit hooks can see both parents of merge
cd ../a
echo b >> a
hg commit -m a1 -d "1 0"
hg update -C 0
echo b > b
hg add b
hg commit -m b -d '1 0'
hg merge 1
hg commit -m merge -d '2 0'

# test generic hooks
hg id
hg cat b

cd ../b
hg pull ../a

# tag hooks can see env vars
cd ../a
echo 'pretag = python ../printenv.py pretag' >> .hg/hgrc
echo 'tag = unset HG_PARENT1 HG_PARENT2; python ../printenv.py tag' >> .hg/hgrc
hg tag -d '3 0' a
hg tag -l la

# pretag hook can forbid tagging
echo 'pretag.forbid = python ../printenv.py pretag.forbid 1' >> .hg/hgrc
hg tag -d '4 0' fa
hg tag -l fla

# pretxncommit hook can see changeset, can roll back txn, changeset
# no more there after
echo 'pretxncommit.forbid0 = hg tip -q' >> .hg/hgrc
echo 'pretxncommit.forbid1 = python ../printenv.py pretxncommit.forbid 1' >> .hg/hgrc
echo z > z
hg add z
hg -q tip
hg commit -m 'fail' -d '4 0'
hg -q tip

# precommit hook can prevent commit
echo 'precommit.forbid = python ../printenv.py precommit.forbid 1' >> .hg/hgrc
hg commit -m 'fail' -d '4 0'
hg -q tip

# preupdate hook can prevent update
echo 'preupdate = python ../printenv.py preupdate' >> .hg/hgrc
hg update 1

# update hook
echo 'update = python ../printenv.py update' >> .hg/hgrc
hg update

# prechangegroup hook can prevent incoming changes
cd ../b
hg -q tip
echo '[hooks]' > .hg/hgrc
echo 'prechangegroup.forbid = python ../printenv.py prechangegroup.forbid 1' >> .hg/hgrc
hg pull ../a

# pretxnchangegroup hook can see incoming changes, can roll back txn,
# incoming changes no longer there after
echo '[hooks]' > .hg/hgrc
echo 'pretxnchangegroup.forbid0 = hg tip -q' >> .hg/hgrc
echo 'pretxnchangegroup.forbid1 = python ../printenv.py pretxnchangegroup.forbid 1' >> .hg/hgrc
hg pull ../a
hg -q tip

# outgoing hooks can see env vars
rm .hg/hgrc
echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing = python ../printenv.py preoutgoing' >> ../a/.hg/hgrc
echo 'outgoing = python ../printenv.py outgoing' >> ../a/.hg/hgrc
hg pull ../a
hg rollback

# preoutgoing hook can prevent outgoing changes
echo 'preoutgoing.forbid = python ../printenv.py preoutgoing.forbid 1' >> ../a/.hg/hgrc
hg pull ../a

# outgoing hooks work for local clones
cd ..
echo '[hooks]' > a/.hg/hgrc
echo 'preoutgoing = python ../printenv.py preoutgoing' >> a/.hg/hgrc
echo 'outgoing = python ../printenv.py outgoing' >> a/.hg/hgrc
hg clone a c
rm -rf c

# preoutgoing hook can prevent outgoing changes for local clones
echo 'preoutgoing.forbid = python ../printenv.py preoutgoing.forbid 1' >> a/.hg/hgrc
hg clone a zzz
cd b

cat > hooktests.py <<EOF
from mercurial import util

uncallable = 0

def printargs(args):
    args.pop('ui', None)
    args.pop('repo', None)
    a = list(args.items())
    a.sort()
    print 'hook args:'
    for k, v in a:
       print ' ', k, v

def passhook(**args):
    printargs(args)

def failhook(**args):
    printargs(args)
    return True

class LocalException(Exception):
    pass

def raisehook(**args):
    raise LocalException('exception from hook')

def aborthook(**args):
    raise util.Abort('raise abort from hook')

def brokenhook(**args):
    return 1 + {}

class container:
    unreachable = 1
EOF

echo '# test python hooks'
PYTHONPATH="`pwd`:$PYTHONPATH"
export PYTHONPATH

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
hg pull ../a 2>&1 | grep 'raised an exception'

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
hg pull ../a 2>&1 | grep 'raised an exception'

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
hg pull ../a

echo '# make sure --traceback works'
echo '[hooks]' > .hg/hgrc
echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc

echo aa > a
hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'

cd ..
hg init c
cd c

cat > hookext.py <<EOF
def autohook(**args):
    print "Automatically installed hook"

def reposetup(ui, repo):
    repo.ui.setconfig("hooks", "commit.auto", autohook)
EOF
echo '[extensions]' >> .hg/hgrc
echo 'hookext = hookext.py' >> .hg/hgrc

touch foo
hg add foo
hg ci -d '0 0' -m 'add foo'
echo >> foo
hg ci --debug -d '0 0' -m 'change foo' | sed -e 's/ at .*>/>/'

hg showconfig hooks | sed -e 's/ at .*>/>/'

echo '# test python hook configured with python:[file]:[hook] syntax'
cd ..
mkdir d
cd d
hg init repo
mkdir hooks

cd hooks
cat > testhooks.py <<EOF
def testhook(**args):
    print 'hook works'
EOF
echo '[hooks]' > ../repo/.hg/hgrc
echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc

cd ../repo
hg commit -d '0 0'

cd ../../b
echo '# make sure --traceback works on hook import failure'
cat > importfail.py <<EOF
import somebogusmodule
# dereference something in the module to force demandimport to load it
somebogusmodule.whatever
EOF

echo '[hooks]' > .hg/hgrc
echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc

echo a >> a
hg --traceback commit -d '0 0' -ma 2>&1 | egrep '^(exception|Traceback|ImportError)'

echo '# commit and update hooks should run after command completion (issue 1827)'
echo '[hooks]' > .hg/hgrc
echo 'commit = hg id' >> .hg/hgrc
echo 'update = hg id' >> .hg/hgrc
echo bb > a
hg ci -d '0 0' -ma
hg up 0

exit 0