827651b074
Reviewed-on: https://go-review.googlesource.com/c/145057 From-SVN: r265541
697 lines
14 KiB
Bash
Executable File
697 lines
14 KiB
Bash
Executable File
#!/bin/sh
|
|
# Copyright 2009 The Go Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style
|
|
# license that can be found in the LICENSE file.
|
|
|
|
# Using all the *_test.go files in the current directory, write out a file
|
|
# _testmain.go that runs all its tests. Compile everything and run the
|
|
# tests.
|
|
# If files are named on the command line, use them instead of *_test.go.
|
|
|
|
# Makes egrep,grep work better in general if we put them
|
|
# in ordinary C mode instead of what the current language is.
|
|
LANG=C
|
|
LC_ALL=C
|
|
LC_CTYPE=C
|
|
export LANG LC_ALL LC_CTYPE
|
|
|
|
GC=${GC:-gccgo}
|
|
GL=${GL:-${GC-gccgo}}
|
|
GOLIBS=${GOLIBS:-}
|
|
export GC GL GOLIBS
|
|
|
|
NM=${NM:-nm}
|
|
|
|
# srcdir is where the source files are found. basedir is where the
|
|
# source file paths are relative to.
|
|
# gofiles are the test files. pkgfiles are the source files.
|
|
srcdir=.
|
|
basedir=.
|
|
goarch=""
|
|
gofiles=""
|
|
goos=""
|
|
pkgfiles=""
|
|
loop=true
|
|
keep=false
|
|
pkgpath=
|
|
prefix=
|
|
dejagnu=no
|
|
timeout=240
|
|
testname=""
|
|
bench=""
|
|
trace=false
|
|
while $loop; do
|
|
case "x$1" in
|
|
x--srcdir)
|
|
srcdir=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--srcdir=*)
|
|
srcdir=`echo $1 | sed -e 's/^--srcdir=//'`
|
|
shift
|
|
;;
|
|
x--basedir)
|
|
basedir=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--basedir=*)
|
|
basedir=`echo $1 | sed -e 's/^--basedir=//'`
|
|
shift
|
|
;;
|
|
x--goarch)
|
|
goarch=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--goarch=*)
|
|
goarch=`echo $1 | sed -e 's/^--goarch=//'`
|
|
shift
|
|
;;
|
|
x--goos)
|
|
goos=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--goos=*)
|
|
goos=`echo $1 | sed -e 's/^--goos=//'`
|
|
shift
|
|
;;
|
|
x--pkgpath)
|
|
pkgpath=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--pkgpath=*)
|
|
pkgpath=`echo $1 | sed -e 's/^--pkgpath=//'`
|
|
shift
|
|
;;
|
|
x--prefix)
|
|
prefix=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--prefix=*)
|
|
prefix=`echo $1 | sed -e 's/^--prefix=//'`
|
|
shift
|
|
;;
|
|
x--keep)
|
|
keep=true
|
|
shift
|
|
;;
|
|
x--pkgfiles)
|
|
pkgfiles=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--pkgfiles=*)
|
|
pkgfiles=`echo $1 | sed -e 's/^--pkgfiles=//'`
|
|
shift
|
|
;;
|
|
x--dejagnu)
|
|
dejagnu=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--dejagnu=*)
|
|
dejagnu=`echo $1 | sed -e 's/^--dejagnu=//'`
|
|
shift
|
|
;;
|
|
x--timeout)
|
|
timeout=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--timeout=*)
|
|
timeout=`echo $1 | sed -e 's/^--timeout=//'`
|
|
shift
|
|
;;
|
|
x--testname)
|
|
testname=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--testname=*)
|
|
testname=`echo $1 | sed -e 's/^--testname=//'`
|
|
shift
|
|
;;
|
|
x--bench)
|
|
bench=$2
|
|
shift
|
|
shift
|
|
;;
|
|
x--bench=*)
|
|
bench=`echo $1 | sed -e 's/^--bench=//'`
|
|
shift
|
|
;;
|
|
x--trace)
|
|
trace=true
|
|
shift
|
|
;;
|
|
x-*)
|
|
loop=false
|
|
;;
|
|
x)
|
|
loop=false
|
|
;;
|
|
*)
|
|
gofiles="$gofiles $1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
DIR=gotest$$
|
|
rm -rf $DIR
|
|
mkdir $DIR
|
|
|
|
cd $DIR
|
|
mkdir test
|
|
cd test
|
|
|
|
if test $keep = false; then
|
|
trap "cd ../..; rm -rf $DIR" 0 1 2 3 14 15
|
|
else
|
|
trap "cd ../..; echo Keeping $DIR" 0 1 2 3 14 15
|
|
fi
|
|
|
|
case "$srcdir" in
|
|
/*)
|
|
;;
|
|
*)
|
|
srcdir="../../$srcdir"
|
|
;;
|
|
esac
|
|
|
|
SRCDIR=$srcdir
|
|
export SRCDIR
|
|
|
|
case "$basedir" in
|
|
/*)
|
|
;;
|
|
*)
|
|
basedir="../../$basedir"
|
|
;;
|
|
esac
|
|
|
|
# Link all the files/directories in srcdir into our working directory,
|
|
# so that the tests do not have to refer to srcdir to find test data.
|
|
ln -s $srcdir/* .
|
|
|
|
# Some tests refer to a ../testdata directory.
|
|
if test -e $srcdir/../testdata; then
|
|
rm -f ../testdata
|
|
abssrcdir=`cd $srcdir && pwd`
|
|
ln -s $abssrcdir/../testdata ../testdata
|
|
fi
|
|
|
|
# Copy the .go files because io/utils_test.go expects a regular file.
|
|
case "x$gofiles" in
|
|
x)
|
|
case "x$pkgfiles" in
|
|
x)
|
|
for f in `cd $srcdir; ls *.go`; do
|
|
rm -f $f;
|
|
cp $srcdir/$f .
|
|
done
|
|
;;
|
|
*)
|
|
for f in $pkgfiles; do
|
|
case $f in
|
|
/*)
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp $f $b
|
|
;;
|
|
*)
|
|
if test -f $basedir/$f; then
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp $basedir/$f $b
|
|
elif test -f ../../$f; then
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp ../../$f $b
|
|
else
|
|
echo "file $f not found" 1>&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
for f in `cd $srcdir; ls *_test.go`; do
|
|
rm -f $f
|
|
cp $srcdir/$f .
|
|
done
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
for f in $gofiles; do
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp $basedir/$f $b
|
|
done
|
|
case "x$pkgfiles" in
|
|
x)
|
|
for f in `cd $srcdir; ls *.go | grep -v *_test.go`; do
|
|
rm -f $f
|
|
cp $srcdir/$f .
|
|
done
|
|
;;
|
|
*)
|
|
for f in $pkgfiles; do
|
|
case $f in
|
|
/*)
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp $f $b
|
|
;;
|
|
*)
|
|
if test -f $basedir/$f; then
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp $basedir/$f $b
|
|
elif test -f ../../$f; then
|
|
b=`basename $f`
|
|
rm -f $b
|
|
cp ../../$f $b
|
|
else
|
|
echo "file $f not found" 1>&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
# Some tests expect the _obj directory created by the gc Makefiles.
|
|
mkdir _obj
|
|
|
|
# Some tests expect the _test directory created by the gc Makefiles.
|
|
mkdir _test
|
|
|
|
case "x$gofiles" in
|
|
x)
|
|
for f in `ls *_test.go`; do
|
|
tag1=`echo $f | sed -e 's/^.*_\([^_]*\)_test.go$/\1/'`
|
|
tag2=`echo $f | sed -e 's/^.*_\([^_]*\)_[^_]*_test.go$/\1/'`
|
|
if test x$tag1 = x$f; then
|
|
tag1=
|
|
fi
|
|
if test x$tag2 = x$f; then
|
|
tag2=
|
|
fi
|
|
|
|
case "$tag1" in
|
|
"") ;;
|
|
$goarch) ;;
|
|
$goos) ;;
|
|
aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
|
|
tag1=nonmatchingtag
|
|
;;
|
|
386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm)
|
|
tag1=nonmatchingtag
|
|
;;
|
|
esac
|
|
|
|
case "$tag2" in
|
|
"") ;;
|
|
$goarch) ;;
|
|
$goos) ;;
|
|
aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
|
|
tag2=nonmatchingtag
|
|
;;
|
|
386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm)
|
|
tag2=nonmatchingtag
|
|
;;
|
|
esac
|
|
|
|
if test x$tag1 != xnonmatchingtag -a x$tag2 != xnonmatchingtag; then
|
|
tags=`sed '/^package /q' < $f | grep '^// +build '`
|
|
omatch=true
|
|
first=true
|
|
match=false
|
|
for tag in $tags; do
|
|
case $tag in
|
|
"//")
|
|
;;
|
|
"+build")
|
|
if test "$first" = "true"; then
|
|
first=false
|
|
elif test "$match" = "false"; then
|
|
omatch=false
|
|
fi
|
|
match=false
|
|
;;
|
|
$goos | $goarch | cgo | gccgo | go1.[0-9])
|
|
match=true
|
|
;;
|
|
"!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9])
|
|
;;
|
|
*,*)
|
|
cmatch=true
|
|
for ctag in `echo $tag | sed -e 's/,/ /g'`; do
|
|
case $ctag in
|
|
$goos | $goarch | cgo | gccgo | go1.[0-9])
|
|
;;
|
|
"!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9])
|
|
cmatch=false
|
|
;;
|
|
"!"*)
|
|
;;
|
|
*)
|
|
cmatch=false
|
|
;;
|
|
esac
|
|
done
|
|
if test "$cmatch" = "true"; then
|
|
match=true
|
|
fi
|
|
;;
|
|
"!"*)
|
|
match=true
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if test "$match" = "false" -a "$first" = "false"; then
|
|
omatch=false
|
|
fi
|
|
|
|
if test "$omatch" = "true"; then
|
|
gofiles="$gofiles $f"
|
|
fi
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
xgofiles=$gofiles
|
|
gofiles=
|
|
for f in $xgofiles; do
|
|
gofiles="$gofiles `basename $f`"
|
|
done
|
|
esac
|
|
|
|
case "x$gofiles" in
|
|
x)
|
|
echo 'no test files found' 1>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Run any commands given in sources, like
|
|
# // gotest: $GC foo.go
|
|
# to build any test-only dependencies.
|
|
holdGC="$GC"
|
|
GC="$GC -g -c -I ."
|
|
sed -n 's/^\/\/ gotest: //p' $gofiles | sh
|
|
GC="$holdGC"
|
|
|
|
case "x$pkgfiles" in
|
|
x)
|
|
pkgbasefiles=`ls *.go | grep -v _test.go 2>/dev/null`
|
|
;;
|
|
*)
|
|
for f in $pkgfiles; do
|
|
pkgbasefiles="$pkgbasefiles `basename $f`"
|
|
done
|
|
;;
|
|
esac
|
|
|
|
case "x$pkgfiles" in
|
|
x)
|
|
echo 'no source files found' 1>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Split $gofiles into external gofiles (those in *_test packages)
|
|
# and internal ones (those in the main package).
|
|
xgofiles=
|
|
for f in $gofiles; do
|
|
package=`grep '^package[ ]' $f | sed 1q`
|
|
case "$package" in
|
|
*_test)
|
|
xgofiles="$xgofiles $f"
|
|
;;
|
|
*)
|
|
ngofiles="$ngofiles $f"
|
|
;;
|
|
esac
|
|
done
|
|
gofiles=$ngofiles
|
|
|
|
# External $O file
|
|
xofile=""
|
|
havex=false
|
|
if [ "x$xgofiles" != "x" ]; then
|
|
xofile="_xtest_.o"
|
|
havex=true
|
|
fi
|
|
|
|
testmain=
|
|
if $havex && fgrep 'func TestMain(' $xgofiles >/dev/null 2>&1; then
|
|
package=`grep '^package[ ]' $xgofiles | sed 1q | sed -e 's/.* //'`
|
|
testmain="${package}.TestMain"
|
|
elif test -n "$gofiles" && fgrep 'func TestMain(' $gofiles >/dev/null 2>&1; then
|
|
package=`grep '^package[ ]' $gofiles | sed 1q | sed -e 's/.* //'`
|
|
testmain="${package}.TestMain"
|
|
fi
|
|
|
|
set -e
|
|
|
|
package=`echo ${srcdir} | sed -e 's|^.*libgo/go/||'`
|
|
|
|
pkgpatharg=
|
|
xpkgpatharg=
|
|
prefixarg=
|
|
if test -n "$pkgpath"; then
|
|
pkgpatharg="-fgo-pkgpath=$pkgpath"
|
|
xpkgpatharg="-fgo-pkgpath=${pkgpath}_test"
|
|
elif test -n "$prefix"; then
|
|
prefixarg="-fgo-prefix=$prefix"
|
|
fi
|
|
|
|
if test "$trace" = "true"; then
|
|
echo $GC -g $pkgpatharg $prefixarg -c -I . -fno-toplevel-reorder -o _gotest_.o $gofiles $pkgbasefiles
|
|
fi
|
|
$GC -g $pkgpatharg $prefixarg -c -I . -fno-toplevel-reorder -o _gotest_.o $gofiles $pkgbasefiles
|
|
|
|
if $havex; then
|
|
mkdir -p `dirname $package`
|
|
cp _gotest_.o `dirname $package`/lib`basename $package`.a
|
|
if test "$trace" = "true"; then
|
|
echo $GC -g $xpkgpatharg -c -I . -fno-toplevel-reorder -o $xofile $xgofiles
|
|
fi
|
|
$GC -g $xpkgpatharg -c -I . -fno-toplevel-reorder -o $xofile $xgofiles
|
|
fi
|
|
|
|
# They all compile; now generate the code to call them.
|
|
|
|
testname() {
|
|
# Remove the package from the name used with the -test option.
|
|
echo $1 | sed 's/^.*\.//'
|
|
}
|
|
|
|
localname() {
|
|
# The package main has been renamed to __main__ when imported.
|
|
# Adjust its uses.
|
|
echo $1 | sed 's/^main\./__main__./'
|
|
}
|
|
|
|
# Takes a list of tests derived from 'nm' output (whose symbols are mangled)
|
|
# and emits a demangled list of tests, using only the terminal package.
|
|
# Example:
|
|
#
|
|
# Original symbol: foo/bar/leaf.Mumble
|
|
# Mangled symbol: foo..z2fbar..z2fleaf.Mumble
|
|
# Returned: leaf.Mumble
|
|
#
|
|
symtogo() {
|
|
result=""
|
|
for tp in $*
|
|
do
|
|
s=$(echo "$tp" | sed -e 's/\.\.z2f/%/g' | sed -e 's/.*%//')
|
|
# screen out methods (X.Y.Z)
|
|
if ! expr "$s" : '^[^.]*\.[^.]*$' >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
echo "$s"
|
|
done
|
|
}
|
|
|
|
{
|
|
text="T"
|
|
|
|
# On systems using PPC64 ELF ABI v1 function symbols show up
|
|
# as descriptors in the data section. We assume that $goarch
|
|
# distinguishes v1 (ppc64) from v2 (ppc64le).
|
|
if test "$goos" != "aix" && test "$goarch" = "ppc64"; then
|
|
text="[TD]"
|
|
fi
|
|
|
|
# test functions are named TestFoo
|
|
# the grep -v eliminates methods and other special names
|
|
# that have multiple dots.
|
|
pattern='Test([^a-z].*)?'
|
|
# The -p option tells GNU nm not to sort.
|
|
# The -v option tells Solaris nm to sort by value.
|
|
testsyms=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' | fgrep -v ' __go_' | egrep -v '\.\.\w+$' | sed 's/.* //')
|
|
tests=$(symtogo "$testsyms")
|
|
if [ "x$tests" = x ]; then
|
|
echo 'gotest: warning: no tests matching '$pattern in _gotest_.o $xofile 1>&2
|
|
exit 2
|
|
fi
|
|
# benchmarks are named BenchmarkFoo.
|
|
pattern='Benchmark([^a-z].*)?'
|
|
benchmarksyms=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' | fgrep -v ' __go_' | egrep -v '\.\.\w+$' | sed 's/.* //')
|
|
benchmarks=$(symtogo "$benchmarksyms")
|
|
|
|
# examples are named ExampleFoo
|
|
pattern='Example([^a-z].*)?'
|
|
examplesyms=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' | fgrep -v ' __go_' | egrep -v '\.\.\w+$' | sed 's/.* //')
|
|
examples=$(symtogo "$examplesyms")
|
|
|
|
# package spec
|
|
echo 'package main'
|
|
echo
|
|
# imports
|
|
if echo "$tests" | egrep -v '_test\.' >/dev/null; then
|
|
echo 'import "./_gotest_"'
|
|
fi
|
|
if $havex; then
|
|
echo 'import "./_xtest_"'
|
|
fi
|
|
echo 'import "testing"'
|
|
echo 'import "testing/internal/testdeps"'
|
|
if ! test -n "$testmain"; then
|
|
echo 'import __os__ "os"'
|
|
fi
|
|
# test array
|
|
echo
|
|
echo 'var tests = []testing.InternalTest {'
|
|
for i in $tests
|
|
do
|
|
n=$(testname $i)
|
|
if test "$n" != "TestMain"; then
|
|
j=$(localname $i)
|
|
echo ' {"'$n'", '$j'},'
|
|
fi
|
|
done
|
|
echo '}'
|
|
|
|
# benchmark array
|
|
# The comment makes the multiline declaration
|
|
# gofmt-safe even when there are no benchmarks.
|
|
echo 'var benchmarks = []testing.InternalBenchmark{ //'
|
|
for i in $benchmarks
|
|
do
|
|
n=$(testname $i)
|
|
j=$(localname $i)
|
|
echo ' {"'$n'", '$j'},'
|
|
done
|
|
echo '}'
|
|
|
|
# examples array
|
|
echo 'var examples = []testing.InternalExample{ //'
|
|
# This doesn't work because we don't pick up the output.
|
|
#for i in $examples
|
|
#do
|
|
# n=$(testname $i)
|
|
# j=$(localname $i)
|
|
# echo ' {"'$n'", '$j', ""},'
|
|
#done
|
|
echo '}'
|
|
|
|
# body
|
|
echo \
|
|
'
|
|
func main() {
|
|
m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, examples)
|
|
'
|
|
if test -n "$testmain"; then
|
|
echo " ${testmain}(m)"
|
|
else
|
|
echo ' __os__.Exit(m.Run())'
|
|
fi
|
|
|
|
echo '}'
|
|
}>_testmain.go
|
|
|
|
case "x$dejagnu" in
|
|
xno)
|
|
if test "$trace" = "true"; then
|
|
echo ${GC} -g -c _testmain.go
|
|
fi
|
|
${GC} -g -c _testmain.go
|
|
|
|
if test "$trace" = "true"; then
|
|
echo ${GL} *.o ${GOLIBS}
|
|
fi
|
|
${GL} *.o ${GOLIBS}
|
|
|
|
set +e
|
|
if test "$bench" = ""; then
|
|
if test "$trace" = "true"; then
|
|
echo ./a.out -test.short -test.timeout=${timeout}s "$@"
|
|
fi
|
|
./a.out -test.short -test.timeout=${timeout}s "$@" &
|
|
pid=$!
|
|
(sleep `expr $timeout + 10`
|
|
echo > gotest-timeout
|
|
echo "timed out in gotest" 1>&2
|
|
kill -9 $pid) &
|
|
alarmpid=$!
|
|
wait $pid
|
|
status=$?
|
|
if ! test -f gotest-timeout; then
|
|
sleeppid=`ps -o pid,ppid,comm | grep " $alarmpid " | grep sleep | sed -e 's/ *\([0-9]*\) .*$/\1/'`
|
|
kill $alarmpid
|
|
wait $alarmpid
|
|
if test "$sleeppid" != ""; then
|
|
kill $sleeppid
|
|
fi
|
|
fi
|
|
else
|
|
if test "$trace" = "true"; then
|
|
echo ./a.out -test.run=^\$ -test.bench="${bench}" "$@"
|
|
fi
|
|
./a.out -test.run=^\$ -test.bench="${bench}" "$@"
|
|
status=$?
|
|
fi
|
|
exit $status
|
|
;;
|
|
xyes)
|
|
rm -rf ../../testsuite/*.o
|
|
files=`echo *`
|
|
for f in $files; do
|
|
if test "$f" = "_obj" || test "$f" = "_test"; then
|
|
continue
|
|
fi
|
|
rm -rf ../../testsuite/$f
|
|
if test -f $f; then
|
|
cp $f ../../testsuite/
|
|
else
|
|
ln -s ../$DIR/test/$f ../../testsuite/
|
|
fi
|
|
done
|
|
cd ../../testsuite
|
|
rm -rf _obj _test
|
|
mkdir _obj _test
|
|
if test "$testname" != ""; then
|
|
GOTESTNAME="$testname"
|
|
export GOTESTNAME
|
|
fi
|
|
$MAKE check RUNTESTFLAGS="$RUNTESTFLAGS GOTEST_TMPDIR=$DIR/test"
|
|
# Useful when using make check-target-libgo
|
|
cat libgo.log >> libgo-all.log
|
|
cat libgo.sum >> libgo-all.sum
|
|
rm -rf $files
|
|
;;
|
|
esac
|