// common holds the elements common between T and B and
// captures common methods such as Errorf.
type common struct {
- mu sync.RWMutex // guards this group of fields
- output []byte // Output generated by test or benchmark.
- w io.Writer // For flushToParent.
- ran bool // Test or benchmark (or one of its subtests) was executed.
- failed bool // Test or benchmark has failed.
- skipped bool // Test of benchmark has been skipped.
- done bool // Test is finished and all subtests have completed.
- helpers map[uintptr]struct{} // functions to be skipped when writing file/line info
-
- chatty bool // A copy of the chatty flag.
- finished bool // Test function has completed.
- hasSub int32 // written atomically
- raceErrors int // number of races detected during test
- runner uintptr // entry pc of tRunner running the test
+ mu sync.RWMutex // guards this group of fields
+ output []byte // Output generated by test or benchmark.
+ w io.Writer // For flushToParent.
+ ran bool // Test or benchmark (or one of its subtests) was executed.
+ failed bool // Test or benchmark has failed.
+ skipped bool // Test of benchmark has been skipped.
+ done bool // Test is finished and all subtests have completed.
+ helpers map[string]struct{} // functions to be skipped when writing file/line info
+
+ chatty bool // A copy of the chatty flag.
+ finished bool // Test function has completed.
+ hasSub int32 // written atomically
+ raceErrors int // number of races detected during test
+ runner string // function name of tRunner running the test
parent *common
level int // Nesting depth of test or benchmark.
more := true
for i := 0; more; i++ {
frame, more = frames.Next()
- if frame.Entry == c.runner {
+ if frame.Function == c.runner {
// We've gone up all the way to the tRunner calling
// the test function (so the user must have
// called tb.Helper from inside that test function).
// Only skip up to the test function itself.
return skip + i - 1
}
- if _, ok := c.helpers[frame.Entry]; !ok {
+ if _, ok := c.helpers[frame.Function]; !ok {
// Found a frame that wasn't inside a helper function.
return skip + i
}
c.mu.Lock()
defer c.mu.Unlock()
if c.helpers == nil {
- c.helpers = make(map[uintptr]struct{})
+ c.helpers = make(map[string]struct{})
}
- c.helpers[callerEntry(1)] = struct{}{}
+ c.helpers[callerName(1)] = struct{}{}
}
-// callerEntry gives the entry pc for the caller after skip frames
-// (where 0 means the current function).
-func callerEntry(skip int) uintptr {
- var pc [1]uintptr
- n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerEntry
+// callerName gives the function name (qualified with a package path)
+// 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
+ n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
if n == 0 {
panic("testing: zero callers found")
}
- frames := runtime.CallersFrames(pc[:])
+ frames := runtime.CallersFrames(pc[:n])
frame, _ := frames.Next()
- return frame.Entry
+ return frame.Function
}
// Parallel signals that this test is to be run in parallel with (and only with)
}
func tRunner(t *T, fn func(t *T)) {
- t.runner = callerEntry(0)
+ t.runner = callerName(0)
// When this goroutine is done, either because fn(t)
// returned normally or because a test failure triggered