mirror of
https://github.com/golang/go
synced 2024-11-24 05:20:04 -07:00
cmd/go: two testing fixes
1. Show passing output for "go test" (no args) and with -v flag. 2. Warn about out-of-date packages being rebuilt. R=golang-dev, adg CC=golang-dev https://golang.org/cl/5504080
This commit is contained in:
parent
3800b14071
commit
eef7184046
@ -336,6 +336,26 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
|
||||
return a
|
||||
}
|
||||
|
||||
// actionList returns the list of actions in the dag rooted at root
|
||||
// as visited in a depth-first post-order traversal.
|
||||
func actionList(root *action) []*action {
|
||||
seen := map[*action]bool{}
|
||||
all := []*action{}
|
||||
var walk func(*action)
|
||||
walk = func(a *action) {
|
||||
if seen[a] {
|
||||
return
|
||||
}
|
||||
seen[a] = true
|
||||
for _, a1 := range a.deps {
|
||||
walk(a1)
|
||||
}
|
||||
all = append(all, a)
|
||||
}
|
||||
walk(root)
|
||||
return all
|
||||
}
|
||||
|
||||
// do runs the action graph rooted at root.
|
||||
func (b *builder) do(root *action) {
|
||||
// Build list of all actions, assigning depth-first post-order priority.
|
||||
@ -349,27 +369,16 @@ func (b *builder) do(root *action) {
|
||||
// ensure that, all else being equal, the execution prefers
|
||||
// to do what it would have done first in a simple depth-first
|
||||
// dependency order traversal.
|
||||
all := map[*action]bool{}
|
||||
priority := 0
|
||||
var walk func(*action)
|
||||
walk = func(a *action) {
|
||||
if all[a] {
|
||||
return
|
||||
all := actionList(root)
|
||||
for i, a := range all {
|
||||
a.priority = i
|
||||
}
|
||||
all[a] = true
|
||||
priority++
|
||||
for _, a1 := range a.deps {
|
||||
walk(a1)
|
||||
}
|
||||
a.priority = priority
|
||||
}
|
||||
walk(root)
|
||||
|
||||
b.readySema = make(chan bool, len(all))
|
||||
done := make(chan bool)
|
||||
|
||||
// Initialize per-action execution state.
|
||||
for a := range all {
|
||||
for _, a := range all {
|
||||
for _, a1 := range a.deps {
|
||||
a1.triggers = append(a1.triggers, a)
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ type Package struct {
|
||||
imports []*Package
|
||||
gofiles []string // GoFiles+CgoFiles, absolute paths
|
||||
target string // installed file for this package (may be executable)
|
||||
fake bool // synthesized package
|
||||
}
|
||||
|
||||
// packageCache is a lookup cache for loadPackage,
|
||||
|
@ -195,23 +195,26 @@ See the documentation of the testing package for more information.
|
||||
var (
|
||||
testC bool // -c flag
|
||||
testX bool // -x flag
|
||||
testV bool // -v flag
|
||||
testFiles []string // -file flag(s) TODO: not respected
|
||||
testArgs []string
|
||||
testShowPass bool // whether to display passing output
|
||||
)
|
||||
|
||||
func runTest(cmd *Command, args []string) {
|
||||
// Determine which are the import paths
|
||||
// (leading arguments not starting with -).
|
||||
i := 0
|
||||
for i < len(args) && !strings.HasPrefix(args[i], "-") {
|
||||
i++
|
||||
}
|
||||
pkgs := packages(args[:i])
|
||||
var pkgArgs []string
|
||||
pkgArgs, testArgs = testFlags(args)
|
||||
|
||||
// show test PASS output when no packages
|
||||
// are listed (implicitly current directory: "go test")
|
||||
// or when the -v flag has been given.
|
||||
testShowPass = len(pkgArgs) == 0 || testV
|
||||
|
||||
pkgs := packages(pkgArgs)
|
||||
if len(pkgs) == 0 {
|
||||
fatalf("no packages to test")
|
||||
}
|
||||
|
||||
testArgs = testFlags(args[i:])
|
||||
if testC && len(pkgs) != 1 {
|
||||
fatalf("cannot use -c flag with multiple packages")
|
||||
}
|
||||
@ -243,9 +246,31 @@ func runTest(cmd *Command, args []string) {
|
||||
a.deps = append(a.deps, runs[i-1])
|
||||
}
|
||||
}
|
||||
root := &action{deps: runs}
|
||||
|
||||
allRuns := &action{deps: runs}
|
||||
b.do(allRuns)
|
||||
// If we are building any out-of-date packages other
|
||||
// than those under test, warn.
|
||||
okBuild := map[*Package]bool{}
|
||||
for _, p := range pkgs {
|
||||
okBuild[p] = true
|
||||
}
|
||||
|
||||
warned := false
|
||||
for _, a := range actionList(root) {
|
||||
if a.p != nil && a.f != nil && !okBuild[a.p] && !a.p.fake {
|
||||
okBuild[a.p] = true // don't warn again
|
||||
if !warned {
|
||||
fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
|
||||
warned = true
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\t%s\n", a.p.ImportPath)
|
||||
}
|
||||
}
|
||||
if warned {
|
||||
fmt.Fprintf(os.Stderr, "installing these packages with 'go install' will speed future tests.\n\n")
|
||||
}
|
||||
|
||||
b.do(root)
|
||||
}
|
||||
|
||||
func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
|
||||
@ -312,6 +337,7 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
|
||||
ptest.Imports = append(append([]string{}, p.info.Imports...), p.info.TestImports...)
|
||||
ptest.imports = append(append([]*Package{}, p.imports...), imports...)
|
||||
ptest.pkgdir = testDir
|
||||
ptest.fake = true
|
||||
a := b.action(modeBuild, modeBuild, ptest)
|
||||
a.objdir = testDir + string(filepath.Separator)
|
||||
a.objpkg = ptestObj
|
||||
@ -333,6 +359,7 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
|
||||
info: &build.DirInfo{},
|
||||
imports: imports,
|
||||
pkgdir: testDir,
|
||||
fake: true,
|
||||
}
|
||||
pxtest.imports = append(pxtest.imports, ptest)
|
||||
a := b.action(modeBuild, modeBuild, pxtest)
|
||||
@ -349,6 +376,7 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
|
||||
t: p.t,
|
||||
info: &build.DirInfo{},
|
||||
imports: []*Package{ptest},
|
||||
fake: true,
|
||||
}
|
||||
if pxtest != nil {
|
||||
pmain.imports = append(pmain.imports, pxtest)
|
||||
@ -407,6 +435,9 @@ func (b *builder) runTest(a *action) error {
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil && (bytes.Equal(out, pass[1:]) || bytes.HasSuffix(out, pass)) {
|
||||
fmt.Printf("ok \t%s\n", a.p.ImportPath)
|
||||
if testShowPass {
|
||||
os.Stdout.Write(out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -78,10 +78,39 @@ var testFlagDefn = []*testFlagSpec{
|
||||
// Unfortunately for us, we need to do our own flag processing because go test
|
||||
// grabs some flags but otherwise its command line is just a holding place for
|
||||
// test.out's arguments.
|
||||
func testFlags(args []string) (passToTest []string) {
|
||||
// We allow known flags both before and after the package name list,
|
||||
// to allow both
|
||||
// go test fmt -custom-flag-for-fmt-test
|
||||
// go test -x math
|
||||
func testFlags(args []string) (packageNames, passToTest []string) {
|
||||
inPkg := false
|
||||
for i := 0; i < len(args); i++ {
|
||||
if !strings.HasPrefix(args[i], "-") {
|
||||
if !inPkg && packageNames == nil {
|
||||
// First package name we've seen.
|
||||
inPkg = true
|
||||
}
|
||||
if inPkg {
|
||||
packageNames = append(packageNames, args[i])
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if inPkg {
|
||||
// Found an argument beginning with "-"; end of package list.
|
||||
inPkg = false
|
||||
}
|
||||
|
||||
f, value, extraWord := testFlag(args, i)
|
||||
if f == nil {
|
||||
// This is a flag we do not know; we must assume
|
||||
// that any args we see after this might be flag
|
||||
// arguments, not package names.
|
||||
inPkg = false
|
||||
if packageNames == nil {
|
||||
// make non-nil: we have seen the empty package list
|
||||
packageNames = []string{}
|
||||
}
|
||||
passToTest = append(passToTest, args[i])
|
||||
continue
|
||||
}
|
||||
@ -90,6 +119,8 @@ func testFlags(args []string) (passToTest []string) {
|
||||
setBoolFlag(&testC, value)
|
||||
case "x":
|
||||
setBoolFlag(&testX, value)
|
||||
case "v":
|
||||
setBoolFlag(&testV, value)
|
||||
case "file":
|
||||
testFiles = append(testFiles, value)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user