1
0
mirror of https://github.com/golang/go synced 2024-11-23 11:40:07 -07:00

io: correctly compute call depth in test

TestMultiReaderFlatten determines the call depth by counting PCs
returned by runtime.Callers. With inlining, this is incorrect because
a PC can represent multiple calls. Furthermore, runtime.Callers might
return an additional "skip" PC, which does not represent a real call.
This modifies the test to use CallersFrames to determine the call depth.
Now the test passes with -l=4.

Change-Id: I284f3b1e0b2d194bd08c230c616914503e5a370d
Reviewed-on: https://go-review.googlesource.com/40990
Run-TryBot: David Lazar <lazard@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
David Lazar 2017-04-18 15:12:54 -04:00
parent 17137fae2e
commit 46ecac99fb

View File

@ -175,13 +175,26 @@ func (f readerFunc) Read(p []byte) (int, error) {
return f(p)
}
// callDepth returns the logical call depth for the given PCs.
func callDepth(callers []uintptr) (depth int) {
frames := runtime.CallersFrames(callers)
more := true
for more {
_, more = frames.Next()
depth++
}
return
}
// Test that MultiReader properly flattens chained multiReaders when Read is called
func TestMultiReaderFlatten(t *testing.T) {
pc := make([]uintptr, 1000) // 1000 should fit the full stack
var myDepth = runtime.Callers(0, pc)
n := runtime.Callers(0, pc)
var myDepth = callDepth(pc[:n])
var readDepth int // will contain the depth from which fakeReader.Read was called
var r Reader = MultiReader(readerFunc(func(p []byte) (int, error) {
readDepth = runtime.Callers(1, pc)
n := runtime.Callers(1, pc)
readDepth = callDepth(pc[:n])
return 0, errors.New("irrelevant")
}))