Subject: [PATCH/RFC v2 3/4] fetch-pack: test cases for the new --stdin option

From: Ivan Todoroski <[email-masked]>
Date: Tue, 27 Mar 2012 08:27:11 +0200

These test cases focus only on testing the parsing of refs on stdin,
without bothering with the rest of the fetch-pack machinery. We pass in
the refs using different combinations of command line and stdin and then
we watch fetch-pack's stdout to see whether it prints all the refs we
specified and in the same order as we specified them.

For the --stateless-rpc tests we cannot easily execute fetch-pack to the
end because that would require simulating the remote protocol. We settle
for only checking 2 cases:

1) Whether fetch-pack correctly fails to parse the refs if they are not
terminated by a flush packet

2) Whether fetch-pack finishes parsing the refs without error when they
are correctly terminated by a flush packet

The fetch-pack invocation fails in both cases due to the missing remote
side of the protocol, but it fails in different ways which allows us to
determine how the refs parsing ended by inspecting the different error
messages.
---
 t/t5500-fetch-pack.sh |  100 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 9bf69e9a0f..f4de7d07c1 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -248,4 +248,104 @@ test_expect_success 'clone shallow object count' '
 	grep "^count: 52" count.shallow
 '
 
+
+cat >stdin.exp <<EOF
+refs/heads/C
+refs/heads/A
+refs/heads/D
+refs/tags/C
+refs/heads/B
+refs/tags/A
+refs/heads/E
+refs/tags/B
+refs/tags/E
+refs/tags/D
+EOF
+
+test_expect_success 'setup tests for --stdin' '
+	for head in C D E F; do
+		add $head
+	done &&
+	for head in A B C D E F; do
+		git tag $head $head
+	done
+'
+
+test_expect_success 'fetch refs from cmdline, make sure it still works OK' '
+	cd client &&
+	git fetch-pack --no-progress .. $(cat ../stdin.exp) |
+	cut -d " " -f 2 > ../stdin.act &&
+	cd .. &&
+	test_cmp stdin.exp stdin.act
+'
+
+test_expect_success 'fetch refs from stdin' '
+	cd client &&
+	cat ../stdin.exp |
+	git fetch-pack --stdin --no-progress .. |
+	cut -d " " -f 2 > ../stdin.act &&
+	cd .. &&
+	test_cmp stdin.exp stdin.act
+'
+
+test_expect_success 'fetch mixed refs from cmdline and stdin in right order' '
+	cd client &&
+	tail -n +5 ../stdin.exp |
+	git fetch-pack --stdin --no-progress .. $(head -n 4 ../stdin.exp) |
+	cut -d " " -f 2 > ../stdin.act &&
+	cd .. &&
+	test_cmp stdin.exp stdin.act
+'
+
+
+# remove final newline and insert random spaces, NULs, and empty lines
+head -c -1 stdin.exp | sed -e '
+	1i
+	2s/^\|$/   /g
+	4s/^/    /
+	6s/$/    /
+	8s/$/\n     /
+	9s/$/Ztrailing garbage/
+	9s/^\|$/    /g
+' | tr "Z" "\000" > stdin.spaces
+
+test_expect_success 'ignore leading/trailing spaces, empty lines and NULs' '
+	cd client &&
+	cat ../stdin.spaces |
+	git fetch-pack --stdin --no-progress .. |
+	cut -d " " -f 2 > ../stdin.act &&
+	cd .. &&
+	test_cmp stdin.exp stdin.act
+'
+
+
+packet_write() { printf "%04x%s\n" $((${#1} + 5)) "$1"; }
+packet_flush() { printf "0000"; }
+
+cat stdin.exp | while read ref; do
+	packet_write $ref
+done | tee stdin.pkt.bad |
+(packet_flush; packet_write garbage) > stdin.pkt.good
+
+echo "fatal: protocol error: expected sha/ref, got 'garbage'" > stdin.pkt.good.exp
+echo "fatal: The remote end hung up unexpectedly" > stdin.pkt.bad.exp
+
+test_expect_success 'refs on stdin in packetized format' '
+	cd client &&
+	cat ../stdin.pkt.good |
+	test_must_fail git fetch-pack --stdin --stateless-rpc .. \
+	2> ../stdin.pkt.good.act &&
+	cd .. &&
+	test_cmp stdin.pkt.good.exp stdin.pkt.good.act
+'
+
+test_expect_success 'fail if flush packet is missing' '
+	cd client &&
+	cat ../stdin.pkt.bad |
+	test_must_fail git fetch-pack --stdin --stateless-rpc .. \
+	2> ../stdin.pkt.bad.act &&
+	cd .. &&
+	test_cmp stdin.pkt.bad.exp stdin.pkt.bad.act
+'
+
 test_done
-- 
1.7.9.5.4.g4f508