forked from getsentry/raven-go
/
stacktrace_test.go
123 lines (108 loc) · 2.68 KB
/
stacktrace_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package raven
import (
"fmt"
"go/build"
"path/filepath"
"runtime"
"strings"
"testing"
)
type FunctionNameTest struct {
skip int
pack string
name string
}
var (
thisFile string
thisPackage string
functionNameTests []FunctionNameTest
)
func TestFunctionName(t *testing.T) {
for _, test := range functionNameTests {
pc, _, _, _ := runtime.Caller(test.skip)
pack, name := functionName(pc)
if pack != test.pack {
t.Errorf("incorrect package; got %s, want %s", pack, test.pack)
}
if name != test.name {
t.Errorf("incorrect function; got %s, want %s", name, test.name)
}
}
}
func TestStacktrace(t *testing.T) {
st := trace()
if st == nil {
t.Error("got nil stacktrace")
}
if len(st.Frames) == 0 {
t.Error("got zero frames")
}
f := st.Frames[len(st.Frames)-1]
if f.Filename != thisFile {
t.Errorf("incorrect Filename; got %s, want %s", f.Filename, thisFile)
}
if !strings.HasSuffix(f.AbsolutePath, thisFile) {
t.Error("incorrect AbsolutePath:", f.AbsolutePath)
}
if f.Function != "trace" {
t.Error("incorrect Function:", f.Function)
}
if f.Module != thisPackage {
t.Error("incorrect Module:", f.Module)
}
if f.Lineno != 83 {
t.Error("incorrect Lineno:", f.Lineno)
}
if f.ContextLine != "\treturn NewStacktrace(0, 2, []string{thisPackage})" {
t.Errorf("incorrect ContextLine: %#v", f.ContextLine)
}
if len(f.PreContext) != 2 || f.PreContext[0] != "// a" || f.PreContext[1] != "func trace() *Stacktrace {" {
t.Errorf("incorrect PreContext %#v", f.PreContext)
}
if len(f.PostContext) != 2 || f.PostContext[0] != "\t// b" || f.PostContext[1] != "}" {
t.Errorf("incorrect PostContext %#v", f.PostContext)
}
if !*f.InApp {
t.Error("expected InApp to be true")
}
if st.Culprit() != fmt.Sprintf("%s.trace", thisPackage) {
t.Error("incorrect Culprit:", st.Culprit())
}
}
// a
func trace() *Stacktrace {
return NewStacktrace(0, 2, []string{thisPackage})
// b
}
func derivePackage() (file, pack string) {
// Get file name by seeking caller's file name.
_, callerFile, _, ok := runtime.Caller(1)
if !ok {
return
}
// Trim file name
file = callerFile
for _, dir := range build.Default.SrcDirs() {
dir := dir + string(filepath.Separator)
if trimmed := strings.TrimPrefix(callerFile, dir); len(trimmed) < len(file) {
file = trimmed
}
}
// Now derive package name
dir := filepath.Dir(callerFile)
dirPkg, err := build.ImportDir(dir, build.AllowBinary)
if err != nil {
return
}
pack = dirPkg.ImportPath
return
}
func init() {
thisFile, thisPackage = derivePackage()
functionNameTests = []FunctionNameTest{
{0, thisPackage, "TestFunctionName"},
{1, "testing", "tRunner"},
{2, "runtime", "goexit"},
{100, "", ""},
}
}