git/t/t5401-update-hooks.sh
Junio C Hamano 41ac414ea2 Sane use of test_expect_failure
Originally, test_expect_failure was designed to be the opposite
of test_expect_success, but this was a bad decision.  Most tests
run a series of commands that leads to the single command that
needs to be tested, like this:

    test_expect_{success,failure} 'test title' '
	setup1 &&
        setup2 &&
        setup3 &&
        what is to be tested
    '

And expecting a failure exit from the whole sequence misses the
point of writing tests.  Your setup$N that are supposed to
succeed may have failed without even reaching what you are
trying to test.  The only valid use of test_expect_failure is to
check a trivial single command that is expected to fail, which
is a minority in tests of Porcelain-ish commands.

This large-ish patch rewrites all uses of test_expect_failure to
use test_expect_success and rewrites the condition of what is
tested, like this:

    test_expect_success 'test title' '
	setup1 &&
        setup2 &&
        setup3 &&
        ! this command should fail
    '

test_expect_failure is redefined to serve as a reminder that
that test *should* succeed but due to a known breakage in git it
currently does not pass.  So if git-foo command should create a
file 'bar' but you discovered a bug that it doesn't, you can
write a test like this:

    test_expect_failure 'git-foo should create bar' '
        rm -f bar &&
        git foo &&
        test -f bar
    '

This construct acts similar to test_expect_success, but instead
of reporting "ok/FAIL" like test_expect_success does, the
outcome is reported as "FIXED/still broken".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-01 20:49:34 -08:00

137 lines
3.6 KiB
Bash
Executable file

#!/bin/sh
#
# Copyright (c) 2006 Shawn O. Pearce
#
test_description='Test the update hook infrastructure.'
. ./test-lib.sh
test_expect_success setup '
echo This is a test. >a &&
git update-index --add a &&
tree0=$(git write-tree) &&
commit0=$(echo setup | git commit-tree $tree0) &&
echo We hope it works. >a &&
git update-index a &&
tree1=$(git write-tree) &&
commit1=$(echo modify | git commit-tree $tree1 -p $commit0) &&
git update-ref refs/heads/master $commit0 &&
git update-ref refs/heads/tofail $commit1 &&
git-clone ./. victim &&
GIT_DIR=victim/.git git update-ref refs/heads/tofail $commit1 &&
git update-ref refs/heads/master $commit1 &&
git update-ref refs/heads/tofail $commit0
'
cat >victim/.git/hooks/pre-receive <<'EOF'
#!/bin/sh
printf %s "$@" >>$GIT_DIR/pre-receive.args
cat - >$GIT_DIR/pre-receive.stdin
echo STDOUT pre-receive
echo STDERR pre-receive >&2
EOF
chmod u+x victim/.git/hooks/pre-receive
cat >victim/.git/hooks/update <<'EOF'
#!/bin/sh
echo "$@" >>$GIT_DIR/update.args
read x; printf %s "$x" >$GIT_DIR/update.stdin
echo STDOUT update $1
echo STDERR update $1 >&2
test "$1" = refs/heads/master || exit
EOF
chmod u+x victim/.git/hooks/update
cat >victim/.git/hooks/post-receive <<'EOF'
#!/bin/sh
printf %s "$@" >>$GIT_DIR/post-receive.args
cat - >$GIT_DIR/post-receive.stdin
echo STDOUT post-receive
echo STDERR post-receive >&2
EOF
chmod u+x victim/.git/hooks/post-receive
cat >victim/.git/hooks/post-update <<'EOF'
#!/bin/sh
echo "$@" >>$GIT_DIR/post-update.args
read x; printf %s "$x" >$GIT_DIR/post-update.stdin
echo STDOUT post-update
echo STDERR post-update >&2
EOF
chmod u+x victim/.git/hooks/post-update
test_expect_success push '
! git-send-pack --force ./victim/.git master tofail >send.out 2>send.err
'
test_expect_success 'updated as expected' '
test $(GIT_DIR=victim/.git git rev-parse master) = $commit1 &&
test $(GIT_DIR=victim/.git git rev-parse tofail) = $commit1
'
test_expect_success 'hooks ran' '
test -f victim/.git/pre-receive.args &&
test -f victim/.git/pre-receive.stdin &&
test -f victim/.git/update.args &&
test -f victim/.git/update.stdin &&
test -f victim/.git/post-receive.args &&
test -f victim/.git/post-receive.stdin &&
test -f victim/.git/post-update.args &&
test -f victim/.git/post-update.stdin
'
test_expect_success 'pre-receive hook input' '
(echo $commit0 $commit1 refs/heads/master;
echo $commit1 $commit0 refs/heads/tofail
) | git diff - victim/.git/pre-receive.stdin
'
test_expect_success 'update hook arguments' '
(echo refs/heads/master $commit0 $commit1;
echo refs/heads/tofail $commit1 $commit0
) | git diff - victim/.git/update.args
'
test_expect_success 'post-receive hook input' '
echo $commit0 $commit1 refs/heads/master |
git diff - victim/.git/post-receive.stdin
'
test_expect_success 'post-update hook arguments' '
echo refs/heads/master |
git diff - victim/.git/post-update.args
'
test_expect_success 'all hook stdin is /dev/null' '
! test -s victim/.git/update.stdin &&
! test -s victim/.git/post-update.stdin
'
test_expect_success 'all *-receive hook args are empty' '
! test -s victim/.git/pre-receive.args &&
! test -s victim/.git/post-receive.args
'
test_expect_success 'send-pack produced no output' '
! test -s send.out
'
cat <<EOF >expect
STDOUT pre-receive
STDERR pre-receive
STDOUT update refs/heads/master
STDERR update refs/heads/master
STDOUT update refs/heads/tofail
STDERR update refs/heads/tofail
STDOUT post-receive
STDERR post-receive
STDOUT post-update
STDERR post-update
EOF
test_expect_success 'send-pack stderr contains hook messages' '
grep ^STD send.err >actual &&
git diff - actual <expect
'
test_done