Subject: bug#11898: [PATCH] tests: verify the shell test scripts are syntactically valid

From: Stefano Lattarini <[email-masked]>
Date: Wed, 11 Jul 2012 11:30:35 +0200

Fixes automake bug#11898.

This measure of extra safety is mostly motivated by the fact that some
shells (at least some versions of Bash in the 3.x release series, one
of which severs as /bin/sh on Mac OS X 10.7, as well as Bash 4.0 and the
/usr/xpg4/bin/sh shell from Solaris 10) erroneously exit with exit status
0 upon encountering a syntax error, if an exit trap is sett (as it is in
our test scripts).

* Makefile.am (check-tests-syntax): New, check that the shell test
scripts listed in $(TESTS) are syntactically correct.
(.PHONY, check-local): Depend on it.
* t/self-check-exit.tap : Remove checks verifying that a script exits
with non-zero status upon encountering a syntax error; as explained
above, we can't depend on that.

Signed-off-by: Stefano Lattarini <[email-masked]>
---

 I plan to push this by this evening or tomorrow.

 Regards,
   Stefano

 Makefile.am           |   35 +++++++++++++++++++++++++++++++++++
 t/self-check-exit.tap |    8 +-------
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 2764481..5aa543e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -426,6 +426,41 @@ check-no-repeated-test-name:
 check-local: check-no-repeated-test-name
 .PHONY: check-no-repeated-test-name
 
+# Check that our test cases are syntactically correct.
+# See automake bug#11898.
+check-tests-syntax:
+	@st=0; \
+	err () { echo "$@: $$*" >&2; st=1; }; \
+## The user might do something like "make check TESTS=t/foo" or
+## "make check TESTS_LOGS=t/foo.log" and expect (say) the test
+## 't/foo.sh' to be run; this has worked well until today, and
+## we want to continue supporting this use case.
+	bases=`for log in : $(TEST_LOGS); do echo $$log; done \
+	  | sed -e '/^:$$/d' -e 's/\.log$$//'`; \
+	for bas in $$bases; do \
+	  for suf in sh tap pl; do \
+	    tst=$$bas.$$suf; \
+## Emulate VPATH search.
+	    if test -f $$tst; then \
+	      break; \
+	    elif test -f $(srcdir)/$$tst; then \
+	      tst=$(srcdir)/$$tst; \
+	      break; \
+	    else \
+	      tst=''; \
+	    fi; \
+	  done; \
+	  test -n "$$tst" || err "couldn't find test '$$bas'"; \
+## Don't check that perl tests are valid shell scripts!
+	  test $$suf = pl && continue; \
+	  $(AM_V_P) && echo " $(AM_TEST_RUNNER_SHELL) -n $$tst"; \
+	  $(AM_TEST_RUNNER_SHELL) -n "$$tst" \
+	    || err "test '$$tst' syntactically invalid"; \
+	done; \
+	exit $$st
+check-local: check-tests-syntax
+.PHONY: check-tests-syntax
+
 ## Checking the list of tests.
 test_subdirs = t t/pm t/perf
 include $(srcdir)/t/CheckListOfTests.am
diff --git a/t/self-check-exit.tap b/t/self-check-exit.tap
index 0fbc9d8..19cf27a 100755
--- a/t/self-check-exit.tap
+++ b/t/self-check-exit.tap
@@ -22,7 +22,7 @@
 am_create_testdir=no
 . ./defs || exit 99
 
-plan_ 34
+plan_ 32
 
 # This test becomes more cumbersome if we keep the 'errexit' shell flag
 # set.  And removing it is no big deal, as this test is a TAP-based one,
@@ -79,10 +79,4 @@ test -f Makefile && test ! -x Makefile || \
 $AM_TEST_RUNNER_SHELL -c "$init ./Makefile; :" "$dummy_test_script"
 command_ok_ "permission denied" test $? -gt 0
 
-: Syntax errors in the test code.
-$AM_TEST_RUNNER_SHELL -c "$init if :; then" "$dummy_test_script"
-command_ok_ "syntax error 1" test $? -gt 0
-$AM_TEST_RUNNER_SHELL -c "$init true ( true )" "$dummy_test_script"
-command_ok_ "syntax error 2" test $? -gt 0
-
 :
-- 
1.7.9.5