This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Support cross-testing (version 3)


On Wed, 24 Oct 2012, Roland McGrath wrote:

> > +while true; do
> 
> Use [ $# -gt 0 ].

Done.

> > +    case "$1" in
> 
> Indent with two spaces, not four (throughout).

Done, though it seems odd for glibc to use different indentation for shell 
scripts from the default used by emacs.

> > +        "--ssh")
> > +            shift; ssh="$1"
> 
> Check for [ $# -gt 0 ] after shift (or -gt 1 before) and complain if not.

Now uses break in that case (so as to reach the existing error handling 
code).

> > +    sed -n \
> > +        -e '1h' \
> > +        -e '2,$H' \
> > +        -e '${g
> > +              s/["$\`]/\\&/g
> 
> This omits numerous metacharacters.  
> The standard set is: [][#;\"*?&|<>(){}$`^]

I've reworked this to use single quotes, so avoiding the need for such a 
list, and bash regular expression substitution, so avoiding the need for 
use of sed.

> > +# 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 |')"
> 
> $(...) always runs ... in a subshell, so the inner parens are superfluous.

The point is to ensure that the unsetting of PATH in blacklist_exports 
doesn't affect finding sed.

> The sed clause should just be in blacklist_exports.

I've moved it (with an explicit subshell inside there).

> > +# 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' ' '
> 
> Use echo -n.

No, echo -n simply wouldn't work here, because the string "-e" is used as 
an argument to a test program (globtest), and "echo -n -e" prints nothing.

I think use of printf is generally to be preferred to echo if printing a 
variable string and you don't want interpretation of "-n" or "-e"; it 
makes the intent clear to the reader, whereas using "echo -n" leaves the 
reader thinking about whether the special cases are possible and what was 
intended for them.  On that basis I'd prefer to avoid "echo" more or less 
entirely - so you don't need to think at all about what shells a script 
might run with, or about what special cases might occur in the arguments.  
But this patch reworks things so that there is only a single place, in 
bourne_quote, that strange strings are passed through such a command, and 
uses "echo -n" there as requested.

I'm running cross tests with this version (it also passes "make info html 
pdf").

2012-10-24  Joseph Myers  <joseph@codesourcery.com>
	    Jim Blandy  <jimb@codesourcery.com>

	* scripts/cross-test-ssh.sh: New file.
	* manual/install.texi (Configuring and compiling): Document use of
	cross-test-ssh.sh.
	* INSTALL: Regenerated.

diff --git a/INSTALL b/INSTALL
index d4fabe9..9c62786 100644
--- a/INSTALL
+++ b/INSTALL
@@ -196,7 +196,13 @@ this: `CC=TARGET-gcc configure TARGET'.  Set `BUILD_CC' to the compiler
 to use for programs run on the build system as part of compiling the
 library.  You may need to set `AR' to cross-compiling versions of `ar'
 if the native tools are not configured to work with object files for
-the target you configured for.
+the target you configured for.  When cross-compiling the GNU C Library,
+it may be tested using `make check
+test-wrapper="SRCDIR/scripts/cross-test-ssh.sh HOSTNAME"', where SRCDIR
+is the absolute directory name for the main source directory and
+HOSTNAME is the host name of a system that can run the newly built
+binaries of the GNU C Library.  The source and build directories must
+be visible at the same locations on both the build system and HOSTNAME.
 
 Installing the C Library
 ========================
diff --git a/manual/install.texi b/manual/install.texi
index 5aca058..c82b918 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -224,7 +224,14 @@ important to use this same @code{CC} value when running
 run on the build system as part of compiling the library.  You may need to
 set @code{AR} to cross-compiling versions of @code{ar}
 if the native tools are not configured to work with
-object files for the target you configured for.
+object files for the target you configured for.  When cross-compiling
+@theglibc{}, it may be tested using @samp{make check
+test-wrapper="@var{srcdir}/scripts/cross-test-ssh.sh @var{hostname}"},
+where @var{srcdir} is the absolute directory name for the main source
+directory and @var{hostname} is the host name of a system that can run
+the newly built binaries of @theglibc{}.  The source and build
+directories must be visible at the same locations on both the build
+system and @var{hostname}.
 
 
 @node Running make install
diff --git a/scripts/cross-test-ssh.sh b/scripts/cross-test-ssh.sh
new file mode 100755
index 0000000..f09c98e
--- /dev/null
+++ b/scripts/cross-test-ssh.sh
@@ -0,0 +1,148 @@
+#! /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 [ $# -gt 0 ]; do
+  case "$1" in
+
+    "--ssh")
+      shift
+      if [ $# -lt 1 ]; then
+        break
+      fi
+      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
+
+# Print the sequence of arguments as strings properly quoted for the
+# Bourne shell, separated by spaces.
+bourne_quote ()
+{
+  local arg qarg
+  for arg in "$@"; do
+    qarg=${arg//\'/\'\\\'\'}
+    echo -n "'$qarg' "
+  done
+}
+
+# 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.  The 'export -p' command adds backslashes for environment
+# variables which contain newlines.
+blacklist_exports ()
+{
+  (unset ${env_blacklist}; export -p) | remove_newlines
+}
+
+# Produce properly quoted Bourne shell arguments for 'env' to carry
+# over the current environment, less blacklisted variables.
+exports="$(blacklist_exports)"
+exports="${exports:+${exports}; }"
+
+# Transform the current argument list into a properly quoted Bourne shell
+# command string.
+command="$(bourne_quote "$@")"
+
+# 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="$(bourne_quote "${command}")"
+$ssh "$host" /bin/sh -c "$full_command"

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]