This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Support cross-testing (version 3)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Wed, 24 Oct 2012 20:37:21 +0000
- Subject: Support cross-testing (version 3)
This third version of the cross-testing changes uses test-wrapper and
test-wrapper-env as the variables to define wrappers. The "env"
program is only used directly in the default definition of
test-wrapper-env (so if you are testing in some way that doesn't allow
you to run that program on the host, you can define test-wrapper-env
in a different way appropriate to your test environment).
Tested x86_64 (native testing), and with cross to powerpc-linux-gnu
(testing over ssh).
2012-10-24 Joseph Myers <joseph@codesourcery.com>
Jim Blandy <jimb@codesourcery.com>
* Makeconfig (test-wrapper): New variable,
(test-wrapper-env): Likewise.
[$(cross-compiling) = yes && $(test-wrapper) != ""]
(run-built-tests): Define to yes.
(run-program-prefix): Use $(test-wrapper).
(built-program-cmd): Likewise.
* Rules (make-test-out): Use $(test-wrapper-env) and
$(host-built-program-cmd).
* elf/Makefile ($(objpfx)order.out): Use $(test-wrapper).
($(objpfx)tst-pathopt.out): Pass $(test-wrapper-env) to
tst-pathopt.sh.
($(objpfx)tst-rtld-load-self.out): Pass $(test-wrapper) and
$(test-wrapper-env) to tst-rtld-load-self.sh.
($(objpfx)order2.out): Use $(test-wrapper).
($(objpfx)tst-initorder.out): Likewise.
($(objpfx)tst-initorder2.out): Likewise.
($(objpfx)tst-unused-dep.out): Use $(test-wrapper-env).
* elf/tst-pathopt.sh (run_program_prefix): Remove unused variable.
(test_wrapper_env): New variable. Use it to run ld.so.
* elf/tst-rtld-load-self.sh (test_wrapper): New variable.
Use it to run ld.so.
(test_wrapper_env): Likewise.
* iconvdata/Makefile ($(objpfx)iconv-test.out): Pass
$(test-wrapper) to run-iconv-test.sh.
* iconvdata/run-iconv-test.sh (test_wrapper): New variable.
(ICONV): Use $test_wrapper.
* posix/Makefile ($(objpfx)globtest.out): Pass
$(run-via-rtld-prefix), $(test-wrapper) and $(test-wrapper-env) to
globtest.sh, not $(run-program-prefix).
* posix/globtest.sh (run_via_rtld_prefix): New variable.
(test_wrapper): Likewise.
(test_wrapper_env): Likewise. Use it to run globtest with HOME
set together with run_via_rtld_prefix.
(run_program_prefix): Define in terms of test_wrapper and
run_via_rtld_prefix.
* scripts/cross-test-ssh.sh: New file.
nptl:
2012-10-24 Joseph Myers <joseph@codesourcery.com>
Jim Blandy <jimb@codesourcery.com>
* Makefile ($(objpfx)tst-tls6.out): Pass $(test-wrapper-env) to
tst-tls6.sh.
* tst-tls6.sh (test_wrapper_env): New variable. Use it to run
programs with LD_PRELOAD set.
diff --git a/Makeconfig b/Makeconfig
index 1b1604a..087144c 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -564,13 +564,29 @@ endif
csu-objpfx = $(common-objpfx)csu/
elf-objpfx = $(common-objpfx)elf/
+# A command that, prepended to the name and arguments of a program,
+# and run on the build system, causes that program with those
+# arguments to be run on the host for which the library is built.
+ifndef test-wrapper
+test-wrapper =
+endif
+# Likewise, but the name of the program is preceded by
+# <variable>=<value> assignments for environment variables.
+ifndef test-wrapper-env
+test-wrapper-env = $(test-wrapper) env
+endif
+
# Whether to run test programs built for the library's host system.
ifndef run-built-tests
ifeq (yes,$(cross-compiling))
+ifeq (,$(test-wrapper))
run-built-tests = no
else
run-built-tests = yes
endif
+else
+run-built-tests = yes
+endif
endif
# How to run a program we just linked with our library.
@@ -600,12 +616,13 @@ endif
# of a program built with the newly built library, produces a command
# that, executed on the build system on which "make" is run, runs that
# program.
-run-program-prefix = $(run-via-rtld-prefix)
+run-program-prefix = $(test-wrapper) $(run-via-rtld-prefix)
# $(built-program-cmd) is a command that, executed on the build system
# on which "make" is run, runs the newly built program that is the
# second dependency of the makefile target in which
# $(built-program-cmd) is used.
-built-program-cmd = $(run-via-rtld-prefix) $(built-program-file)
+built-program-cmd = $(test-wrapper) \
+ $(run-via-rtld-prefix) $(built-program-file)
# $(host-built-program-cmd) is a command that, executed on the host
# for which the library is built, runs the newly built program that is
# the second dependency of the makefile target in which
diff --git a/Rules b/Rules
index db5bad0..35e6ce0 100644
--- a/Rules
+++ b/Rules
@@ -180,8 +180,9 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
# These are the implicit rules for making test outputs
# from the test programs and whatever input files are present.
-make-test-out = GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
- $($*-ENV) $(built-program-cmd) $($*-ARGS)
+make-test-out = $(test-wrapper-env) \
+ GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
+ $($*-ENV) $(host-built-program-cmd) $($*-ARGS)
$(objpfx)%-bp.out: %.input $(objpfx)%-bp
$(make-test-out) > $@ < $(word 1,$^)
$(objpfx)%.out: %.input $(objpfx)%
diff --git a/elf/Makefile b/elf/Makefile
index 4f092ab..f539f13 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -644,6 +644,7 @@ $(objpfx)circlemod2a.so: $(objpfx)circlemod3a.so
$(objpfx)order: $(addprefix $(objpfx),dep4.so dep3.so dep2.so dep1.so)
$(objpfx)order.out: $(objpfx)order
+ $(test-wrapper) \
$(elf-objpfx)$(rtld-installed-name) \
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
$(objpfx)order > $@
@@ -710,10 +711,10 @@ $(objpfx)lateglobal.out: $(objpfx)ltglobmod1.so $(objpfx)ltglobmod2.so
$(objpfx)tst-pathopt: $(libdl)
$(objpfx)tst-pathopt.out: tst-pathopt.sh $(objpfx)tst-pathopt \
$(objpfx)pathoptobj.so
- $(SHELL) $< $(common-objpfx)
+ $(SHELL) $< $(common-objpfx) '$(test-wrapper-env)'
$(objpfx)tst-rtld-load-self.out: tst-rtld-load-self.sh $(objpfx)ld.so
- $(SHELL) $^ > $@
+ $(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' > $@
$(objpfx)initfirst: $(libdl)
$(objpfx)initfirst.out: $(objpfx)firstobj.so
@@ -1035,6 +1036,7 @@ $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so
$(objpfx)order2: $(libdl)
$(objpfx)order2.out: $(objpfx)order2 $(objpfx)order2mod1.so \
$(objpfx)order2mod2.so
+ $(test-wrapper) \
$(elf-objpfx)$(rtld-installed-name) \
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
$(objpfx)order2 > $@
@@ -1129,6 +1131,7 @@ $(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
$(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so
$(objpfx)tst-initorder.out: $(objpfx)tst-initorder
+ $(test-wrapper) \
$(elf-objpfx)${rtld-installed-name} \
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
$< > $@
@@ -1150,6 +1153,7 @@ object-suffixes-left := a b c d
include $(o-iterator)
$(objpfx)tst-initorder2.out: $(objpfx)tst-initorder2
+ $(test-wrapper) \
$(elf-objpfx)${rtld-installed-name} \
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
$< > $@
@@ -1179,6 +1183,7 @@ tests: $(objpfx)tst-unused-dep.out
endif
$(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so
+ $(test-wrapper-env) \
LD_TRACE_LOADED_OBJECTS=1 \
LD_DEBUG=unused \
LD_PRELOAD= \
diff --git a/elf/tst-pathopt.sh b/elf/tst-pathopt.sh
index 048c612..2f8bfc6 100755
--- a/elf/tst-pathopt.sh
+++ b/elf/tst-pathopt.sh
@@ -20,7 +20,7 @@
set -e
common_objpfx=$1
-run_program_prefix=$2
+test_wrapper_env=$2
test -e ${common_objpfx}elf/will-be-empty &&
rm -fr ${common_objpfx}elf/will-be-empty
@@ -29,6 +29,7 @@ test -d ${common_objpfx}elf/for-renamed ||
cp ${common_objpfx}elf/pathoptobj.so ${common_objpfx}elf/for-renamed/renamed.so
+${test_wrapper_env} \
LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}iconvdata \
LC_ALL=C LD_LIBRARY_PATH=${common_objpfx}elf/will-be-empty:${common_objpfx}elf/for-renamed:${common_objpfx}.:${common_objpfx}dlfcn \
${common_objpfx}elf/ld.so ${common_objpfx}elf/tst-pathopt \
diff --git a/elf/tst-rtld-load-self.sh b/elf/tst-rtld-load-self.sh
index f4c5dea..18723a9 100755
--- a/elf/tst-rtld-load-self.sh
+++ b/elf/tst-rtld-load-self.sh
@@ -21,25 +21,28 @@
set -e
rtld=$1
+test_wrapper=$2
+test_wrapper_env=$3
result=0
echo '# normal mode'
-$rtld $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld $rtld 2>&1 && rc=0 || rc=$?
echo "# exit status $rc"
test $rc -le 127 || result=1
echo '# list mode'
-$rtld --list $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld --list $rtld 2>&1 && rc=0 || rc=$?
echo "# exit status $rc"
test $rc -eq 0 || result=1
echo '# verify mode'
-$rtld --verify $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld --verify $rtld 2>&1 && rc=0 || rc=$?
echo "# exit status $rc"
test $rc -eq 2 || result=1
echo '# trace mode'
-LD_TRACE_LOADED_OBJECTS=1 $rtld $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper_env} LD_TRACE_LOADED_OBJECTS=1 \
+ $rtld $rtld 2>&1 && rc=0 || rc=$?
echo "# exit status $rc"
test $rc -eq 0 || result=1
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 89f0dcd..2840cff 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -299,7 +299,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
$(common-objdir)/iconv/iconv_prog TESTS
- $(SHELL) $< $(common-objdir) > $@
+ $(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index cb9f5df..ec8f024 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -21,6 +21,7 @@
set -e
codir=$1
+test_wrapper="$2"
# We use always the same temporary file.
temp1=$codir/iconvdata/iconv-test.xxx
@@ -39,6 +40,7 @@ LIBPATH=$codir:$codir/iconvdata
# How the start the iconv(1) program.
ICONV='$codir/elf/ld.so --library-path $LIBPATH --inhibit-rpath ${from}.so \
$codir/iconv/iconv_prog'
+ICONV="$test_wrapper $ICONV"
# Which echo?
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
diff --git a/nptl/Makefile b/nptl/Makefile
index 21a8766..fc71177 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -476,7 +476,7 @@ $(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \
$(objpfx)tst-tls5modc.so $(objpfx)tst-tls5modd.so \
$(objpfx)tst-tls5mode.so $(objpfx)tst-tls5modf.so
$(SHELL) $< $(common-objpfx) $(elf-objpfx) \
- $(rtld-installed-name)
+ $(rtld-installed-name) '$(test-wrapper-env)'
endif
$(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
diff --git a/nptl/tst-tls6.sh b/nptl/tst-tls6.sh
index 2622e33..6ef1232 100755
--- a/nptl/tst-tls6.sh
+++ b/nptl/tst-tls6.sh
@@ -22,6 +22,7 @@ set -e
common_objpfx=$1; shift
elf_objpfx=$1; shift
rtld_installed_name=$1; shift
+test_wrapper_env=$1; shift
logfile=$common_objpfx/nptl/tst-tls6.out
# We have to find libc and nptl
@@ -40,33 +41,38 @@ fail=0
for aligned in a e f; do
echo "preload tst-tls5mod{$aligned,b,c,d}.so" >> $logfile
echo "===============" >> $logfile
- LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{$aligned,b,c,d}.so \
- | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+ ${test_wrapper_env} \
+ LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{$aligned,b,c,d}.so \
+ | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
echo >> $logfile
echo "preload tst-tls5mod{b,$aligned,c,d}.so" >> $logfile
echo "===============" >> $logfile
- LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{b,$aligned,c,d}.so \
- | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+ ${test_wrapper_env} \
+ LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{b,$aligned,c,d}.so \
+ | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
echo >> $logfile
echo "preload tst-tls5mod{b,c,d,$aligned}.so" >> $logfile
echo "===============" >> $logfile
- LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{b,c,d,$aligned}.so \
- | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+ ${test_wrapper_env} \
+ LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{b,c,d,$aligned}.so \
+ | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
echo >> $logfile
done
echo "preload tst-tls5mod{d,a,b,c,e}" >> $logfile
echo "===============" >> $logfile
-LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,c,e}.so \
- | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+${test_wrapper_env} \
+LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,c,e}.so \
+ | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
echo >> $logfile
echo "preload tst-tls5mod{d,a,b,e,f}" >> $logfile
echo "===============" >> $logfile
-LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,e,f}.so \
- | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+${test_wrapper_env} \
+LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,e,f}.so \
+ | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
echo >> $logfile
exit $fail
diff --git a/posix/Makefile b/posix/Makefile
index 86e6c6b..328738d 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -117,7 +117,8 @@ ifeq ($(run-built-tests),yes)
ifeq (yes,$(build-shared))
tests: $(objpfx)globtest.out $(objpfx)wordexp-tst.out
$(objpfx)globtest.out: globtest.sh $(objpfx)globtest
- $(SHELL) $< $(common-objpfx) '$(run-program-prefix)'
+ $(SHELL) $< $(common-objpfx) '$(run-via-rtld-prefix)' \
+ '$(test-wrapper)' '$(test-wrapper-env)'
$(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
$(SHELL) $< $(common-objpfx) '$(run-program-prefix)'
endif
diff --git a/posix/globtest.sh b/posix/globtest.sh
index ea947b8..121be85 100755
--- a/posix/globtest.sh
+++ b/posix/globtest.sh
@@ -20,7 +20,10 @@
set -e
common_objpfx=$1; shift
-run_program_prefix=$1; shift
+run_via_rtld_prefix=$1; shift
+test_wrapper=$1; shift
+test_wrapper_env=$1; shift
+run_program_prefix="${test_wrapper} ${run_via_rtld_prefix}"
logfile=$common_objpfx/posix/globtest.out
#CMP=cmp
@@ -758,8 +761,9 @@ cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
`dir6/file1[ab]'
`nondir\/'
EOF
+${test_wrapper_env} \
HOME="$testdir" \
-${run_program_prefix} \
+${run_via_rtld_prefix} \
${common_objpfx}posix/globtest -ct "$testdir" \
'~/dir1/file1_1' '~/dir1/file1_9' '~/dir3\*/file1' '~/dir3\*/file2' \
'~\/dir1/file1_2' |
diff --git a/scripts/cross-test-ssh.sh b/scripts/cross-test-ssh.sh
new file mode 100755
index 0000000..5dd3be4
--- /dev/null
+++ b/scripts/cross-test-ssh.sh
@@ -0,0 +1,156 @@
+#! /bin/bash
+# Run a testcase on a remote system, via ssh.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library 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 the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# usage: cross-test-ssh.sh [--ssh SSH] HOST COMMAND ...
+# Run with --help flag to get more detailed help.
+
+progname="$(basename $0)"
+env_blacklist='HOME LOGNAME MAIL PATH SHELL SHLVL SSH_CLIENT SSH_CONNECTION
+USER TERM TERMCAP PWD'
+
+usage="usage: ${progname} [--ssh SSH] HOST COMMAND ..."
+help="Run a glibc test COMMAND on the remote machine HOST, via ssh,
+passing environment variables, preserving the current working directory,
+and respecting quoting.
+
+If the '--ssh SSH' flag is present, use SSH as the SSH command,
+instead of ordinary 'ssh'.
+
+To use this to run glibc tests, invoke the tests as follows:
+
+ $ make test-wrapper='ABSPATH/cross-test-ssh.sh HOST' tests
+
+where ABSPATH is the absolute path to this script, and HOST is the
+name of the machine to connect to via ssh.
+
+If you need to connect to the test machine as a different user, you
+may specify that just as you would to SSH:
+
+ $ make test-wrapper='ABSPATH/cross-test-ssh.sh USER@HOST' tests
+
+Naturally, the remote user must have an appropriate public key, and
+you will want to ensure that SSH does not prompt interactively for a
+password on each connection.
+
+HOST and the build machines (on which 'make check' is being run) must
+share a filesystem; all files needed by the tests must be visible at
+the same paths on both machines.
+
+${progname} runs COMMAND in the same directory on the HOST that
+${progname} itself is run in on the build machine.
+
+The command and arguments are passed to the remote host in a way that
+avoids any further shell substitution or expansion, on the assumption
+that the shell on the build machine has already done them
+appropriately.
+
+${progname} propagates the values all environment variables through to
+the remote target, except the following:
+${env_blacklist}"
+
+ssh='ssh'
+while true; do
+ case "$1" in
+
+ "--ssh")
+ shift; ssh="$1"
+ ;;
+
+ "--help")
+ echo "$usage"
+ echo "$help"
+ exit 0
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+if [ $# -lt 1 ]; then
+ echo "$usage" >&2
+ echo "Type '${progname} --help' for more detailed help." >&2
+ exit 1
+fi
+
+host="$1"; shift
+
+# Return all input as a properly quoted Bourne shell string.
+bourne_quote ()
+{
+ printf '%s' '"'
+ sed -n \
+ -e '1h' \
+ -e '2,$H' \
+ -e '${g
+ s/["$\`]/\\&/g
+ p
+ }'
+ printf '%s' '"'
+}
+
+# Remove unnecessary newlines from a Bourne shell command sequence.
+remove_newlines ()
+{
+ sed -n \
+ -e '1h' \
+ -e '2,$H' \
+ -e '${g
+ s/\([^\]\)\n/\1; /g
+ p
+ }'
+}
+
+# Unset all variables from the blacklist. Then echo all exported
+# variables. This should be run in a subshell. The 'export -p'
+# command adds backslashes for environment variables which contain
+# newlines.
+blacklist_exports ()
+{
+ local var
+ for var in ${env_blacklist}; do
+ unset $var
+ done
+ export -p
+}
+
+# Produce properly quoted Bourne shell arguments for 'env' to carry
+# over the current environment, less blacklisted variables.
+exports="$( (blacklist_exports) | sed -e 's|^declare -x |export |')"
+
+# Transform the current argument list into a properly quoted Bourne shell
+# command string.
+command="$(for word in "$@"; do
+ printf '%s' "$word" | bourne_quote
+ printf '%s' ' '
+ done)"
+
+# Add commands to set environment variables and the current directory.
+command="${exports}
+cd $PWD
+${command}"
+
+# HOST's sshd simply concatenates its arguments with spaces and
+# passes them to some shell. We want to force the use of /bin/sh,
+# so we need to re-quote the whole command to ensure it appears as
+# the sole argument of the '-c' option.
+full_command="$(printf '%s\n' "${command}" | bourne_quote | remove_newlines)"
+$ssh "$host" /bin/sh -c "$full_command"
--
Joseph S. Myers
joseph@codesourcery.com