OSDN Git Service

libgo: Update to weekly.2012-03-13.
[pf3gnuchains/gcc-fork.git] / libgo / go / testing / testing.go
1 // Copyright 2009 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 // Package testing provides support for automated testing of Go packages.
6 // It is intended to be used in concert with the ``go test'' command, which automates
7 // execution of any function of the form
8 //     func TestXxx(*testing.T)
9 // where Xxx can be any alphanumeric string (but the first letter must not be in
10 // [a-z]) and serves to identify the test routine.
11 // These TestXxx routines should be declared within the package they are testing.
12 //
13 // Functions of the form
14 //     func BenchmarkXxx(*testing.B)
15 // are considered benchmarks, and are executed by the "go test" command when
16 // the -test.bench flag is provided.
17 //
18 // A sample benchmark function looks like this:
19 //     func BenchmarkHello(b *testing.B) {
20 //         for i := 0; i < b.N; i++ {
21 //             fmt.Sprintf("hello")
22 //         }
23 //     }
24 //
25 // The benchmark package will vary b.N until the benchmark function lasts
26 // long enough to be timed reliably.  The output
27 //     testing.BenchmarkHello    10000000    282 ns/op
28 // means that the loop ran 10000000 times at a speed of 282 ns per loop.
29 //
30 // If a benchmark needs some expensive setup before running, the timer
31 // may be stopped:
32 //     func BenchmarkBigLen(b *testing.B) {
33 //         b.StopTimer()
34 //         big := NewBig()
35 //         b.StartTimer()
36 //         for i := 0; i < b.N; i++ {
37 //             big.Len()
38 //         }
39 //     }
40 //
41 // The package also runs and verifies example code. Example functions may
42 // include a concluding comment that begins with "Output:" and is compared with
43 // the standard output of the function when the tests are run, as in these
44 // examples of an example:
45 //
46 //     func ExampleHello() {
47 //             fmt.Println("hello")
48 //             // Output: hello
49 //     }
50 //
51 //     func ExampleSalutations() {
52 //             fmt.Println("hello, and")
53 //             fmt.Println("goodbye")
54 //             // Output:
55 //             // hello, and
56 //             // goodbye
57 //     }
58 //
59 // Example functions without output comments are compiled but not executed.
60 //
61 // The naming convention to declare examples for a function F, a type T and
62 // method M on type T are:
63 //
64 //     func ExampleF() { ... }
65 //     func ExampleT() { ... }
66 //     func ExampleT_M() { ... }
67 //
68 // Multiple example functions for a type/function/method may be provided by
69 // appending a distinct suffix to the name. The suffix must start with a
70 // lower-case letter.
71 //
72 //     func ExampleF_suffix() { ... }
73 //     func ExampleT_suffix() { ... }
74 //     func ExampleT_M_suffix() { ... }
75 //
76 // The entire test file is presented as the example when it contains a single
77 // example function, at least one other function, type, variable, or constant
78 // declaration, and no test or benchmark functions.
79 package testing
80
81 import (
82         _ "debug/elf"
83         "flag"
84         "fmt"
85         "os"
86         "runtime"
87         "runtime/pprof"
88         "strconv"
89         "strings"
90         "time"
91 )
92
93 var (
94         // The short flag requests that tests run more quickly, but its functionality
95         // is provided by test writers themselves.  The testing package is just its
96         // home.  The all.bash installation script sets it to make installation more
97         // efficient, but by default the flag is off so a plain "go test" will do a
98         // full test of the package.
99         short = flag.Bool("test.short", false, "run smaller test suite to save time")
100
101         // Report as tests are run; default is silent for success.
102         chatty         = flag.Bool("test.v", false, "verbose: print additional output")
103         match          = flag.String("test.run", "", "regular expression to select tests and examples to run")
104         memProfile     = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
105         memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
106         cpuProfile     = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
107         timeout        = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
108         cpuListStr     = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
109         parallel       = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
110
111         haveExamples bool // are there examples?
112
113         cpuList []int
114 )
115
116 // common holds the elements common between T and B and
117 // captures common methods such as Errorf.
118 type common struct {
119         output   []byte    // Output generated by test or benchmark.
120         failed   bool      // Test or benchmark has failed.
121         start    time.Time // Time test or benchmark started
122         duration time.Duration
123         self     interface{}      // To be sent on signal channel when done.
124         signal   chan interface{} // Output for serial tests.
125 }
126
127 // Short reports whether the -test.short flag is set.
128 func Short() bool {
129         return *short
130 }
131
132 // decorate inserts the final newline if needed and indentation tabs for formatting.
133 // If addFileLine is true, it also prefixes the string with the file and line of the call site.
134 func decorate(s string, addFileLine bool) string {
135         if addFileLine {
136                 _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
137                 if ok {
138                         // Truncate file name at last file name separator.
139                         if index := strings.LastIndex(file, "/"); index >= 0 {
140                                 file = file[index+1:]
141                         } else if index = strings.LastIndex(file, "\\"); index >= 0 {
142                                 file = file[index+1:]
143                         }
144                 } else {
145                         file = "???"
146                         line = 1
147                 }
148                 s = fmt.Sprintf("%s:%d: %s", file, line, s)
149         }
150         s = "\t" + s // Every line is indented at least one tab.
151         n := len(s)
152         if n > 0 && s[n-1] != '\n' {
153                 s += "\n"
154                 n++
155         }
156         for i := 0; i < n-1; i++ { // -1 to avoid final newline
157                 if s[i] == '\n' {
158                         // Second and subsequent lines are indented an extra tab.
159                         return s[0:i+1] + "\t" + decorate(s[i+1:n], false)
160                 }
161         }
162         return s
163 }
164
165 // T is a type passed to Test functions to manage test state and support formatted test logs.
166 // Logs are accumulated during execution and dumped to standard error when done.
167 type T struct {
168         common
169         name          string    // Name of test.
170         startParallel chan bool // Parallel tests will wait on this.
171 }
172
173 // Fail marks the function as having failed but continues execution.
174 func (c *common) Fail() { c.failed = true }
175
176 // Failed returns whether the function has failed.
177 func (c *common) Failed() bool { return c.failed }
178
179 // FailNow marks the function as having failed and stops its execution.
180 // Execution will continue at the next test or benchmark.
181 func (c *common) FailNow() {
182         c.Fail()
183
184         // Calling runtime.Goexit will exit the goroutine, which
185         // will run the deferred functions in this goroutine,
186         // which will eventually run the deferred lines in tRunner,
187         // which will signal to the test loop that this test is done.
188         //
189         // A previous version of this code said:
190         //
191         //      c.duration = ...
192         //      c.signal <- c.self
193         //      runtime.Goexit()
194         //
195         // This previous version duplicated code (those lines are in
196         // tRunner no matter what), but worse the goroutine teardown
197         // implicit in runtime.Goexit was not guaranteed to complete
198         // before the test exited.  If a test deferred an important cleanup
199         // function (like removing temporary files), there was no guarantee
200         // it would run on a test failure.  Because we send on c.signal during
201         // a top-of-stack deferred function now, we know that the send
202         // only happens after any other stacked defers have completed.
203         runtime.Goexit()
204 }
205
206 // log generates the output. It's always at the same stack depth.
207 func (c *common) log(s string) {
208         c.output = append(c.output, decorate(s, true)...)
209 }
210
211 // Log formats its arguments using default formatting, analogous to Println(),
212 // and records the text in the error log.
213 func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
214
215 // Logf formats its arguments according to the format, analogous to Printf(),
216 // and records the text in the error log.
217 func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
218
219 // Error is equivalent to Log() followed by Fail().
220 func (c *common) Error(args ...interface{}) {
221         c.log(fmt.Sprintln(args...))
222         c.Fail()
223 }
224
225 // Errorf is equivalent to Logf() followed by Fail().
226 func (c *common) Errorf(format string, args ...interface{}) {
227         c.log(fmt.Sprintf(format, args...))
228         c.Fail()
229 }
230
231 // Fatal is equivalent to Log() followed by FailNow().
232 func (c *common) Fatal(args ...interface{}) {
233         c.log(fmt.Sprintln(args...))
234         c.FailNow()
235 }
236
237 // Fatalf is equivalent to Logf() followed by FailNow().
238 func (c *common) Fatalf(format string, args ...interface{}) {
239         c.log(fmt.Sprintf(format, args...))
240         c.FailNow()
241 }
242
243 // Parallel signals that this test is to be run in parallel with (and only with) 
244 // other parallel tests in this CPU group.
245 func (t *T) Parallel() {
246         t.signal <- (*T)(nil) // Release main testing loop
247         <-t.startParallel     // Wait for serial tests to finish
248 }
249
250 // An internal type but exported because it is cross-package; part of the implementation
251 // of the "go test" command.
252 type InternalTest struct {
253         Name string
254         F    func(*T)
255 }
256
257 func tRunner(t *T, test *InternalTest) {
258         t.start = time.Now()
259
260         // When this goroutine is done, either because test.F(t)
261         // returned normally or because a test failure triggered 
262         // a call to runtime.Goexit, record the duration and send
263         // a signal saying that the test is done.
264         defer func() {
265                 t.duration = time.Now().Sub(t.start)
266                 // If the test panicked, print any test output before dying.
267                 if err := recover(); err != nil {
268                         t.report()
269                         panic(err)
270                 }
271                 t.signal <- t
272         }()
273
274         test.F(t)
275 }
276
277 // An internal function but exported because it is cross-package; part of the implementation
278 // of the "go test" command.
279 func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
280         flag.Parse()
281         parseCpuList()
282
283         before()
284         startAlarm()
285         haveExamples = len(examples) > 0
286         testOk := RunTests(matchString, tests)
287         exampleOk := RunExamples(matchString, examples)
288         if !testOk || !exampleOk {
289                 fmt.Println("FAIL")
290                 os.Exit(1)
291         }
292         fmt.Println("PASS")
293         stopAlarm()
294         RunBenchmarks(matchString, benchmarks)
295         after()
296 }
297
298 func (t *T) report() {
299         tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
300         format := "--- %s: %s %s\n%s"
301         if t.failed {
302                 fmt.Printf(format, "FAIL", t.name, tstr, t.output)
303         } else if *chatty {
304                 fmt.Printf(format, "PASS", t.name, tstr, t.output)
305         }
306 }
307
308 func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
309         ok = true
310         if len(tests) == 0 && !haveExamples {
311                 fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
312                 return
313         }
314         for _, procs := range cpuList {
315                 runtime.GOMAXPROCS(procs)
316                 // We build a new channel tree for each run of the loop.
317                 // collector merges in one channel all the upstream signals from parallel tests.
318                 // If all tests pump to the same channel, a bug can occur where a test
319                 // kicks off a goroutine that Fails, yet the test still delivers a completion signal,
320                 // which skews the counting.
321                 var collector = make(chan interface{})
322
323                 numParallel := 0
324                 startParallel := make(chan bool)
325
326                 for i := 0; i < len(tests); i++ {
327                         matched, err := matchString(*match, tests[i].Name)
328                         if err != nil {
329                                 fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
330                                 os.Exit(1)
331                         }
332                         if !matched {
333                                 continue
334                         }
335                         testName := tests[i].Name
336                         if procs != 1 {
337                                 testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
338                         }
339                         t := &T{
340                                 common: common{
341                                         signal: make(chan interface{}),
342                                 },
343                                 name:          testName,
344                                 startParallel: startParallel,
345                         }
346                         t.self = t
347                         if *chatty {
348                                 fmt.Printf("=== RUN %s\n", t.name)
349                         }
350                         go tRunner(t, &tests[i])
351                         out := (<-t.signal).(*T)
352                         if out == nil { // Parallel run.
353                                 go func() {
354                                         collector <- <-t.signal
355                                 }()
356                                 numParallel++
357                                 continue
358                         }
359                         t.report()
360                         ok = ok && !out.failed
361                 }
362
363                 running := 0
364                 for numParallel+running > 0 {
365                         if running < *parallel && numParallel > 0 {
366                                 startParallel <- true
367                                 running++
368                                 numParallel--
369                                 continue
370                         }
371                         t := (<-collector).(*T)
372                         t.report()
373                         ok = ok && !t.failed
374                         running--
375                 }
376         }
377         return
378 }
379
380 // before runs before all testing.
381 func before() {
382         if *memProfileRate > 0 {
383                 runtime.MemProfileRate = *memProfileRate
384         }
385         if *cpuProfile != "" {
386                 f, err := os.Create(*cpuProfile)
387                 if err != nil {
388                         fmt.Fprintf(os.Stderr, "testing: %s", err)
389                         return
390                 }
391                 if err := pprof.StartCPUProfile(f); err != nil {
392                         fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s", err)
393                         f.Close()
394                         return
395                 }
396                 // Could save f so after can call f.Close; not worth the effort.
397         }
398
399 }
400
401 // after runs after all testing.
402 func after() {
403         if *cpuProfile != "" {
404                 pprof.StopCPUProfile() // flushes profile to disk
405         }
406         if *memProfile != "" {
407                 f, err := os.Create(*memProfile)
408                 if err != nil {
409                         fmt.Fprintf(os.Stderr, "testing: %s", err)
410                         return
411                 }
412                 if err = pprof.WriteHeapProfile(f); err != nil {
413                         fmt.Fprintf(os.Stderr, "testing: can't write %s: %s", *memProfile, err)
414                 }
415                 f.Close()
416         }
417 }
418
419 var timer *time.Timer
420
421 // startAlarm starts an alarm if requested.
422 func startAlarm() {
423         if *timeout > 0 {
424                 timer = time.AfterFunc(*timeout, alarm)
425         }
426 }
427
428 // stopAlarm turns off the alarm.
429 func stopAlarm() {
430         if *timeout > 0 {
431                 timer.Stop()
432         }
433 }
434
435 // alarm is called if the timeout expires.
436 func alarm() {
437         panic("test timed out")
438 }
439
440 func parseCpuList() {
441         if len(*cpuListStr) == 0 {
442                 cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
443         } else {
444                 for _, val := range strings.Split(*cpuListStr, ",") {
445                         cpu, err := strconv.Atoi(val)
446                         if err != nil || cpu <= 0 {
447                                 fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu", val)
448                                 os.Exit(1)
449                         }
450                         cpuList = append(cpuList, cpu)
451                 }
452         }
453 }