go/src/pkg/runtime/debug/stack_test.go

63 lines
1.7 KiB
Go
Raw Normal View History

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
testing: let runtime catch the panic. It's not as pretty, but it deletes some irrelevant information from the printout and avoids a dependency. It also means the test binary will stop if a test panics. That's a feature, not a bug. Any output printed by the test appears before the panic traceback. before: --- FAIL: TestPanic (0.00 seconds) fmt_test.go:19: HI testing.go:257: runtime error: index out of range /Users/r/go/src/pkg/testing/testing.go:257 (0x23998) _func_003: t.Logf("%s\n%s", err, debug.Stack()) /Users/r/go/src/pkg/runtime/proc.c:1388 (0x10d2d) panic: reflect·call(d->fn, d->args, d->siz); /Users/r/go/src/pkg/runtime/runtime.c:128 (0x119b0) panicstring: runtime·panic(err); /Users/r/go/src/pkg/runtime/runtime.c:85 (0x11857) panicindex: runtime·panicstring("index out of range"); /Users/r/go/src/pkg/fmt/fmt_test.go:21 (0x23d72) TestPanic: a[10]=1 /Users/r/go/src/pkg/testing/testing.go:264 (0x21b75) tRunner: test.F(t) /Users/r/go/src/pkg/runtime/proc.c:258 (0xee9e) goexit: runtime·goexit(void) FAIL after: --- FAIL: TestPanic (0.00 seconds) fmt_test.go:19: HI panic: runtime error: index out of range [recovered] panic: (*testing.T) (0xec3b0,0xf8400001c0) goroutine 2 [running]: testing._func_003(0x21f5fa8, 0x21f5100, 0x21f5fb8, 0x21f5e88) /Users/r/go/src/pkg/testing/testing.go:259 +0x108 ----- stack segment boundary ----- fmt_test.TestPanic(0xf8400001c0, 0x27603728) /Users/r/go/src/pkg/fmt/fmt_test.go:21 +0x6b testing.tRunner(0xf8400001c0, 0x18edb8, 0x0, 0x0) /Users/r/go/src/pkg/testing/testing.go:264 +0x6f created by testing.RunTests /Users/r/go/src/pkg/testing/testing.go:343 +0x76e goroutine 1 [chan receive]: testing.RunTests(0x2000, 0x18edb8, 0x2400000024, 0x100000001, 0x200000001, ...) /Users/r/go/src/pkg/testing/testing.go:344 +0x791 testing.Main(0x2000, 0x18edb8, 0x2400000024, 0x188a58, 0x800000008, ...) /Users/r/go/src/pkg/testing/testing.go:275 +0x62 main.main() /var/folders/++/+++Fn+++6+0++4RjPqRgNE++2Qk/-Tmp-/go-build743922747/fmt/_test/_testmain.go:129 +0x91 exit status 2 R=rsc, dsymonds CC=golang-dev https://golang.org/cl/5658048
2012-02-14 14:53:30 +11:00
package debug
import (
"strings"
"testing"
)
type T int
func (t *T) ptrmethod() []byte {
return Stack()
}
func (t T) method() []byte {
return t.ptrmethod()
}
/*
The traceback should look something like this, modulo line numbers and hex constants.
Don't worry much about the base levels, but check the ones in our own package.
/Users/r/go/src/pkg/runtime/debug/stack_test.go:15 (0x13878)
(*T).ptrmethod: return Stack()
/Users/r/go/src/pkg/runtime/debug/stack_test.go:18 (0x138dd)
T.method: return t.ptrmethod()
/Users/r/go/src/pkg/runtime/debug/stack_test.go:23 (0x13920)
TestStack: b := T(0).method()
/Users/r/go/src/pkg/testing/testing.go:132 (0x14a7a)
tRunner: test.F(t)
/Users/r/go/src/pkg/runtime/proc.c:145 (0xc970)
???: runtime·unlock(&runtime·sched);
*/
func TestStack(t *testing.T) {
b := T(0).method()
lines := strings.Split(string(b), "\n")
if len(lines) <= 6 {
t.Fatal("too few lines")
}
n := 0
frame := func(line, code string) {
check(t, lines[n], line)
n++
// The source might not be available while running the test.
if strings.HasPrefix(lines[n], "\t") {
check(t, lines[n], code)
n++
}
}
frame("src/pkg/runtime/debug/stack_test.go", "\t(*T).ptrmethod: return Stack()")
frame("src/pkg/runtime/debug/stack_test.go", "\tT.method: return t.ptrmethod()")
frame("src/pkg/runtime/debug/stack_test.go", "\tTestStack: b := T(0).method()")
frame("src/pkg/testing/testing.go", "")
}
func check(t *testing.T, line, has string) {
if strings.Index(line, has) < 0 {
t.Errorf("expected %q in %q", has, line)
}
}