github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/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  	"runtime"
    19  	"strings"
    20  	"testing"
    21  
    22  	"golang.org/x/tools/internal/testenv"
    23  )
    24  
    25  func init() {
    26  	// This test currently requires GOPATH mode.
    27  	// Explicitly disabling module mode should suffix, but
    28  	// we'll also turn off GOPROXY just for good measure.
    29  	if err := os.Setenv("GO111MODULE", "off"); err != nil {
    30  		log.Fatal(err)
    31  	}
    32  	if err := os.Setenv("GOPROXY", "off"); err != nil {
    33  		log.Fatal(err)
    34  	}
    35  }
    36  
    37  func TestCallgraph(t *testing.T) {
    38  	if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
    39  		t.Skipf("skipping due to suspected file corruption bug on windows/arm64 (https://go.dev/issue/50706)")
    40  	}
    41  
    42  	testenv.NeedsTool(t, "go")
    43  
    44  	gopath, err := filepath.Abs("testdata")
    45  	if err != nil {
    46  		t.Fatal(err)
    47  	}
    48  
    49  	for _, test := range []struct {
    50  		algo  string
    51  		tests bool
    52  		want  []string
    53  	}{
    54  		{"rta", false, []string{
    55  			// rta imprecisely shows cross product of {main,main2} x {C,D}
    56  			`pkg.main --> (pkg.C).f`,
    57  			`pkg.main --> (pkg.D).f`,
    58  			`pkg.main --> pkg.main2`,
    59  			`pkg.main2 --> (pkg.C).f`,
    60  			`pkg.main2 --> (pkg.D).f`,
    61  		}},
    62  		{"vta", false, []string{
    63  			// vta distinguishes main->C, main2->D.
    64  			"pkg.main --> (pkg.C).f",
    65  			"pkg.main --> pkg.main2",
    66  			"pkg.main2 --> (pkg.D).f",
    67  		}},
    68  		{"pta", false, []string{
    69  			// pta distinguishes main->C, main2->D.  Also has a root node.
    70  			`<root> --> pkg.init`,
    71  			`<root> --> pkg.main`,
    72  			`pkg.main --> (pkg.C).f`,
    73  			`pkg.main --> pkg.main2`,
    74  			`pkg.main2 --> (pkg.D).f`,
    75  		}},
    76  		// tests: both the package's main and the test's main are called.
    77  		// The callgraph includes all the guts of the "testing" package.
    78  		{"rta", true, []string{
    79  			`pkg.test.main --> testing.MainStart`,
    80  			`testing.runExample --> pkg.Example`,
    81  			`pkg.Example --> (pkg.C).f`,
    82  			`pkg.main --> (pkg.C).f`,
    83  		}},
    84  		{"vta", true, []string{
    85  			`pkg.test.main --> testing.MainStart`,
    86  			`testing.runExample --> pkg.Example`,
    87  			`pkg.Example --> (pkg.C).f`,
    88  			`pkg.main --> (pkg.C).f`,
    89  		}},
    90  		{"pta", true, []string{
    91  			`<root> --> pkg.test.main`,
    92  			`<root> --> pkg.main`,
    93  			`pkg.test.main --> testing.MainStart`,
    94  			`testing.runExample --> pkg.Example`,
    95  			`pkg.Example --> (pkg.C).f`,
    96  			`pkg.main --> (pkg.C).f`,
    97  		}},
    98  	} {
    99  		const format = "{{.Caller}} --> {{.Callee}}"
   100  		stdout = new(bytes.Buffer)
   101  		if err := doCallgraph("testdata/src", gopath, test.algo, format, test.tests, []string{"pkg"}); err != nil {
   102  			t.Error(err)
   103  			continue
   104  		}
   105  
   106  		edges := make(map[string]bool)
   107  		for _, line := range strings.Split(fmt.Sprint(stdout), "\n") {
   108  			edges[line] = true
   109  		}
   110  		ok := true
   111  		for _, edge := range test.want {
   112  			if !edges[edge] {
   113  				ok = false
   114  				t.Errorf("callgraph(%q, %t): missing edge: %s",
   115  					test.algo, test.tests, edge)
   116  			}
   117  		}
   118  		if !ok {
   119  			t.Log("got:\n", stdout)
   120  		}
   121  	}
   122  }