summaryrefslogtreecommitdiffstats
path: root/runtests.sh
diff options
context:
space:
mode:
Diffstat (limited to 'runtests.sh')
-rwxr-xr-xruntests.sh360
1 files changed, 360 insertions, 0 deletions
diff --git a/runtests.sh b/runtests.sh
new file mode 100755
index 0000000..0c463be
--- /dev/null
+++ b/runtests.sh
@@ -0,0 +1,360 @@
+#! /bin/sh
+
+# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
+# Copyright (C) 2003-2022 Wayne Davison
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version
+# 2 as published by the Free Software Foundation.
+#
+# 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# -------------------------------------------------------------------------
+
+# rsync top-level test script -- this invokes all the other more
+# detailed tests in order. This script can either be called by `make
+# check' or `make installcheck'. `check' runs against the copies of
+# the program and other files in the build directory, and
+# `installcheck' against the installed copy of the program.
+
+# It can also be called on a single test file using a run like this:
+#
+# preserve_scratch=yes whichtests=itemize.test ./runtests.sh
+
+# In either case we need to also be able to find the source directory,
+# since we read test scripts and possibly other information from
+# there.
+
+# Whenever possible, informational messages are written to stdout and
+# error messages to stderr. They're separated out by the build farm
+# display scripts.
+
+# According to the GNU autoconf manual, the only valid place to set up
+# directory locations is through Make, since users are allowed to (try
+# to) change their mind on the Make command line. So, Make has to
+# pass in all the values we need.
+
+# For other configured settings we read ./config.sh, which tells us
+# about shell commands on this machine and similar things.
+
+# rsync_bin gives the location of the rsync binary. This is either
+# builddir/rsync if we're testing an uninstalled copy, or
+# install_prefix/bin/rsync if we're testing an installed copy. On the
+# build farm rsync will be installed, but into a scratch /usr.
+
+# srcdir gives the location of the source tree, which lets us find the
+# build scripts. At the moment we assume we are invoked from the
+# source directory.
+
+# This script must be invoked from the build directory.
+
+# A scratch directory, 'testtmp', is used in the build directory to
+# hold per-test subdirectories.
+
+# This script also uses the $loglevel environment variable. 1 is the
+# default value, and 10 the most verbose. You can set this from the
+# Make command line. It's also set by the build farm to give more
+# detail for failing builds.
+
+# -------------------------------------------------------------------------
+
+# NOTES FOR TEST CASES:
+
+# Each test case runs in its own shell.
+
+# Exit codes from tests:
+
+# 1 tests failed
+# 2 error in starting tests
+# 77 this test skipped (random value unlikely to happen by chance, same as
+# automake)
+
+# HOWEVER, the overall exit code to the farm is different: we return
+# the *number of tests that failed*, so that it will show up nicely in
+# the overall summary.
+
+# rsync.fns contains some general setup functions and definitions.
+
+# -------------------------------------------------------------------------
+
+# NOTES ON PORTABILITY:
+
+# Both this script and the Makefile have to be pretty conservative
+# about which Unix features they use.
+
+# We cannot count on Make exporting variables to commands, unless
+# they're explicitly given on the command line.
+
+# Also, we can't count on 'cp -a' or 'mkdir -p', although they're
+# pretty handy (see function makepath for the latter).
+
+# I think some of the GNU documentation suggests that we shouldn't
+# rely on shell functions. However, the Bash manual seems to say that
+# they're in POSIX 1003.2, and since the build farm relies on them
+# they're probably working on most machines we really care about.
+
+# You cannot use "function foo {" syntax, but must instead say "foo()
+# {", or it breaks on FreeBSD.
+
+# BSD machines tend not to have "head" or "seq".
+
+# You cannot do "export VAR=VALUE" all on one line; the export must be
+# separate from the assignment. (SCO SysV)
+
+# Don't rely on grep -q, as that doesn't work everywhere -- just redirect
+# stdout to /dev/null to keep it quiet.
+
+# -------------------------------------------------------------------------
+
+# STILL TO DO:
+
+# We need a good protection against tests that hang indefinitely.
+# Perhaps some combination of starting them in the background, wait,
+# and kill?
+
+# Perhaps we need a common way to cleanup tests. At the moment just
+# clobbering the directory when we're done should be enough.
+
+# If any of the targets fail, then (GNU?) Make returns 2, instead of
+# the return code from the failing command. This is fine, but it
+# means that the build farm just shows "2" for failed tests, not the
+# number of tests that actually failed. For more details we might
+# need to grovel through the log files to find a line saying how many
+# failed.
+
+
+set -e
+
+. "./shconfig"
+
+RUNSHFLAGS='-e'
+export RUNSHFLAGS
+
+# for Solaris
+if [ -d /usr/xpg4/bin ]; then
+ PATH="/usr/xpg4/bin/:$PATH"
+ export PATH
+fi
+
+if [ "x$loglevel" != x ] && [ "$loglevel" -gt 8 ]; then
+ if set -x; then
+ # If it doesn't work the first time, don't keep trying.
+ RUNSHFLAGS="$RUNSHFLAGS -x"
+ fi
+fi
+
+POSIXLY_CORRECT=1
+if test x"$TOOLDIR" = x; then
+ TOOLDIR=`pwd`
+fi
+srcdir=`dirname $0`
+if test x"$srcdir" = x || test x"$srcdir" = x.; then
+ srcdir="$TOOLDIR"
+fi
+if test x"$rsync_bin" = x; then
+ rsync_bin="$TOOLDIR/rsync"
+fi
+
+# This allows the user to specify extra rsync options -- use carefully!
+RSYNC="$rsync_bin $*"
+#RSYNC="valgrind $rsync_bin $*"
+
+TLS_ARGS=''
+if grep -E '^#define HAVE_LUTIMES 1' config.h >/dev/null; then
+ TLS_ARGS="$TLS_ARGS -l"
+fi
+if grep -E '#undef CHOWN_MODIFIES_SYMLINK' config.h >/dev/null; then
+ TLS_ARGS="$TLS_ARGS -L"
+fi
+
+export POSIXLY_CORRECT TOOLDIR srcdir RSYNC TLS_ARGS
+
+echo "============================================================"
+echo "$0 running in $TOOLDIR"
+echo " rsync_bin=$RSYNC"
+echo " srcdir=$srcdir"
+echo " TLS_ARGS=$TLS_ARGS"
+
+if [ -f /usr/bin/whoami ]; then
+ testuser=`/usr/bin/whoami`
+elif [ -f /usr/ucb/whoami ]; then
+ testuser=`/usr/ucb/whoami`
+elif [ -f /bin/whoami ]; then
+ testuser=`/bin/whoami`
+else
+ testuser=`id -un 2>/dev/null || echo ${LOGNAME:-${USERNAME:-${USER:-'UNKNOWN'}}}`
+fi
+
+echo " testuser=$testuser"
+echo " os=`uname -a`"
+
+# It must be "yes", not just nonnull
+if [ "x$preserve_scratch" = xyes ]; then
+ echo " preserve_scratch=yes"
+else
+ echo " preserve_scratch=no"
+fi
+
+# Check if setacl/setfacl is around and if it supports the -k or -s option.
+if setacl -k u::7,g::5,o:5 testsuite 2>/dev/null; then
+ setfacl_nodef='setacl -k'
+elif setfacl --help 2>&1 | grep ' -k,\|\[-[a-z]*k' >/dev/null; then
+ setfacl_nodef='setfacl -k'
+elif setfacl -s u::7,g::5,o:5 testsuite 2>/dev/null; then
+ setfacl_nodef='setfacl -s u::7,g::5,o:5'
+else
+ # The "true" command runs successfully, but does nothing.
+ setfacl_nodef=true
+fi
+
+export setfacl_nodef
+
+if [ ! -f "$rsync_bin" ]; then
+ echo "rsync_bin $rsync_bin is not a file" >&2
+ exit 2
+fi
+
+if [ ! -d "$srcdir" ]; then
+ echo "srcdir $srcdir is not a directory" >&2
+ exit 2
+fi
+
+expect_skipped="${RSYNC_EXPECT_SKIPPED-IGNORE}"
+skipped_list=''
+skipped=0
+missing=0
+passed=0
+failed=0
+
+# Directory that holds the other test subdirs. We create separate dirs
+# inside for each test case, so that they can be left behind in case of
+# failure to aid investigation. We don't remove the testtmp subdir at
+# the end so that it can be configured as a symlink to a filesystem that
+# has ACLs and xattr support enabled (if desired).
+scratchbase="${scratchbase:-$TOOLDIR}"/testtmp
+echo " scratchbase=$scratchbase"
+[ -d "$scratchbase" ] || mkdir "$scratchbase"
+
+suitedir="$srcdir/testsuite"
+TESTRUN_TIMEOUT=300
+
+export scratchdir suitedir TESTRUN_TIMEOUT
+
+prep_scratch() {
+ [ -d "$scratchdir" ] && chmod -R u+rwX "$scratchdir" && rm -rf "$scratchdir"
+ mkdir "$scratchdir"
+ # Get rid of default ACLs and dir-setgid to avoid confusing some tests.
+ $setfacl_nodef "$scratchdir" 2>/dev/null || true
+ chmod g-s "$scratchdir"
+ case "$srcdir" in
+ /*) ln -s "$srcdir" "$scratchdir/src" ;;
+ *) ln -s "$TOOLDIR/$srcdir" "$scratchdir/src" ;;
+ esac
+ return 0
+}
+
+maybe_discard_scratch() {
+ [ x"$preserve_scratch" != xyes ] && [ -d "$scratchdir" ] && rm -rf "$scratchdir"
+ return 0
+}
+
+if [ "x$whichtests" = x ]; then
+ whichtests="*.test"
+ full_run=yes
+else
+ full_run=no
+fi
+
+for testscript in $suitedir/$whichtests; do
+ testbase=`echo $testscript | sed -e 's!.*/!!' -e 's/.test\$//'`
+ scratchdir="$scratchbase/$testbase"
+
+ prep_scratch
+
+ case "$testscript" in
+ *hardlinks*) TESTRUN_TIMEOUT=600 ;;
+ *) TESTRUN_TIMEOUT=300 ;;
+ esac
+
+ set +e
+ "$TOOLDIR/"testrun $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
+ result=$?
+ set -e
+
+ if [ "x$always_log" = xyes ] || ( [ $result != 0 ] && [ $result != 77 ] && [ $result != 78 ] )
+ then
+ echo "----- $testbase log follows"
+ cat "$scratchdir/test.log"
+ echo "----- $testbase log ends"
+ if [ -f "$scratchdir/rsyncd.log" ]; then
+ echo "----- $testbase rsyncd.log follows"
+ cat "$scratchdir/rsyncd.log"
+ echo "----- $testbase rsyncd.log ends"
+ fi
+ fi
+
+ case $result in
+ 0)
+ echo "PASS $testbase"
+ passed=`expr $passed + 1`
+ maybe_discard_scratch
+ ;;
+ 77)
+ # backticks will fill the whole file onto one line, which is a feature
+ whyskipped=`cat "$scratchdir/whyskipped"`
+ echo "SKIP $testbase ($whyskipped)"
+ skipped_list="$skipped_list,$testbase"
+ skipped=`expr $skipped + 1`
+ maybe_discard_scratch
+ ;;
+ 78)
+ # It failed, but we expected that. don't dump out error logs,
+ # because most users won't want to see them. But do leave
+ # the working directory around.
+ echo "XFAIL $testbase"
+ failed=`expr $failed + 1`
+ ;;
+ *)
+ echo "FAIL $testbase"
+ failed=`expr $failed + 1`
+ if [ "x$nopersist" = xyes ]; then
+ exit 1
+ fi
+ esac
+done
+
+echo '------------------------------------------------------------'
+echo "----- overall results:"
+echo " $passed passed"
+[ "$failed" -gt 0 ] && echo " $failed failed"
+[ "$skipped" -gt 0 ] && echo " $skipped skipped"
+[ "$missing" -gt 0 ] && echo " $missing missing"
+if [ "$full_run" = yes ] && [ "$expect_skipped" != IGNORE ]; then
+ skipped_list=`echo "$skipped_list" | sed 's/^,//'`
+ echo "----- skipped results:"
+ echo " expected: $expect_skipped"
+ echo " got: $skipped_list"
+else
+ skipped_list=''
+ expect_skipped=''
+fi
+echo '------------------------------------------------------------'
+
+# OK, so expr exits with 0 if the result is neither null nor zero; and
+# 1 if the expression is null or zero. This is the opposite of what
+# we want, and if we just call expr then this script will always fail,
+# because -e is set.
+
+result=`expr $failed + $missing || true`
+if [ "$result" = 0 ] && [ "$skipped_list" != "$expect_skipped" ]; then
+ result=1
+fi
+echo "overall result is $result"
+exit $result