golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/cmd/callgraph/main_test.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // No testdata on Android. 6 7 //go:build !android && go1.11 8 // +build !android,go1.11 9 10 package main 11 12 import ( 13 "bytes" 14 "fmt" 15 "log" 16 "os" 17 "path/filepath" 18 "strings" 19 "testing" 20 21 "golang.org/x/tools/internal/testenv" 22 ) 23 24 func init() { 25 // This test currently requires GOPATH mode. 26 // Explicitly disabling module mode should suffix, but 27 // we'll also turn off GOPROXY just for good measure. 28 if err := os.Setenv("GO111MODULE", "off"); err != nil { 29 log.Fatal(err) 30 } 31 if err := os.Setenv("GOPROXY", "off"); err != nil { 32 log.Fatal(err) 33 } 34 } 35 36 func TestCallgraph(t *testing.T) { 37 testenv.NeedsTool(t, "go") 38 39 gopath, err := filepath.Abs("testdata") 40 if err != nil { 41 t.Fatal(err) 42 } 43 44 for _, test := range []struct { 45 algo string 46 tests bool 47 want []string 48 }{ 49 {"rta", false, []string{ 50 // rta imprecisely shows cross product of {main,main2} x {C,D} 51 `pkg.main --> (pkg.C).f`, 52 `pkg.main --> (pkg.D).f`, 53 `pkg.main --> pkg.main2`, 54 `pkg.main2 --> (pkg.C).f`, 55 `pkg.main2 --> (pkg.D).f`, 56 }}, 57 {"vta", false, []string{ 58 // vta distinguishes main->C, main2->D. 59 "pkg.main --> (pkg.C).f", 60 "pkg.main --> pkg.main2", 61 "pkg.main2 --> (pkg.D).f", 62 }}, 63 // tests: both the package's main and the test's main are called. 64 // The callgraph includes all the guts of the "testing" package. 65 {"rta", true, []string{ 66 `pkg.test.main --> testing.MainStart`, 67 `testing.runExample --> pkg.Example`, 68 `pkg.Example --> (pkg.C).f`, 69 `pkg.main --> (pkg.C).f`, 70 }}, 71 {"vta", true, []string{ 72 `pkg.test.main --> testing.MainStart`, 73 `testing.runExample --> pkg.Example`, 74 `pkg.Example --> (pkg.C).f`, 75 `pkg.main --> (pkg.C).f`, 76 }}, 77 } { 78 const format = "{{.Caller}} --> {{.Callee}}" 79 stdout = new(bytes.Buffer) 80 if err := doCallgraph("testdata/src", gopath, test.algo, format, test.tests, []string{"pkg"}); err != nil { 81 t.Error(err) 82 continue 83 } 84 85 edges := make(map[string]bool) 86 for _, line := range strings.Split(fmt.Sprint(stdout), "\n") { 87 edges[line] = true 88 } 89 ok := true 90 for _, edge := range test.want { 91 if !edges[edge] { 92 ok = false 93 t.Errorf("callgraph(%q, %t): missing edge: %s", 94 test.algo, test.tests, edge) 95 } 96 } 97 if !ok { 98 t.Log("got:\n", stdout) 99 } 100 } 101 }