Subject: [PATCH/RFC svn-fe] tests: introduce helper to fill a pipe in the background

From: Jonathan Nieder <[email-masked]>
Date: Wed, 30 Mar 2011 03:16:43 -0500

The fill_input function generates a fifo and runs a command to write
to it and wait.  The intended use is to check that specialized
programs can find the end of their input without reading too much or
relying on EOF or SIGPIPE.  For example:

	fill_input "echo hi" &&
	head -1 input

will succeed, while

	fill_input "echo hi" &&
	head -2 input

will hang.

It works by running the indicated commands followed by
"exec sleep 100" in a background process; the process ID is later
passed to "kill" to avoid leaving behind random processes.

Several tests already did something like that but this adds some
improvements:

  1. Wrap the "kill" in a test_when_finished, since we want
     to clean up the process whether the test succeeds or not.

  2. Mark the kill as OK to fail.  These tests are not about
     whether the input generating function dies due to SIGPIPE
     or the system is slow enough for the timer to expire early
     but about what happens on the downstream end.

  3. Mark the relevant tests with the EXECKEEPSPID prerequisite.

Based-on-patch-by: Jeff King <[email-masked]>
Improved-by: Johannes Sixt <[email-masked]>
Signed-off-by: Jonathan Nieder <[email-masked]>
---
Johannes Sixt wrote:

> Note that tests that depend on ( exec ... ) & kill $! must be marked with
> the EXECKEEPSPID prerequisite.

Hmm, that's a shame, since the point of writing t0081 was to make sure
some assumptions the line-buffer lib makes are valid on Windows.  So I
suspect a better thing to do would be to remove t0081 --- the
line-buffer lib is simple, everyday use exercises it pretty well
already, and I can't imagine this script catching a bug.

 t/t0081-line-buffer.sh |   61 ++++++++++++++++++++++--------------------------
 1 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh
index 5067d1e..fb09ff1 100755
--- a/t/t0081-line-buffer.sh
+++ b/t/t0081-line-buffer.sh
@@ -14,6 +14,25 @@ correctly.
 
 test -n "$GIT_REMOTE_SVN_TEST_BIG_FILES" && test_set_prereq EXPENSIVE
 
+fill_input () {
+	if
+		! test_declared_prereq PIPE ||
+		! test_declared_prereq EXECKEEPSPID
+	then
+		echo >&4 "fill_input requires PIPE,EXECKEEPSPID prerequisites"
+		return 127
+	fi &&
+	rm -f input &&
+	mkfifo input &&
+	{
+		(
+			eval "$*" &&
+			exec sleep 100
+		) >input &
+	} &&
+	test_when_finished "kill $!"
+}
+
 generate_tens_of_lines () {
 	tens=$1 &&
 	line=$2 &&
@@ -35,28 +54,15 @@ long_read_test () {
 	line=abcdefghi &&
 	echo "$line" >expect &&
 
-	if ! test_declared_prereq PIPE
-	then
-		echo >&4 "long_read_test: need to declare PIPE prerequisite"
-		return 127
-	fi &&
 	tens_of_lines=$(($1 / 100 + 1)) &&
 	lines=$(($tens_of_lines * 10)) &&
 	readsize=$((($lines - 1) * 10 + 3)) &&
 	copysize=7 &&
-	rm -f input &&
-	mkfifo input &&
-	{
-		(
-			generate_tens_of_lines $tens_of_lines "$line" &&
-			exec sleep 100
-		) >input &
-	} &&
+	fill_input "generate_tens_of_lines $tens_of_lines $line" &&
 	test-line-buffer input <<-EOF >output &&
 	binary $readsize
 	copy $copysize
 	EOF
-	kill $! &&
 	test_line_count = $lines output &&
 	tail -n 1 <output >actual &&
 	test_cmp expect actual
@@ -79,18 +85,13 @@ test_expect_success 'hello world' '
 	test_cmp expect actual
 '
 
-test_expect_success PIPE '0-length read, no input available' '
+test_expect_success PIPE,EXECKEEPSPID '0-length read, no input available' '
 	printf ">" >expect &&
-	rm -f input &&
-	mkfifo input &&
-	{
-		sleep 100 >input &
-	} &&
+	fill_input : &&
 	test-line-buffer input <<-\EOF >actual &&
 	binary 0
 	copy 0
 	EOF
-	kill $! &&
 	test_cmp expect actual
 '
 
@@ -104,26 +105,20 @@ test_expect_success '0-length read, send along greeting' '
 	test_cmp expect actual
 '
 
-test_expect_success PIPE '1-byte read, no input available' '
+test_expect_success PIPE,EXECKEEPSPID '1-byte read, no input available' '
 	printf ">%s" ab >expect &&
-	rm -f input &&
-	mkfifo input &&
-	{
-		(
-			printf "%s" a &&
-			printf "%s" b &&
-			exec sleep 100
-		) >input &
-	} &&
+	fill_input "
+		printf a &&
+		printf b
+	" &&
 	test-line-buffer input <<-\EOF >actual &&
 	binary 1
 	copy 1
 	EOF
-	kill $! &&
 	test_cmp expect actual
 '
 
-test_expect_success PIPE 'long read (around 8192 bytes)' '
+test_expect_success PIPE,EXECKEEPSPID 'long read (around 8192 bytes)' '
 	long_read_test 8192
 '
 
-- 
1.7.4.2