// 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[string]struct{} // functions to be skipped when writing file/line info
- cleanup func() // optional function to be called at the end of 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
+ cleanup func() // optional function to be called at the end of the test
+ cleanupName string // Name of the cleanup function.
+ cleanupPc []uintptr // The stack trace at the point where Cleanup was called.
chatty bool // A copy of the chatty flag.
finished bool // Test function has completed.
var firstFrame, prevFrame, frame runtime.Frame
for more := true; more; prevFrame = frame {
frame, more = frames.Next()
+ if frame.Function == c.cleanupName {
+ frames = runtime.CallersFrames(c.cleanupPc)
+ continue
+ }
if firstFrame.PC == 0 {
firstFrame = frame
}
c.mu.Lock()
defer c.mu.Unlock()
oldCleanup := c.cleanup
+ oldCleanupPc := c.cleanupPc
c.cleanup = func() {
if oldCleanup != nil {
- defer oldCleanup()
+ defer func() {
+ c.cleanupPc = oldCleanupPc
+ oldCleanup()
+ }()
}
+ c.cleanupName = callerName(0)
f()
}
+ var pc [maxStackLen]uintptr
+ // Skip two extra frames to account for this function and runtime.Callers itself.
+ n := runtime.Callers(2, pc[:])
+ c.cleanupPc = pc[:n]
}
var tempDirReplacer struct {