go-approval-tests icon indicating copy to clipboard operation
go-approval-tests copied to clipboard

bug: use CallerFrames to find the filename instead of traversing program counter

Open karngyan opened this issue 2 years ago • 0 comments

Regarding findFileName

Go runtime docs discourage traversing PC or FuncForPC on any returned PCs as they can't account for inlining or return program counter adjustment.

This sometimes returns the wrong file name.

Something like this would be a better alternative:

func findFileName() (*string, error) {
	pc := make([]uintptr, 100)
	count := runtime.Callers(0, pc)
	frames := runtime.CallersFrames(pc[:count])
	var lastFrame *runtime.Frame
	var testFrame *runtime.Frame

	for {
		frame, more := frames.Next()
		if !more {
			break
		}

		if isTestRunnerFrame(&frame) {
			testFrame = &frame
			break
		}
		lastFrame = &frame
	}

	if !isTestRunnerFrame(testFrame) {
		return nil, fmt.Errorf("approvals: could not find the test method")
	}

	return &lastFrame.File, nil
}

func isTestRunnerFrame(f *runtime.Frame) bool {
	return f != nil && f.Function == "testing.tRunner" || f.Function == "testing.runExample"
}

What do you think?

karngyan avatar Jun 08 '22 13:06 karngyan