Here are a few patches I'll push tomorrow. The first is technically a bug fix. It was exposed by the tests added in 3/4.
[PATCH 1/4] zcmp: consistently indicate failure with exit status of 2 [PATCH 2/4] tests: make distcheck invoke "make syntax-check" and other tests [PATCH 3/4] tests: add the help-version sanity tests from coreutils [PATCH 4/4] doc: minor adjustment to README-release >From 4d356e268da6e97856a4d9a2ea09c8dca71262fb Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 7 Feb 2010 12:04:22 +0100 Subject: [PATCH 1/4] zcmp: consistently indicate failure with exit status of 2 * zcmp.in: Exit with status of 2 (not 1), when writing --help or --version output fails, to be more like cmp. --- zcmp.in | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/zcmp.in b/zcmp.in index d3fb956..c3476cf 100644 --- a/zcmp.in +++ b/zcmp.in @@ -1,7 +1,7 @@ #!/bin/sh # Compare the uncompressed contents of compressed files, byte by byte. -# Copyright (C) 2007 Free Software Foundation +# Copyright (C) 2007-2010 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -42,9 +42,10 @@ If a FILE is '-' or missing, read standard input. Report bugs to <bug-gzip@gnu.org>." +st=0 case $1 in ---help) exec echo "$usage";; ---version) exec echo "$version";; +--help) echo "$usage" || st=2; exit $st;; +--version) echo "$version" || st=2; exit $st;; esac exec zdiff --__cmp "$@" -- 1.7.0.rc1.214.gd5f8a >From 7d83690c52507a0ad059028a356aabce56d7fb6b Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 7 Feb 2010 12:21:36 +0100 Subject: [PATCH 2/4] tests: make distcheck invoke "make syntax-check" and other tests * dist-check.mk: New file, from coreutils. * cfg.mk: Include it. * Makefile.am (distcheck-hook): New rule, to make us use it. --- Makefile.am | 8 +++ cfg.mk | 2 + dist-check.mk | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 0 deletions(-) create mode 100644 dist-check.mk diff --git a/Makefile.am b/Makefile.am index 26dfc43..f285e68 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 136c96c..61e8cfe 100644 --- 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 index 0000000..6287dfe --- /dev/null +++ b/dist-check.mk @@ -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 "========================" -- 1.7.0.rc1.214.gd5f8a >From e707c8a875eda329578b5cda879215d3c9129137 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 7 Feb 2010 12:22:58 +0100 Subject: [PATCH 3/4] tests: add the help-version sanity tests from coreutils * tests/help-version: New file, from coreutils. * Makefile.am (TESTS): Add it. --- Makefile.am | 1 + tests/help-version | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+), 0 deletions(-) create mode 100755 tests/help-version diff --git a/Makefile.am b/Makefile.am index f285e68..816e9f4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -104,6 +104,7 @@ check-local: $(FILES_TO_CHECK) $(bin_PROGRAMS) gzip.doc.gz TESTS = \ tests/helin-segv \ + tests/help-version \ tests/hufts \ tests/memcpy-abuse \ tests/mixed \ diff --git a/tests/help-version b/tests/help-version new file mode 100755 index 0000000..ebdc69a --- /dev/null +++ b/tests/help-version @@ -0,0 +1,237 @@ +#! /bin/sh +# Make sure all these programs work properly +# when invoked with --help or --version. + +# Copyright (C) 2000-2010 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +test "$VERBOSE" = yes && set -x + +# Ensure that $SHELL is set to *some* value and exported. +# This is required for dircolors, which would fail e.g., when +# invoked via debuild (which removes SHELL from the environment). +test "x$SHELL" = x && SHELL=/bin/sh +export SHELL + +: ${srcdir=.} +. "$srcdir/tests/init.sh" + +expected_failure_status_chroot=125 +expected_failure_status_env=125 +expected_failure_status_nice=125 +expected_failure_status_nohup=125 +expected_failure_status_stdbuf=125 +expected_failure_status_su=125 +expected_failure_status_timeout=125 +expected_failure_status_printenv=2 +expected_failure_status_tty=3 +expected_failure_status_sort=2 +expected_failure_status_expr=3 +expected_failure_status_lbracket=2 +expected_failure_status_dir=2 +expected_failure_status_ls=2 +expected_failure_status_vdir=2 + +expected_failure_status_cmp=2 +expected_failure_status_zcmp=2 +expected_failure_status_sdiff=2 +expected_failure_status_diff3=2 +expected_failure_status_diff=2 +expected_failure_status_zdiff=2 +expected_failure_status_zgrep=2 +expected_failure_status_zegrep=2 +expected_failure_status_zfgrep=2 + +test "$built_programs" \ + || { echo "$this_test: no programs built!?!" 1>&2; Exit 1; } + +for lang in C fr da; do + for i in $built_programs; do + + # Skip `test'; it doesn't accept --help or --version. + test $i = test && continue; + + # false fails even when invoked with --help or --version. + if test $i = false; then + env LC_MESSAGES=$lang $i --help >/dev/null && fail=1 + env LC_MESSAGES=$lang $i --version >/dev/null && fail=1 + continue + fi + + # The just-built install executable is always named `ginstall'. + test $i = install && i=ginstall + + # Make sure they exit successfully, under normal conditions. + env $i --help > h-$i || fail=1 + env $i --version >/dev/null || fail=1 + + # Make sure they mention the bug-reporting address in --help output. + grep "$PACKAGE_BUGREPORT" h-$i > /dev/null || fail=1 + rm -f h-$i + + # Make sure they fail upon `disk full' error. + if test -w /dev/full && test -c /dev/full; then + env $i --help >/dev/full 2>/dev/null && fail=1 + env $i --version >/dev/full 2>/dev/null && fail=1 + status=$? + test $i = [ && prog=lbracket || prog=$i + eval "expected=\$expected_failure_status_$prog" + test x$expected = x && expected=1 + if test $status = $expected; then + : # ok + else + fail=1 + echo "*** $i: bad exit status \`$status' (expected $expected)," 1>&2 + echo " with --help or --version output redirected to /dev/full" 1>&2 + fi + fi + done +done + +bigZ_in=bigZ-in.Z +zin=zin.gz +zin2=zin2.gz + +tmp=tmp-$$ +tmp_in=in-$$ +tmp_in2=in2-$$ +tmp_dir=dir-$$ +tmp_out=out-$$ +mkdir $tmp || fail=1 +cd $tmp || fail=1 + +comm_args="$tmp_in $tmp_in" +csplit_args="$tmp_in //" +cut_args='-f 1' +join_args="$tmp_in $tmp_in" +tr_args='a a' + +chmod_args="a+x $tmp_in" +# Punt on these. +chgrp_args=--version +chown_args=--version +mkfifo_args=--version +mknod_args=--version +# Punt on uptime, since it fails (e.g., failing to get boot time) +# on some systems, and we shouldn't let that stop `make check'. +uptime_args=--version + +# Create a file in the current directory, not in $TMPDIR. +mktemp_args=mktemp.XXXX + +cmp_args="$tmp_in $tmp_in2" + +# Tell dd not to print the line with transfer rate and total. +# The transfer rate would vary between runs. +dd_args=status=noxfer + +zdiff_args="$zin $zin2" +zcmp_args="$zin $zin2" +zcat_args=$zin +gunzip_args=$zin +zmore_args=$zin +zless_args=$zin +znew_args=$bigZ_in +zforce_args=$zin +zgrep_args="z $zin" +zegrep_args="z $zin" +zfgrep_args="z $zin" +gzexe_args=$tmp_in + +diff_args="$tmp_in $tmp_in2" +sdiff_args="$tmp_in $tmp_in2" +diff3_args="$tmp_in $tmp_in2 $tmp_in2" +cp_args="$tmp_in $tmp_in2" +ln_args="$tmp_in ln-target" +ginstall_args="$tmp_in $tmp_in2" +mv_args="$tmp_in $tmp_in2" +mkdir_args=$tmp_dir/subdir +rmdir_args=$tmp_dir +rm_args=$tmp_in +shred_args=$tmp_in +touch_args=$tmp_in2 +truncate_args="--reference=$tmp_in $tmp_in2" + +basename_args=$tmp_in +dirname_args=$tmp_in +expr_args=foo + +# Punt, in case GNU `id' hasn't been installed yet. +groups_args=--version + +pathchk_args=$tmp_in +yes_args=--version +logname_args=--version +nohup_args=--version +printf_args=foo +seq_args=10 +sleep_args=0 +su_args=--version +stdbuf_args="-oL true" +timeout_args=--version + +# I'd rather not run sync, since it spins up disks that I've +# deliberately caused to spin down (but not unmounted). +sync_args=--version + +test_args=foo + +# This is necessary in the unusual event that there is +# no valid entry in /etc/mtab. +df_args=/ + +# This is necessary in the unusual event that getpwuid (getuid ()) fails. +id_args=-u + +# Use env to avoid invoking built-in sleep of Solaris 11's /bin/sh. +env sleep 10m & +kill_args=$! + +link_args="$tmp_in link-target" +unlink_args=$tmp_in + +ln -s . slink +readlink_args=slink + +stat_args=$tmp_in +unlink_args=$tmp_in +lbracket_args=": ]" + +# Ensure that each program "works" (exits successfully) when doing +# something more than --help or --version. +for i in $built_programs; do + # Skip these. + case $i in chroot|stty|tty|false|chcon|runcon) continue;; esac + + rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out $bigZ_in $zin $zin2 + echo z |gzip > $zin + cp $zin $zin2 + cp $zin $bigZ_in + echo > $tmp_in + echo > $tmp_in2 + mkdir $tmp_dir + # echo ================== $i + test $i = [ && prog=lbracket || prog=$i + eval "args=\$${prog}_args" + if env $i $args < $tmp_in > $tmp_out; then + : # ok + else + echo FAIL: $i + fail=1 + fi + rm -rf $tmp_in $tmp_in2 $tmp_out $tmp_dir +done + +Exit $fail -- 1.7.0.rc1.214.gd5f8a >From a68cb1221c4989eb521b198ac340bcf5809dcd5c Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 7 Feb 2010 12:24:07 +0100 Subject: [PATCH 4/4] doc: minor adjustment to README-release * README-release: Tweak description, to sync from coreutils. --- README-release | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/README-release b/README-release index 662c2b2..f336ac8 100644 --- a/README-release +++ b/README-release @@ -13,7 +13,9 @@ Here are most of the steps we (maintainers) follow when making a release. * Ensure that you're on "master" with no uncommitted diffs. This should produce no output: git checkout master; git diff -* Run bootstrap: ./bootstrap +* Run bootstrap one last time. This downloads any new translations: + + ./bootstrap * Pre-release testing: Ensure that make check syntax-check succeeds. -- 1.7.0.rc1.214.gd5f8a