blob: 8f22236288f280de860f498b0ee276546cc936d7 [file] [log] [blame]
// Copyright 2020 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.
package stack_test
import (
"bytes"
"strings"
"testing"
"golang.org/x/exp/internal/stack"
)
func TestProcess(t *testing.T) {
for _, test := range []struct{ name, input, expect string }{{
name: `empty`,
input: ``,
expect: ``,
}, {
name: `no_frame`,
input: `goroutine 1 [running]:`,
expect: `
[running]: $1
1 goroutines, 1 unique
`,
}, {
name: `one_frame`,
input: `
goroutine 1 [running]:
package.function(args)
file.go:10
`,
expect: `
[running]: $1
file.go:10: function
1 goroutines, 1 unique
`,
}, {
name: `one_call`,
input: `
goroutine 1 [running]:
package1.functionA(args)
file1.go:10
package2.functionB(args)
file2.go:20
package3.functionC(args)
file3.go:30
`,
expect: `
[running]: $1
file1.go:10: functionA
file2.go:20: functionB
file3.go:30: functionC
1 goroutines, 1 unique
`,
}, {
name: `two_call`,
input: `
goroutine 1 [running]:
package1.functionA(args)
file1.go:10
goroutine 2 [running]:
package2.functionB(args)
file2.go:20
`,
expect: `
[running]: $1
file1.go:10: functionA
[running]: $2
file2.go:20: functionB
2 goroutines, 2 unique
`,
}, {
name: `merge_call`,
input: `
goroutine 1 [running]:
package1.functionA(args)
file1.go:10
goroutine 2 [running]:
package1.functionA(args)
file1.go:10
`,
expect: `
[running]: $1, $2
file1.go:10: functionA
2 goroutines, 1 unique
`,
}, {
name: `alternating_call`,
input: `
goroutine 1 [running]:
package1.functionA(args)
file1.go:10
goroutine 2 [running]:
package2.functionB(args)
file2.go:20
goroutine 3 [running]:
package1.functionA(args)
file1.go:10
goroutine 4 [running]:
package2.functionB(args)
file2.go:20
goroutine 5 [running]:
package1.functionA(args)
file1.go:10
goroutine 6 [running]:
package2.functionB(args)
file2.go:20
`,
expect: `
[running]: $1, $3, $5
file1.go:10: functionA
[running]: $2, $4, $6
file2.go:20: functionB
6 goroutines, 2 unique
`,
}, {
name: `sort_calls`,
input: `
goroutine 1 [running]:
package3.functionC(args)
file3.go:30
goroutine 2 [running]:
package2.functionB(args)
file2.go:20
goroutine 3 [running]:
package1.functionA(args)
file1.go:10
`,
expect: `
[running]: $3
file1.go:10: functionA
[running]: $2
file2.go:20: functionB
[running]: $1
file3.go:30: functionC
3 goroutines, 3 unique
`,
}, {
name: `real_single`,
input: `
panic: oops
goroutine 53 [running]:
golang.org/x/tools/internal/jsonrpc2_test.testHandler.func1(0x1240c20, 0xc000013350, 0xc0000133b0, 0x1240ca0, 0xc00002ab00, 0x3, 0x3)
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:160 +0x74c
golang.org/x/tools/internal/jsonrpc2.(*Conn).Run(0xc000204330, 0x1240c20, 0xc000204270, 0x1209570, 0xc000212120, 0x1242700)
/work/tools/internal/jsonrpc2/jsonrpc2.go:187 +0x777
golang.org/x/tools/internal/jsonrpc2_test.run.func1(0x123ebe0, 0xc000206018, 0x123ec20, 0xc000206010, 0xc0002080a0, 0xc000204330, 0x1240c20, 0xc000204270, 0xc000212120)
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:131 +0xe2
created by golang.org/x/tools/internal/jsonrpc2_test.run
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:121 +0x263
FAIL golang.org/x/tools/internal/jsonrpc2 0.252s
FAIL
`,
expect: `
panic: oops
[running]: $53
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:160: testHandler.func1
/work/tools/internal/jsonrpc2/jsonrpc2.go:187: (*Conn).Run
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:131: run.func1
/work/tools/internal/jsonrpc2/jsonrpc2_test.go:121: run
1 goroutines, 1 unique
FAIL golang.org/x/tools/internal/jsonrpc2 0.252s
FAIL
`,
}} {
t.Run(test.name, func(t *testing.T) {
buf := &bytes.Buffer{}
stack.Process(buf, strings.NewReader(test.input))
expect := strings.TrimSpace(test.expect)
got := strings.TrimSpace(buf.String())
if got != expect {
t.Errorf("got:\n%s\nexpect:\n%s", got, expect)
}
})
}
}