]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: two testing fixes
authorRuss Cox <rsc@golang.org>
Fri, 23 Dec 2011 03:24:43 +0000 (22:24 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 23 Dec 2011 03:24:43 +0000 (22:24 -0500)
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

src/cmd/go/build.go
src/cmd/go/pkg.go
src/cmd/go/test.go
src/cmd/go/testflag.go

index 7e87956e7d26f8e2983c5615ca0b06f0ca91f67b..701d6cd6d744b5fb829fef6160e0489f57d6aa53 100644 (file)
@@ -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[a] = true
-               priority++
-               for _, a1 := range a.deps {
-                       walk(a1)
-               }
-               a.priority = priority
+       all := actionList(root)
+       for i, a := range all {
+               a.priority = i
        }
-       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)
                }
index 8f0f59c6877cc2811147c825d2eacde900affd53..f3f79b6a7db207e05271e6b6cee7194ebc6c6e44 100644 (file)
@@ -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,
index e43a2711f14a0404cbf7a1fe132a71b8eca0e653..4904703ec3f8f82676050cf75fb2ab7494e3675b 100644 (file)
@@ -193,25 +193,28 @@ See the documentation of the testing package for more information.
 // For now just use the gotest code.
 
 var (
-       testC     bool     // -c flag
-       testX     bool     // -x flag
-       testFiles []string // -file flag(s)  TODO: not respected
-       testArgs  []string
+       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}
+
+       // 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")
+       }
 
-       allRuns := &action{deps: runs}
-       b.do(allRuns)
+       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
        }
 
index 249a9316b1b120ae596f53451b601bee29c99d0b..07133035e9a25d51cf6f0a59c3739716cfb285ca 100644 (file)
@@ -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)
                }