2015-08-05 18:53:24 -06:00
|
|
|
// Copyright 2014 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.
|
|
|
|
|
|
|
|
// No testdata on Android.
|
|
|
|
|
|
|
|
// +build !android
|
2018-08-13 11:45:06 -06:00
|
|
|
// +build go1.11
|
2015-08-05 18:53:24 -06:00
|
|
|
|
2014-11-12 15:36:22 -07:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2018-08-08 15:02:13 -06:00
|
|
|
"path/filepath"
|
2014-11-12 15:36:22 -07:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCallgraph(t *testing.T) {
|
2018-08-08 15:02:13 -06:00
|
|
|
gopath, err := filepath.Abs("testdata")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2014-11-12 15:36:22 -07:00
|
|
|
|
|
|
|
for _, test := range []struct {
|
2018-08-08 15:02:13 -06:00
|
|
|
algo string
|
|
|
|
tests bool
|
|
|
|
want []string
|
2014-11-12 15:36:22 -07:00
|
|
|
}{
|
2018-08-08 15:02:13 -06:00
|
|
|
{"rta", false, []string{
|
2014-11-12 15:36:22 -07:00
|
|
|
// rta imprecisely shows cross product of {main,main2} x {C,D}
|
|
|
|
`pkg.main --> (pkg.C).f`,
|
|
|
|
`pkg.main --> (pkg.D).f`,
|
|
|
|
`pkg.main --> pkg.main2`,
|
|
|
|
`pkg.main2 --> (pkg.C).f`,
|
|
|
|
`pkg.main2 --> (pkg.D).f`,
|
|
|
|
}},
|
2018-08-08 15:02:13 -06:00
|
|
|
{"pta", false, []string{
|
2014-11-12 15:36:22 -07:00
|
|
|
// pta distinguishes main->C, main2->D. Also has a root node.
|
|
|
|
`<root> --> pkg.init`,
|
|
|
|
`<root> --> pkg.main`,
|
|
|
|
`pkg.main --> (pkg.C).f`,
|
|
|
|
`pkg.main --> pkg.main2`,
|
|
|
|
`pkg.main2 --> (pkg.D).f`,
|
|
|
|
}},
|
2018-08-08 15:02:13 -06:00
|
|
|
// tests: both the package's main and the test's main are called.
|
|
|
|
// The callgraph includes all the guts of the "testing" package.
|
|
|
|
{"rta", true, []string{
|
|
|
|
`pkg.test.main --> testing.MainStart`,
|
|
|
|
`testing.runExample --> pkg.Example`,
|
2014-11-12 15:36:22 -07:00
|
|
|
`pkg.Example --> (pkg.C).f`,
|
2018-08-08 15:02:13 -06:00
|
|
|
`pkg.main --> (pkg.C).f`,
|
2014-11-12 15:36:22 -07:00
|
|
|
}},
|
2018-08-08 15:02:13 -06:00
|
|
|
{"pta", true, []string{
|
|
|
|
`<root> --> pkg.test.main`,
|
|
|
|
`<root> --> pkg.main`,
|
|
|
|
`pkg.test.main --> testing.MainStart`,
|
|
|
|
`testing.runExample --> pkg.Example`,
|
2014-11-12 15:36:22 -07:00
|
|
|
`pkg.Example --> (pkg.C).f`,
|
2018-08-08 15:02:13 -06:00
|
|
|
`pkg.main --> (pkg.C).f`,
|
2014-11-12 15:36:22 -07:00
|
|
|
}},
|
|
|
|
} {
|
2018-08-08 15:02:13 -06:00
|
|
|
const format = "{{.Caller}} --> {{.Callee}}"
|
2014-11-12 15:36:22 -07:00
|
|
|
stdout = new(bytes.Buffer)
|
2018-08-08 15:02:13 -06:00
|
|
|
if err := doCallgraph("testdata/src", gopath, test.algo, format, test.tests, []string{"pkg"}); err != nil {
|
2014-11-12 15:36:22 -07:00
|
|
|
t.Error(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-08-08 15:02:13 -06:00
|
|
|
edges := make(map[string]bool)
|
|
|
|
for _, line := range strings.Split(fmt.Sprint(stdout), "\n") {
|
|
|
|
edges[line] = true
|
|
|
|
}
|
|
|
|
for _, edge := range test.want {
|
|
|
|
if !edges[edge] {
|
|
|
|
t.Errorf("callgraph(%q, %t): missing edge: %s",
|
|
|
|
test.algo, test.tests, edge)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if t.Failed() {
|
|
|
|
t.Log("got:\n", stdout)
|
2014-11-12 15:36:22 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|