tests: make distcheck invoke "make syntax-check" and other tests
authorJim Meyering <meyering@redhat.com>
Sun, 7 Feb 2010 11:21:36 +0000 (12:21 +0100)
committerJim Meyering <meyering@redhat.com>
Sun, 7 Feb 2010 11:21:36 +0000 (12:21 +0100)
* dist-check.mk: New file, from coreutils.
* cfg.mk: Include it.
* Makefile.am (distcheck-hook): New rule, to make us use it.

Makefile.am
cfg.mk
dist-check.mk [new file with mode: 0644]

index 26dfc436a6b4c9f54dddff40f8b594f6b08925cf..f285e6898ace953be49e7c24b374e4b4df433e5b 100644 (file)
@@ -17,6 +17,8 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
+ALL_RECURSIVE_TARGETS =
+
 SUBDIRS = lib doc
 ACLOCAL_AMFLAGS = -I m4
 AM_CPPFLAGS = -I$(top_srcdir)/lib
@@ -27,6 +29,7 @@ man_MANS = gunzip.1 gzexe.1 gzip.1 \
 
 EXTRA_DIST = $(ACINCLUDE_INPUTS) $(man_MANS) \
   ChangeLog-2007 \
+  dist-check.mk        \
   tests/hufts-segv.gz \
   algorithm.doc amiga/match.a amiga/Makefile.gcc amiga/Makefile.sasc \
   amiga/tailor.c amiga/utime.h atari/Makefile.st crypt.h \
@@ -141,6 +144,10 @@ install-exec-hook remove-installed-links:
 
 uninstall-local: remove-installed-links
 
+ALL_RECURSIVE_TARGETS += distcheck-hook
+distcheck-hook:
+       $(MAKE) my-distcheck
+
 MAINTAINERCLEANFILES = gzip.doc
 
 MOSTLYCLEANFILES = _match.i match_.s _match.S gzip.doc.gz \
@@ -173,6 +180,7 @@ TESTS_ENVIRONMENT =                         \
   abs_top_builddir='$(abs_top_builddir)'       \
   abs_top_srcdir='$(abs_top_srcdir)'           \
   abs_srcdir='$(abs_srcdir)'                   \
+  built_programs='$(PROGRAMS) $(SCRIPTS)'      \
   srcdir='$(srcdir)'                           \
   top_srcdir='$(top_srcdir)'                   \
   CC='$(CC)'                                   \
diff --git a/cfg.mk b/cfg.mk
index 136c96c3a6df9dd968800c228c2f5e4e7790a412..61e8cfe0365150ca6ddc0db8e06d34dba67459ee 100644 (file)
--- a/cfg.mk
+++ b/cfg.mk
@@ -61,3 +61,5 @@ sc_prohibit_emacs__indent_tabs_mode__setting:
        @re='^( *[*#] *)?indent-tabs-mode:'                             \
        msg='use of emacs indent-tabs-mode: setting'                    \
          $(_prohibit_regexp)
