2 # Copyright 2009 The Go Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style
4 # license that can be found in the LICENSE file.
6 # Using all the *_test.go files in the current directory, write out a file
7 # _testmain.go that runs all its tests. Compile everything and run the
9 # If files are named on the command line, use them instead of *_test.go.
11 # Makes egrep,grep work better in general if we put them
12 # in ordinary C mode instead of what the current language is.
16 export LANG LC_ALL LC_CTYPE
25 # srcdir is where the source files are found. basedir is where the
26 # source file paths are relative to.
27 # gofiles are the test files. pkgfiles are the source files.
51 srcdir
=`echo $1 | sed -e 's/^--srcdir=//'`
60 basedir
=`echo $1 | sed -e 's/^--basedir=//'`
69 goarch
=`echo $1 | sed -e 's/^--goarch=//'`
78 goos
=`echo $1 | sed -e 's/^--goos=//'`
87 pkgpath
=`echo $1 | sed -e 's/^--pkgpath=//'`
96 prefix
=`echo $1 | sed -e 's/^--prefix=//'`
109 pkgfiles
=`echo $1 | sed -e 's/^--pkgfiles=//'`
118 dejagnu
=`echo $1 | sed -e 's/^--dejagnu=//'`
127 timeout
=`echo $1 | sed -e 's/^--timeout=//'`
136 testname
=`echo $1 | sed -e 's/^--testname=//'`
145 bench
=`echo $1 | sed -e 's/^--bench=//'`
159 gofiles
="$gofiles $1"
173 if test $keep = false
; then
174 trap "cd ../..; rm -rf $DIR" 0 1 2 3 14 15
176 trap "cd ../..; echo Keeping $DIR" 0 1 2 3 14 15
183 srcdir
="../../$srcdir"
194 basedir
="../../$basedir"
198 # Link all the files/directories in srcdir into our working directory,
199 # so that the tests do not have to refer to srcdir to find test data.
202 # Some tests refer to a ../testdata directory.
203 if test -e $srcdir/..
/testdata
; then
205 abssrcdir
=`cd $srcdir && pwd`
206 ln -s $abssrcdir/..
/testdata ..
/testdata
209 # Copy the .go files because io/utils_test.go expects a regular file.
214 for f
in `cd $srcdir; ls *.go`; do
220 for f
in $pkgfiles; do
228 if test -f $basedir/$f; then
232 elif test -f ..
/..
/$f; then
237 echo "file $f not found" 1>&2
243 for f
in `cd $srcdir; ls *_test.go`; do
251 for f
in $gofiles; do
258 for f
in `cd $srcdir; ls *.go | grep -v *_test.go`; do
264 for f
in $pkgfiles; do
272 if test -f $basedir/$f; then
276 elif test -f ..
/..
/$f; then
281 echo "file $f not found" 1>&2
293 line
=$
(echo "$1" |
sed -e 's|//go:build ||')
294 line
=$
(echo "$line" |
sed -e 's/go1\.[0-9]\+/1/g' -e 's/goexperiment\./goexperiment/')
297 for ones
in $goarch $goos cgo gccgo goexperimentfieldtrack
; do
298 line
=$
(echo "$line" |
sed -e "s/\\(${wrap}\\)${ones}\\(${wrap}\\)/"'\11\2/g')
300 # 386 is a special case since it looks like a number to the shell.
301 # We need it to be 0 if it's not $goarch.
302 if test "$goarch" != "386"; then
303 line
=$
(echo "$line" |
sed -e "s/\\(${wrap}\\)386\\(${wrap}\\)/\10\2/g")
310 for f
in `ls *_test.go`; do
311 tag1
=`echo $f | sed -e 's/^.*_\([^_]*\)_test.go$/\1/'`
312 tag2
=`echo $f | sed -e 's/^.*_\([^_]*\)_[^_]*_test.go$/\1/'`
313 if test x
$tag1 = x
$f; then
316 if test x
$tag2 = x
$f; then
324 aix | android | darwin | dragonfly | freebsd | hurd | ios | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows | zos
)
327 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm
)
331 # File name like x_amd64_random.go, where tag1=random.
332 # Don't match based on tag2.
341 aix | android | darwin | dragonfly | freebsd | hurd | ios | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows | zos
)
344 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm
)
349 if test x
$tag1 = xnonmatchingtag
-o x
$tag2 = xnonmatchingtag
; then
353 # Check for go:build line
354 build
=$
(sed '/^package /q' < $f |
grep '^//go:build ' |
cat)
355 if test -n "$build"; then
356 if $
(gobuild
"$build"); then
357 gofiles
="$gofiles $f"
362 # No go:build line, check for +build lines.
363 tags
=`sed '/^package /q' < $f | grep '^// *+build '`
371 "+build" |
"//+build")
372 if test "$first" = "true"; then
374 elif test "$match" = "false"; then
379 $goos |
$goarch | cgo | gccgo | goexperiment.fieldtrack | go1.
[0-9] | go1.
[0-9][0-9])
382 "!"$goos |
"!"$goarch |
"!cgo" |
"!gccgo" |
"!goexperiment.fieldtrack" |
"!"go1.
[0-9] |
"!"go1.1
[0-7])
386 for ctag
in `echo $tag | sed -e 's/,/ /g'`; do
388 $goos |
$goarch | cgo | gccgo | goexperiment.fieldtrack | go1.
[0-9] | go1.
[0-9][0-9])
390 "!"$goos |
"!"$goarch |
"!cgo" |
"!gccgo" |
"!goexperiment.fieldtrack" |
"!"go1.
[0-9] |
"!"go1.1
[0-7])
400 if test "$cmatch" = "true"; then
410 if test "$match" = "false" -a "$first" = "false"; then
414 if test "$omatch" = "true"; then
415 gofiles
="$gofiles $f"
422 for f
in $xgofiles; do
423 gofiles
="$gofiles `basename $f`"
429 echo 'no test files found' 1>&2
436 pkgbasefiles
=`ls *.go | grep -v _test.go 2>/dev/null`
439 for f
in $pkgfiles; do
440 pkgbasefiles
="$pkgbasefiles `basename $f`"
447 echo 'no source files found' 1>&2
452 # Split $gofiles into external gofiles (those in *_test packages)
453 # and internal ones (those in the main package).
456 for f
in $gofiles; do
457 package
=`grep '^package[ ]' $f | sed 1q`
460 xpackage
=`echo $package | sed -e 's/package[ ]//' -e 's/[ ]*$//'`
461 xgofiles
="$xgofiles $f"
464 ngofiles
="$ngofiles $f"
473 if [ "x$xgofiles" != "x" ]; then
479 if $havex && fgrep
'func TestMain(' $xgofiles >/dev
/null
2>&1; then
480 package
=`grep '^package[ ]' $xgofiles | sed 1q | sed -e 's/.* //'`
481 testmain
="${package}.TestMain"
482 elif test -n "$gofiles" && fgrep
'func TestMain(' $gofiles >/dev
/null
2>&1; then
483 package
=`grep '^package[ ]' $gofiles | sed 1q | sed -e 's/.* //'`
484 testmain
="${package}.TestMain"
489 package
=`echo ${srcdir} | sed -e 's|^.*libgo/go/||'`
494 if test -n "$pkgpath"; then
495 pkgpatharg
="-fgo-pkgpath=$pkgpath"
496 xpkgpatharg
="-fgo-pkgpath=${pkgpath}_test"
497 elif test -n "$prefix"; then
498 prefixarg
="-fgo-prefix=$prefix"
501 if test "$trace" = "true"; then
502 echo $GC -g $pkgpatharg $prefixarg -c -I .
-fno-toplevel-reorder -o _gotest_.o
$gofiles $pkgbasefiles
504 $GC -g $pkgpatharg $prefixarg -c -I .
-fno-toplevel-reorder -o _gotest_.o
$gofiles $pkgbasefiles
507 mkdir
-p `dirname $package`
508 cp _gotest_.o
`dirname $package`/lib
`basename $package`.a
510 # Force the test version of the package to be imported first,
511 # so that its type definitions will be used, in case any new
512 # methods appear in export_test.go files.
513 echo "package $xpackage" > _first_test.go
514 echo 'import _ "'$package'"' >> _first_test.go
516 if test "$trace" = "true"; then
517 echo $GC -g $xpkgpatharg -c -I .
-fno-toplevel-reorder -o $xofile _first_test.go
$xgofiles
519 $GC -g $xpkgpatharg -c -I .
-fno-toplevel-reorder -o $xofile _first_test.go
$xgofiles
522 # They all compile; now generate the code to call them.
525 # Remove the package from the name used with the -test option.
526 echo $1 |
sed 's/^.*\.//'
530 # The package main has been renamed to __main__ when imported.
532 # Also demangle underscores.
533 echo $1 |
sed 's/^main\./__main__./' |
sed 's/__/_/'
536 # Takes a list of tests derived from 'nm' output (whose symbols are mangled)
537 # and emits a demangled list of tests, using only the terminal package.
540 # Original symbol: foo/bar/leaf.Mumble
541 # Mangled symbol: foo_1fbar_1leaf.Mumble
542 # Returned: leaf.Mumble
547 # Discard symbols with a leading dot.
548 # On AIX, this will remove function text symbols (with a leading dot).
549 # Therefore, only function descriptor symbols (without this leading dot)
550 # will be used to retrieve the go symbols, avoiding duplication.
551 if expr "$tp" : '^\.' >/dev
/null
2>&1; then
554 # Skip type descriptors. These are normally skipped because they
555 # are weak symbols, but if not using GNU nm we may see them here.
556 if expr "$tp" : '^type\.\.' >/dev
/null
2>&1; then
559 s
=$
(echo "$tp" |
sed -e 's/_1/%/g' |
sed -e 's/.*%//')
560 # Screen out methods (X.Y.Z).
561 if ! expr "$s" : '^[^.]*\.[^.]*$' >/dev
/null
2>&1; then
566 if test x
$tname = xTestMain
; then
569 # Check that the function is defined in a test file,
570 # not an ordinary non-test file.
571 if grep "^func $tname(" $gofiles $xgofiles >/dev
/null
2>&1; then
577 # Find Go benchmark/fuzz/example functions.
578 # The argument is the function name prefix.
580 pattern
="$1([^a-z].*)?"
581 syms
=$
($NM -p -v _gotest_.o |
egrep " $text .*\."$pattern'$' | fgrep
-v ' __go_' |
egrep -v '\.\.\w+$' |
sed 's/.* //')
583 xsyms
=$
($NM -p -v $xofile |
egrep " $text .*\."$pattern'$' | fgrep
-v ' __go_' |
egrep -v '\.\.\w+$' |
sed 's/.* //')
589 # Takes an example name and puts any output into the file example.txt.
590 # It strips comment markers but does not otherwise change the output.
593 for f
in $gofiles $xgofiles; do
594 if ! grep "^func $n(" $f >/dev
/null
2>&1; then
597 # Copy the output comment, if any, into example.txt.
598 # Remove the comment markers.
599 sed -n "/^func $n(/,/^}$/ p" $f |
600 sed -n '\|// \([Uu]nordered \)\?[Oo]utput:|,$ p' |
601 sed -n '\|//| s|[ ]*// \?||p' > example.txt
602 # Check whether we found an output comment.
603 if ! sed -n '1p' < example.txt |
grep '[Oo]utput:' >/dev
/null
2>&1; then
611 # On systems using PPC64 ELF ABI v1 function symbols show up
612 # as descriptors in the data section.
615 # test functions are named TestFoo
616 # the grep -v eliminates methods and other special names
617 # that have multiple dots.
618 pattern
='Test([^a-z].*)?'
619 # The -p option tells GNU nm not to sort.
620 # The -v option tells Solaris nm to sort by value.
621 testsyms
=$
($NM -p -v _gotest_.o |
egrep " $text .*\."$pattern'$' | fgrep
-v ' __go_' |
egrep -v '\.\.\w+$' |
sed 's/.* //')
624 testxsyms
=$
($NM -p -v $xofile |
egrep " $text .*\."$pattern'$' | fgrep
-v ' __go_' |
egrep -v '\.\.\w+$' |
sed 's/.* //')
625 testsyms
="$testsyms $testxsyms"
627 tests
=$
(symtogo
"$testsyms")
628 if [ "x$tests" = x
]; then
629 echo 'gotest: warning: no tests matching '$pattern in _gotest_.o
$xofile 1>&2
633 benchmarks
=$
(findfuncs Benchmark
)
634 fuzztargets
=$
(findfuncs Fuzz
)
635 examples
=$
(findfuncs Example
)
641 if echo "$tests" |
egrep -v '_test\.' >/dev
/null
; then
642 echo 'import "./_gotest_"'
646 if test -n "$testxsyms"; then
648 elif echo "$benchmarks" |
grep '_test\.' >/dev
/null
; then
651 # Check whether any example has output.
652 for i
in $
(echo "$examples" |
grep '_test\.'); do
654 if test -f example.txt
; then
661 if test x
$needxtest = xtrue
; then
662 echo 'import "./_xtest_"'
664 echo 'import _ "./_xtest_"'
667 if test "$package" != "testing"; then
668 echo 'import "testing"'
670 echo 'import "testing/internal/testdeps"'
671 if ! test -n "$testmain"; then
672 echo 'import __os__ "os"'
676 echo 'var tests = []testing.InternalTest {'
680 echo ' {"'$n'", '$j'},'
685 # The comment makes the multiline declaration
686 # gofmt-safe even when there are no benchmarks.
687 echo 'var benchmarks = []testing.InternalBenchmark{'
688 for i
in $benchmarks; do
691 echo ' {"'$n'", '$j'},'
696 echo 'var fuzzTargets = []testing.InternalFuzzTarget{'
697 for i
in $fuzztargets; do
700 echo ' {"'$n'", '$j'},'
705 echo 'var examples = []testing.InternalExample{'
706 for i
in $examples; do
709 # Look for a //output comment.
714 if ! test -f example.txt
; then
717 # Check whether the output can be unordered.
719 if sed -n '1p' < example.txt |
grep -i unordered
>/dev
/null
2>&1; then
722 # Remove the output header.
724 # Quote quotation characters.
726 # Turn pairs of spaces into " \x20", because $() will
727 # drop duplicate spaces.
728 # Drop trailing spaces, and turn newlines into \n.
729 # Remove leading and trailing \n.
730 sed '1 s/\([Uu]nordered \)\?[Oo]utput:[ ]*//' < example.txt |
731 sed -e 's/\\/\\\\/g' \
737 sed -e 's/^\(\\n\)*//' \
738 -e 's/\(\\n\)*$//' > example2.txt
740 echo ' {"'$n'", '$j','
741 sed -e 's/^/ "/' -e 's/$/", /' < example2.txt
743 rm -f example.txt example2.txt
751 m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, fuzzTargets, examples)
753 if test -n "$testmain"; then
754 echo " ${testmain}(m)"
756 echo ' __os__.Exit(m.Run())'
764 if test "$trace" = "true"; then
765 echo ${GC} -g -c _testmain.go
767 ${GC} -g -c _testmain.go
769 if test "$trace" = "true"; then
770 echo ${GL} *.o
${GOLIBS}
775 if test "$bench" = ""; then
776 if test "$trace" = "true"; then
777 echo .
/a.out
-test.short
-test.timeout
=${timeout}s
"$@"
779 .
/a.out
-test.short
-test.timeout
=${timeout}s
"$@" &
781 (sleep `expr $timeout + 10`
782 echo > gotest-timeout
783 echo "timed out in gotest" 1>&2
788 if ! test -f gotest-timeout
; then
789 sleeppid
=`ps -o pid,ppid,comm | grep " $alarmpid " | grep sleep | sed -e 's/ *\([0-9]*\) .*$/\1/'`
792 if test "$sleeppid" != ""; then
797 if test "$trace" = "true"; then
798 echo .
/a.out
-test.run
=^\$
-test.bench
="${bench}" "$@"
800 .
/a.out
-test.run
=^\$
-test.bench
="${bench}" "$@"
806 rm -rf ..
/..
/testsuite
/*.o
809 if test "$f" = "_obj" ||
test "$f" = "_test"; then
812 rm -rf ..
/..
/testsuite
/$f
814 cp $f ..
/..
/testsuite
/
816 ln -s ..
/$DIR/test
/$f ..
/..
/testsuite
/
822 if test "$testname" != ""; then
823 GOTESTNAME
="$testname"
826 $MAKE check RUNTESTFLAGS
="$RUNTESTFLAGS GOTEST_TMPDIR=$DIR/test"
827 # Useful when using make check-target-libgo
828 cat libgo.log
>> libgo-all.log
829 cat libgo.
sum >> libgo-all.
sum