#!/usr/bin/env bash # 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. unset LANG export LC_ALL=C export LC_CTYPE=C GOBIN="${GOBIN:-$HOME/bin}" _GC=$GC # Make.$GOARCH will overwrite this if [ ! -f [Mm]akefile ]; then echo 'please create a Makefile for gotest; see http://golang.org/doc/contribute.html (sic) for details' 1>&2 exit 2 fi . "$GOROOT"/src/Make.$GOARCH if [ -z "$O" ]; then echo 'missing $O - maybe no Make.$GOARCH?' 1>&2 exit 2 fi E="" case "$GOOS" in nacl) E="nacl" esac # TODO(kaib): proper emulator strategy case x"$GOARCH" in xarm) export E=${EMU_arm:-qemu-arm -cpu cortex-a8} esac # Allow overrides GC="$GOBIN/${_GC:-$GC} -I _test" GL="$GOBIN/${GL:-$LD} -L _test" CC="$GOBIN/$CC" LD="$GOBIN/$LD" export GC GL O AS CC LD gofiles="" loop=true while $loop; do case "x$1" in x-*) loop=false ;; x) loop=false ;; *) gofiles="$gofiles $1" shift ;; esac done case "x$gofiles" in x) gofiles=$(echo -n $(ls *_test.go 2>/dev/null)) esac case "x$gofiles" in x) echo 'no test files found (*_test.go)' 1>&2 exit 2 esac # Run any commands given in sources, like # // gotest: $GC foo.go # to build any test-only dependencies. sed -n 's/^\/\/ gotest: //p' $gofiles | sh -e || exit 1 # Split $gofiles into external gofiles (those in *_test packages) # and internal ones (those in the main package). xgofiles=$(echo $(grep '^package[ ]' $gofiles /dev/null | grep ':.*_test' | sed 's/:.*//')) gofiles=$(echo $(grep '^package[ ]' $gofiles /dev/null | grep -v ':.*_test' | sed 's/:.*//')) # External $O file xofile="" havex=false if [ "x$xgofiles" != "x" ]; then xofile="_xtest_.$O" havex=true fi set -e "$GOBIN"/gomake testpackage-clean "$GOBIN"/gomake testpackage "GOTESTFILES=$gofiles" if $havex; then $GC -o $xofile $xgofiles fi # They all compile; now generate the code to call them. trap "rm -f _testmain.go _testmain.$O" 0 1 2 3 14 15 # Suppress output to stdout on Linux MAKEFLAGS= MAKELEVEL= # usage: nmgrep pattern file... nmgrep() { pat="$1" shift for i do # Package symbol "".Foo is pkg.Foo when imported in Go. # Figure out pkg. case "$i" in *.a) pkg=$("$GOBIN"/gopack p $i __.PKGDEF | sed -n 's/^package //p' | sed 1q) ;; *) pkg=$(sed -n 's/^ .* in package "\(.*\)".*/\1/p' $i | sed 1q) ;; esac "$GOBIN"/6nm -s "$i" | egrep ' T .*\.'"$pat"'$' | sed 's/.* //; /\..*\./d; s/""\./'"$pkg"'./g' done } importpath=$("$GOBIN"/gomake -s importpath) { # test functions are named TestFoo # the grep -v eliminates methods and other special names # that have multiple dots. pattern='Test([^a-z].*)?' tests=$(nmgrep $pattern _test/$importpath.a $xofile) if [ "x$tests" = x ]; then echo 'gotest: error: no tests matching '$pattern in _test/$importpath.a $xofile 1>&2 exit 2 fi # benchmarks are named BenchmarkFoo. pattern='Benchmark([^a-z].*)?' benchmarks=$(nmgrep $pattern _test/$importpath.a $xofile) # package spec echo 'package main' echo # imports if echo "$tests" | egrep -v '_test\.' >/dev/null; then if [ "$importpath" != "testing" ]; then echo 'import "'$importpath'"' fi fi if $havex; then echo 'import "./_xtest_"' fi echo 'import "testing"' # test array echo echo 'var tests = []testing.Test {' for i in $tests do echo ' testing.Test{ "'$i'", '$i' },' done echo '}' # benchmark array echo 'var benchmarks = []testing.Benchmark {' for i in $benchmarks do echo ' testing.Benchmark{ "'$i'", '$i' },' done echo '}' # body echo echo 'func main() {' echo ' testing.Main(tests);' echo ' testing.RunBenchmarks(benchmarks)' echo '}' }>_testmain.go $GC _testmain.go $GL _testmain.$O $E ./$O.out "$@"