automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/3] parallel-tests: optimize 'recheck' target for speed


From: Stefano Lattarini
Subject: [PATCH 2/3] parallel-tests: optimize 'recheck' target for speed
Date: Mon, 30 Apr 2012 17:54:02 +0200

With this change, the time required to execute the test case
'testsuite-recheck-speed.sh' has dropped as follows:

  + Slow Debian i686 system, 1 core x 1.5 GHz, 768 MB of RAM,
    GNU make 3.81:
      - 1 run: 6 minutes => 40 seconds

  + Fast Solaris 10 i686 system, 4 cores x 3 GHz, 20 GB of RAM,
    Solaris CCS make:
      - 4 runs: 3 minutes => 1 minute

  + Very fast Fedora ppc64 system, 64 cores x 3.5 GHz, 64 GB of RAM,
    GNU make 3.82:
      - 5 runs: 4 minutes => 1 minute 30 seconds

* lib/am/check.am (recheck): Optimize for speed, by avoiding lots of
forks with the help of ...
(am__list_recheck_tests): ... this new internal variable, basically
defining a proper awk program, and ...
(am__recheck_rx): ... this other new internal variable, used by the
one above.
* t/test-trs-recover2.sh: Relax by not checking for a very corner
case ('.log' and '.trs' files both unreadable) that we don't handle
anymore.

Signed-off-by: Stefano Lattarini <address@hidden>
---
 lib/am/check.am        |   95 +++++++++++++++++++++++++++++++++---------------
 t/test-trs-recover2.sh |   10 -----
 2 files changed, 66 insertions(+), 39 deletions(-)

diff --git a/lib/am/check.am b/lib/am/check.am
index 7866570..f2bfb6a 100644
--- a/lib/am/check.am
+++ b/lib/am/check.am
@@ -55,6 +55,57 @@ include inst-vars.am
 ## of more test metadata, and the use of custom test derivers and protocols
 ## (among them, TAP).
 
+am__recheck_rx = ^[    ]*:recheck:[    ]*
+
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+## By default, we assume the test is to be re-run.
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+## If we've encountered an I/O error here, there are three possibilities:
+##
+##  [1] The '.log' file exists, but the '.trs' does not; in this case,
+##      we "gracefully" recover by assuming the corresponding test is
+##      to be re-run (which will re-create the missing '.trs' file).
+##
+##  [2] Both the '.log' and '.trs' files are missing; this means that
+##      the corresponding test has not been run, and is thus *not* to
+##      be re-run.
+##
+##  [3] We have encountered some corner-case problem (e.g., a '.log' or
+##      '.trs' files somehow made unreadable, or issues with a bad NFS
+##      connection, or whatever); we don't handle such corner cases.
+##
+          if ((getline line2 < ($$0 ".log")) < 0) \
+           recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+## A directive explicitly specifying the test is *not* to be re-run.
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+## A directive explicitly specifying the test *is* to be re-run.
+          break; \
+        } \
+## else continue with the next iteration.
+    }; \
+  if (recheck) \
+    print $$0; \
+## Don't leak open file descriptors, as this could cause serious
+## problems when there are many tests (yes, even on Linux).
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+
 # Restructured Text title and section.
 am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
 am__rst_section = { sed 'p;s/./=/g;' && echo; }
@@ -326,36 +377,22 @@ check-TESTS recheck:
 ## cannot use '$?' to compute the set of lazily rerun tests, lest
 ## we rely on .PHONY to work portably.
        @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-       @ws='[  ]'; \
-       log_list='' trs_list=''; $(am__set_TESTS_bases); \
-       for i in $$bases; do \
+       @$(am__set_TESTS_bases); \
+       if test $@ = recheck; then \
 ## If running a "make recheck", we must only consider tests that had an
-## unexpected outcome (FAIL or XPASS) in the earlier run.  In particular,
-## skip tests that haven't been run.  But recover gracefully from deleted
-## '.trs' files.
-         if test $@ = recheck; then \
-           test -f $$i.trs || test -f $$i.log || continue; \
-## FIXME: one fork per test -- this is horrendously inefficient!
-           grep "^$$ws*:recheck:$$ws*no$$ws*$$" $$i.trs \
-             >/dev/null 2>&1 && continue; \
-         else :; fi; \
-## Be careful to avoid extra whitespace in the definition of $list, since
-## its value will be passed to the recursive make invocation below through
-## the TEST_LOGS macro, and leading/trailing white space in a make macro
-## definition can be problematic.  In this particular case, trailing white
-## space was known to cause a segmentation fault on Solaris 10 XPG4 make:
-## <http://lists.gnu.org/archive/html/bug-automake/2010-08/msg00004.html>
-         if test -z "$$log_list"; then \
-           log_list="$$i.log"; \
-         else \
-           log_list="$$log_list $$i.log"; \
-         fi; \
-         if test -z "$$trs_list"; then \
-           trs_list="$$i.trs"; \
-         else \
-           trs_list="$$trs_list $$i.trs"; \
-         fi; \
-       done; \
+## unexpected outcome (FAIL or XPASS) in the earlier run.
+         bases=`for i in $$bases; do echo $$i; done \
+                  | $(am__list_recheck_tests)` || exit 1; \
+       fi; \
+       log_list=`for i in $$bases; do echo $$i.log; done`; \
+       trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+## Remove newlines and normalize whitespace, being careful to avoid extra
+## whitespace in the definition of $log_list, since its value will be
+## passed to the recursive make invocation below through the TEST_LOGS
+## macro, and leading/trailing white space in a make macro definition can
+## be problematic.  In this particular case, trailing white space is known
+## to have caused segmentation faults on Solaris 10 XPG4 make:
+       log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
 ## Under "make recheck", remove the .log and .trs files associated
 ## with the files to recheck, so that those will be rerun by the
 ## "make test-suite.log" recursive invocation below.  But use a proper
diff --git a/t/test-trs-recover2.sh b/t/test-trs-recover2.sh
index 9726870..a154ce7 100755
--- a/t/test-trs-recover2.sh
+++ b/t/test-trs-recover2.sh
@@ -80,16 +80,6 @@ test -r bar.trs
 grep '^PASS: foo\.test' stdout
 grep '^PASS: bar\.test' stdout
 
-: More complex interactions with "make recheck" are OK.
-chmod a-r bar.log bar.trs
-$MAKE recheck >stdout || { cat stdout; Exit 1; }
-cat stdout
-test -f bar.trs
-test -r bar.trs
-grep '^PASS: bar\.test' stdout
-grep 'foo\.test' stdout && Exit 1
-count_test_results total=1 pass=1 fail=0 xpass=0 xfail=0 skip=0 error=0
-
 : Recreate by remaking the global test log.
 chmod a-r foo.trs
 rm -f test-suite.log
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]