mirror of
https://github.com/golang/go
synced 2024-11-05 11:36:10 -07:00
8e53eb937b
Supporting user-defined TestMain functions requires that we generate a "testmain" package for each testable package, rather than a single one for the entire program. This entails these API changes: 1. (*ssa.Program).{CreateTestMainPackage,FindTests} both now accept only a single package. Existing clients that pass them multiple packages must call them from a loop. 2. (*ssa.Program).FindTests returns an additional result, the the optional TestMain *ssa.Function. Existing clients may discard it. Also: - Test the new logic using the SSA interpreter - add ssautil.MainPackages helper - callgraph: allow multiple main packages, and analyze them all - ssadump -run: allow multiple main/test packages, and run each in a new interpreter - minor simplifications to some callers (e.g. guru) Fixes golang/go#9553 Change-Id: Ia7de9bd27448fb08b8d172ba5cdbcf37a762b7a0 Reviewed-on: https://go-review.googlesource.com/25102 Reviewed-by: Robert Griesemer <gri@golang.org>
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
// 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
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"go/build"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCallgraph(t *testing.T) {
|
|
ctxt := build.Default // copy
|
|
ctxt.GOPATH = "testdata"
|
|
|
|
const format = "{{.Caller}} --> {{.Callee}}"
|
|
|
|
for _, test := range []struct {
|
|
algo, format string
|
|
tests bool
|
|
want []string
|
|
}{
|
|
{"rta", format, false, []string{
|
|
// 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`,
|
|
}},
|
|
{"pta", format, false, []string{
|
|
// 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`,
|
|
}},
|
|
// tests: main is not called.
|
|
{"rta", format, true, []string{
|
|
`pkg$testmain.init --> pkg.init`,
|
|
`pkg.Example --> (pkg.C).f`,
|
|
}},
|
|
{"pta", format, true, []string{
|
|
`<root> --> pkg$testmain.init`,
|
|
`<root> --> pkg.Example`,
|
|
`pkg$testmain.init --> pkg.init`,
|
|
`pkg.Example --> (pkg.C).f`,
|
|
}},
|
|
} {
|
|
stdout = new(bytes.Buffer)
|
|
if err := doCallgraph(&ctxt, test.algo, test.format, test.tests, []string{"pkg"}); err != nil {
|
|
t.Error(err)
|
|
continue
|
|
}
|
|
|
|
got := sortedLines(fmt.Sprint(stdout))
|
|
if !reflect.DeepEqual(got, test.want) {
|
|
t.Errorf("callgraph(%q, %q, %t):\ngot:\n%s\nwant:\n%s",
|
|
test.algo, test.format, test.tests,
|
|
strings.Join(got, "\n"),
|
|
strings.Join(test.want, "\n"))
|
|
}
|
|
}
|
|
}
|
|
|
|
func sortedLines(s string) []string {
|
|
s = strings.TrimSpace(s)
|
|
lines := strings.Split(s, "\n")
|
|
sort.Strings(lines)
|
|
return lines
|
|
}
|