aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing/testing.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/testing/testing.go')
-rw-r--r--libgo/go/testing/testing.go126
1 files changed, 87 insertions, 39 deletions
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 3068630..339df13 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -249,7 +249,18 @@ import (
"time"
)
-var (
+var initRan bool
+
+// Init registers testing flags. These flags are automatically registered by
+// the "go test" command before running test functions, so Init is only needed
+// when calling functions such as Benchmark without using "go test".
+//
+// Init has no effect if it was already called.
+func Init() {
+ if initRan {
+ return
+ }
+ initRan = true
// The short flag requests that tests run more quickly, but its functionality
// is provided by test writers themselves. The testing package is just its
// home. The all.bash installation script sets it to make installation more
@@ -265,25 +276,50 @@ var (
// this flag lets "go test" tell the binary to write the files in the directory where
// the "go test" command is run.
outputDir = flag.String("test.outputdir", "", "write profiles to `dir`")
-
// Report as tests are run; default is silent for success.
- chatty = flag.Bool("test.v", false, "verbose: print additional output")
- count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
- coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
- matchList = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
- match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
- memProfile = flag.String("test.memprofile", "", "write an allocation profile to `file`")
- memProfileRate = flag.Int("test.memprofilerate", 0, "set memory allocation profiling `rate` (see runtime.MemProfileRate)")
- cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
- blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
- blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
- mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
+ chatty = flag.Bool("test.v", false, "verbose: print additional output")
+ count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
+ coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
+ matchList = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
+ match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
+ memProfile = flag.String("test.memprofile", "", "write an allocation profile to `file`")
+ memProfileRate = flag.Int("test.memprofilerate", 0, "set memory allocation profiling `rate` (see runtime.MemProfileRate)")
+ cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
+ blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
+ blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
+ mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
- traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
- timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
- cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
- parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
- testlog = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)")
+ traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
+ timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
+ cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
+ parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
+ testlog = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)")
+
+ initBenchmarkFlags()
+}
+
+var (
+ // Flags, registered during Init.
+ short *bool
+ failFast *bool
+ outputDir *string
+ chatty *bool
+ count *uint
+ coverProfile *string
+ matchList *string
+ match *string
+ memProfile *string
+ memProfileRate *int
+ cpuProfile *string
+ blockProfile *string
+ blockProfileRate *int
+ mutexProfile *string
+ mutexProfileFraction *int
+ traceFile *string
+ timeout *time.Duration
+ cpuListStr *string
+ parallel *int
+ testlog *string
haveExamples bool // are there examples?
@@ -328,11 +364,12 @@ type common struct {
// Short reports whether the -test.short flag is set.
func Short() bool {
- // Catch code that calls this from TestMain without first
- // calling flag.Parse. This shouldn't really be a panic
+ if short == nil {
+ panic("testing: Short called before Init")
+ }
+ // Catch code that calls this from TestMain without first calling flag.Parse.
if !flag.Parsed() {
- fmt.Fprintf(os.Stderr, "testing: testing.Short called before flag.Parse\n")
- os.Exit(2)
+ panic("testing: Short called before Parse")
}
return *short
@@ -347,6 +384,13 @@ func CoverMode() string {
// Verbose reports whether the -test.v flag is set.
func Verbose() bool {
+ // Same as in Short.
+ if chatty == nil {
+ panic("testing: Verbose called before Init")
+ }
+ if !flag.Parsed() {
+ panic("testing: Verbose called before Parse")
+ }
return *chatty
}
@@ -614,7 +658,7 @@ func (c *common) log(s string) {
c.logDepth(s, 3) // logDepth + log + public function
}
-// logDepth generates the output. At an arbitary stack depth
+// logDepth generates the output at an arbitrary stack depth.
func (c *common) logDepth(s string, depth int) {
c.mu.Lock()
defer c.mu.Unlock()
@@ -727,7 +771,7 @@ func (c *common) Helper() {
// for the caller after skip frames (where 0 means the current function).
func callerName(skip int) string {
// Make room for the skip PC.
- var pc [2]uintptr
+ var pc [1]uintptr
n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
if n == 0 {
panic("testing: zero callers found")
@@ -1031,6 +1075,12 @@ type testDeps interface {
// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
// It may change signature from release to release.
func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
+ // In most cases, Init has already been called by the testinginit code
+ // that 'go test' injects into test packages.
+ // Call it again here to handle cases such as:
+ // - test packages that don't import "testing" (such as example-only packages)
+ // - direct use of MainStart (though that isn't well-supported)
+ Init()
return &M{
deps: deps,
tests: tests,
@@ -1287,7 +1337,7 @@ func (m *M) writeProfiles() {
os.Exit(2)
}
if err = m.deps.WriteProfileTo("mutex", f, 0); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *mutexProfile, err)
os.Exit(2)
}
f.Close()
@@ -1303,20 +1353,18 @@ func toOutputDir(path string) string {
if *outputDir == "" || path == "" {
return path
}
- if runtime.GOOS == "windows" {
- // On Windows, it's clumsy, but we can be almost always correct
- // by just looking for a drive letter and a colon.
- // Absolute paths always have a drive letter (ignoring UNC).
- // Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
- // what to do, but even then path/filepath doesn't help.
- // TODO: Worth doing better? Probably not, because we're here only
- // under the management of go test.
- if len(path) >= 2 {
- letter, colon := path[0], path[1]
- if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
- // If path starts with a drive letter we're stuck with it regardless.
- return path
- }
+ // On Windows, it's clumsy, but we can be almost always correct
+ // by just looking for a drive letter and a colon.
+ // Absolute paths always have a drive letter (ignoring UNC).
+ // Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
+ // what to do, but even then path/filepath doesn't help.
+ // TODO: Worth doing better? Probably not, because we're here only
+ // under the management of go test.
+ if runtime.GOOS == "windows" && len(path) >= 2 {
+ letter, colon := path[0], path[1]
+ if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
+ // If path starts with a drive letter we're stuck with it regardless.
+ return path
}
}
if os.IsPathSeparator(path[0]) {