]> Cypherpunks repositories - gostls13.git/commitdiff
testing: add -test.cpuprofile flag
authorRuss Cox <rsc@golang.org>
Wed, 23 Mar 2011 22:17:14 +0000 (18:17 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 23 Mar 2011 22:17:14 +0000 (18:17 -0400)
R=r
CC=golang-dev
https://golang.org/cl/4272066

src/cmd/gotest/gotest
src/cmd/prof/gopprof
src/pkg/testing/testing.go

index 4cadb5c94d8209bcfc96f227684deb4904225eb2..d00c9d4cd2f1ad7fa15da5a63103d9f9bd775071 100755 (executable)
@@ -203,8 +203,7 @@ func matchString(pat, str string) (result bool, err __os__.Error) {
 }
 
 func main() {
-       testing.Main(matchString, tests)
-       testing.RunBenchmarks(matchString, benchmarks)
+       testing.Main(matchString, tests, benchmarks)
 }'
 }>_testmain.go
 
index e391f36a0b4f74b70b80b5dcab2fe23fef8957ee..8fa00cbe8c5b41d84c5c6e0e2d94dc2970b5ae82 100755 (executable)
@@ -2476,7 +2476,8 @@ sub RemoveUninterestingFrames {
     # Nothing skipped for unknown types
   }
 
-  if ($main::profile_type eq 'cpu') {
+  # Go doesn't have the problem that this heuristic tries to fix.  Disable.
+  if (0 && $main::profile_type eq 'cpu') {
     # If all the second-youngest program counters are the same,
     # this STRONGLY suggests that it is an artifact of measurement,
     # i.e., stack frames pushed by the CPU profiler signal handler.
@@ -2976,7 +2977,7 @@ sub FetchDynamicProfile {
         $url = sprintf("http://$profile_name" . "seconds=%d",
             $main::opt_seconds);
       }
-      $curl_timeout = sprintf("--max-time=%d",
+      $curl_timeout = sprintf("--max-time %d",
                               int($main::opt_seconds * 1.01 + 60));
     } else {
       # For non-CPU profiles, we add a type-extension to
index 0751436903ed69e3c12903b83570ad8536723a68..ab8cf999a2564dd6c3d7c0b4f74f79bc60218e5c 100644 (file)
@@ -51,8 +51,9 @@ var (
        // Report as tests are run; default is silent for success.
        chatty         = flag.Bool("test.v", false, "verbose: print additional output")
        match          = flag.String("test.run", "", "regular expression to select tests to run")
-       memProfile     = flag.String("test.memprofile", "", "after execution write the memory profile to the named file")
+       memProfile     = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
        memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
+       cpuProfile     = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
 )
 
 
@@ -141,10 +142,16 @@ func tRunner(t *T, test *InternalTest) {
 
 // An internal function but exported because it is cross-package; part of the implementation
 // of gotest.
-func Main(matchString func(pat, str string) (bool, os.Error), tests []InternalTest) {
+func Main(matchString func(pat, str string) (bool, os.Error), tests []InternalTest, benchmarks []InternalBenchmark) {
        flag.Parse()
 
        before()
+       RunTests(matchString, tests)
+       RunBenchmarks(matchString, benchmarks)
+       after()
+}
+
+func RunTests(matchString func(pat, str string) (bool, os.Error), tests []InternalTest) {
        ok := true
        if len(tests) == 0 {
                println("testing: warning: no tests to run")
@@ -177,7 +184,6 @@ func Main(matchString func(pat, str string) (bool, os.Error), tests []InternalTe
                        print(t.errors)
                }
        }
-       after()
        if !ok {
                println("FAIL")
                os.Exit(1)
@@ -190,20 +196,36 @@ func before() {
        if *memProfileRate > 0 {
                runtime.MemProfileRate = *memProfileRate
        }
+       if *cpuProfile != "" {
+               f, err := os.Open(*cpuProfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0666)
+               if err != nil {
+                       fmt.Fprintf(os.Stderr, "testing: %s", err)
+                       return
+               }
+               if err := pprof.StartCPUProfile(f); err != nil {
+                       fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s", err)
+                       f.Close()
+                       return
+               }
+               // Could save f so after can call f.Close; not worth the effort.
+       }
+
 }
 
 // after runs after all testing.
 func after() {
-       if *memProfile == "" {
-               return
-       }
-       fd, err := os.Open(*memProfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0666)
-       if err != nil {
-               fmt.Fprintf(os.Stderr, "testing: can't open %s: %s", *memProfile, err)
-               return
+       if *cpuProfile != "" {
+               pprof.StopCPUProfile() // flushes profile to disk
        }
-       if err = pprof.WriteHeapProfile(fd); err != nil {
-               fmt.Fprintf(os.Stderr, "testing: can't write %s: %s", *memProfile, err)
+       if *memProfile != "" {
+               f, err := os.Open(*memProfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0666)
+               if err != nil {
+                       fmt.Fprintf(os.Stderr, "testing: %s", err)
+                       return
+               }
+               if err = pprof.WriteHeapProfile(f); err != nil {
+                       fmt.Fprintf(os.Stderr, "testing: can't write %s: %s", *memProfile, err)
+               }
+               f.Close()
        }
-       fd.Close()
 }