+
+include $(srcdir)/dist-check.mk
diff --git a/dist-check.mk b/dist-check.mk
new file mode 100644 (file)
index 0000000..6287dfe
--- /dev/null
@@ -0,0 +1,197 @@
+# Most of this is probably too coreutils-centric to be useful to other packages.
+
+bin=bin-$$$$
+
+write_loser = printf '\#!%s\necho $$0: bad path 1>&2; exit 1\n' '$(SHELL)'
+
+tmpdir = $(abs_top_builddir)/tests/torture
+
+t=$(tmpdir)/$(PACKAGE)/test
+pfx=$(t)/i
+
+built_programs =                                               \
+  $$(echo 'spy:;@echo $$(bin_PROGRAMS)'                                \
+    | MAKEFLAGS= $(MAKE) -s -f Makefile -f - spy               \
+    | fmt -1 | sed 's,$(EXEEXT)$$,,' | sort -u)
+
+# More than once, tainted build and source directory names would
+# have caused at least one "make check" test to apply "chmod 700"
+# to all directories under $HOME.  Make sure it doesn't happen again.
+tp = $(tmpdir)/taint
+t_prefix = $(tp)/a
+t_taint = '$(t_prefix) b'
+fake_home = $(tp)/home
+
+# When extracting from a distribution tarball, extract using the fastest
+# method possible.  With dist-xz, that means using the *.xz file.
+ifneq ('', $(filter *.xz, $(DIST_ARCHIVES)))
+  tar_decompress_opt_ = J
+  suffix_ = xz
+else
+  ifneq ('', $(filter *.gz, $(DIST_ARCHIVES)))
+    tar_decompress_opt_ = z
+    suffix_ = gz
+  else
+    tar_decompress_opt_ = j
+    suffix_ = bz2
+  endif
+endif
+amtar_extract_ = $(AMTAR) -$(tar_decompress_opt_)xf
+preferred_tarball_ = $(distdir).tar.$(suffix_)
+
+# Ensure that tests run from tainted build and src dir names work,
+# and don't affect anything in $HOME.  Create witness files in $HOME,
+# record their attributes, and build/test.  Then ensure that the
+# witnesses were not affected.
+# Skip this test when using libtool, since libtool-generated scripts
+# cannot deal with a space-tainted srcdir.
+ALL_RECURSIVE_TARGETS += taint-distcheck
+taint-distcheck: $(DIST_ARCHIVES)
+       grep '^[         ]*LT_INIT' configure.ac >/dev/null && exit 0 || :
+       test -d $(t_taint) && chmod -R 700 $(t_taint) || :
+       -rm -rf $(t_taint) $(fake_home)
+       mkdir -p $(t_prefix) $(t_taint) $(fake_home)
+       $(amtar_extract_) $(preferred_tarball_) -C $(t_taint)
+       mkfifo $(fake_home)/fifo
+       touch $(fake_home)/f
+       mkdir -p $(fake_home)/d/e
+       ls -lR $(fake_home) $(t_prefix) > $(tp)/.ls-before
+       HOME=$(fake_home); export HOME;                 \
+       cd $(t_taint)/$(distdir)                        \
+         && ./configure                                \
+         && $(MAKE)                                    \
+         && $(MAKE) check                              \
+         && ls -lR $(fake_home) $(t_prefix) > $(tp)/.ls-after \
+         && diff $(tp)/.ls-before $(tp)/.ls-after      \
+         && test -d $(t_prefix)
+       rm -rf $(tp)
+
+# Verify that a twisted use of --program-transform-name=PROGRAM works.
+define install-transform-check
+  echo running install-transform-check                 \
+    && rm -rf $(pfx)                                   \
+    && $(MAKE) program_transform_name='s/.*/zyx/'      \
+      prefix=$(pfx) install                            \
+    && test "$$(echo $(pfx)/bin/*)" = "$(pfx)/bin/zyx" \
+    && test "$$(find $(pfx)/share/man -type f|sed 's,.*/,,;s,\..*,,')" = "zyx"
+endef
+
+# Install, then verify that all binaries and man pages are in place.
+# Note that neither the binary, ginstall, nor the [.1 man page is installed.
+define my-instcheck
+  echo running my-instcheck;                           \
+  $(MAKE) prefix=$(pfx) install                                \
+    && test ! -f $(pfx)/bin/ginstall                   \
+    && { fail=0;                                       \
+      for i in $(built_programs); do                   \
+        test "$$i" = ginstall && i=install;            \
+        for j in "$(pfx)/bin/$$i"                      \
+                 "$(pfx)/share/man/man1/$$i.1"; do     \
+          case $$j in *'[.1') continue;; esac;         \
+          test -f "$$j" && :                           \
+            || { echo "$$j not installed"; fail=1; };  \
+        done;                                          \
+      done;                                            \
+      test $$fail = 1 && exit 1 || :;                  \
+    }
+endef
+
+# The hard-linking for-loop below ensures that there is a bin/ directory
+# full of all of the programs under test (except the ones that are required
+# for basic Makefile rules), all symlinked to the just-built "false" program.
+# This is to ensure that if ever a test neglects to make PATH include
+# the build srcdir, these always-failing programs will run.
+# Otherwise, it is too easy to test the wrong programs.
+# Note that "false" itself is a symlink to true, so it too will malfunction.
+define coreutils-path-check
+  {                                                    \
+    echo running coreutils-path-check;                 \
+    if test -f $(srcdir)/src/true.c; then              \
+      fail=1;                                          \
+      mkdir $(bin)                                     \
+       && ($(write_loser)) > $(bin)/loser              \
+       && chmod a+x $(bin)/loser                       \
+       && for i in $(built_programs); do               \
+              case $$i in                              \
+                rm|expr|basename|echo|sort|ls|tr);;    \
+                cat|dirname|mv|wc);;                   \
+                *) ln $(bin)/loser $(bin)/$$i;;        \
+              esac;                                    \
+            done                                       \
+         && ln -sf ../src/true $(bin)/false            \
+         && PATH=`pwd`/$(bin)$(PATH_SEPARATOR)$$PATH   \
+               $(MAKE) -C tests check                  \
+         && { test -d gnulib-tests                     \
+                && $(MAKE) -C gnulib-tests check       \
+                || :; }                                \
+         && rm -rf $(bin)                              \
+         && fail=0;                                    \
+    else                                               \
+      fail=0;                                          \
+    fi;                                                        \
+    test $$fail = 1 && exit 1 || :;                    \
+  }
+endef
+
+# More generic version of the rule above.
+define generic-path-check
+  {                                                    \
+    echo running generic-path-check;                   \
+    if test -f /bin/false; then                                \
+      fail=1;                                          \
+      mkdir $(bin)                                     \
+       && ($(write_loser)) > $(bin)/loser              \
+       && chmod a+x $(bin)/loser                       \
+       && for i in $(built_programs); do               \
+            ln $(bin)/loser $(bin)/$$i;                \
+          done                                         \
+       && PATH=`pwd`/$(bin)$(PATH_SEPARATOR)$$PATH     \
+            $(MAKE) check                              \
+       && { test -d gnulib-tests                       \
+              && $(MAKE) -C gnulib-tests check         \
+              || :; }                                  \
+       && rm -rf $(bin)                                \
+       && fail=0;                                      \
+    else                                               \
+      fail=0;                                          \
+    fi;                                                        \
+    test $$fail = 1 && exit 1 || :;                    \
+  }
+endef
+
+# Use this to make sure we don't run these programs when building
+# from a virgin compressed tarball file, below.
+null_AM_MAKEFLAGS ?= \
+  ACLOCAL=false \
+  AUTOCONF=false \
+  AUTOMAKE=false \
+  AUTOHEADER=false \
+  GPERF=false \
+  MAKEINFO=false
+
+ALL_RECURSIVE_TARGETS += my-distcheck
+my-distcheck: $(DIST_ARCHIVES) $(local-check)
+       $(MAKE) syntax-check
+       $(MAKE) check
+       -rm -rf $(t)
+       mkdir -p $(t)
+       $(amtar_extract_) $(preferred_tarball_) -C $(t)
+       (set -e; cd $(t)/$(distdir);                    \
+         ./configure --quiet --enable-gcc-warnings --disable-nls; \
+         $(MAKE) AM_MAKEFLAGS='$(null_AM_MAKEFLAGS)';  \
+         $(MAKE) dvi;                                  \
+         $(install-transform-check);                   \
+         $(my-instcheck);                              \
+         $(coreutils-path-check);                      \
+         $(generic-path-check);                        \
+         $(MAKE) distclean                             \
+       )
+       (cd $(t) && mv $(distdir) $(distdir).old        \
+         && $(amtar_extract_) - ) < $(preferred_tarball_)
+       diff -ur $(t)/$(distdir).old $(t)/$(distdir)
+       -rm -rf $(t)
+       rmdir $(tmpdir)/$(PACKAGE) $(tmpdir)
+       @echo "========================"; \
+       echo "ready for distribution:"; \
+       for i in $(DIST_ARCHIVES); do echo "  $$i"; done; \
+       echo "========================"