PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pkg/testing/testing.go

https://code.google.com/p/go/
Go | 622 lines | 501 code | 12 blank | 109 comment | 6 complexity | 749cb7b910b8472f62de010364292fd0 MD5 | raw file
Possible License(s): BSD-3-Clause
  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. // Package testing provides support for automated testing of Go packages.
  5. // It is intended to be used in concert with the ``go test'' command, which automates
  6. // execution of any function of the form
  7. // func TestXxx(*testing.T)
  8. // where Xxx can be any alphanumeric string (but the first letter must not be in
  9. // [a-z]) and serves to identify the test routine.
  10. // These TestXxx routines should be declared within the package they are testing.
  11. //
  12. // Tests and benchmarks may be skipped if not applicable like this:
  13. // func TestTimeConsuming(t *testing.T) {
  14. // if testing.Short() {
  15. // t.Skip("skipping test in short mode.")
  16. // }
  17. // ...
  18. // }
  19. //
  20. // Benchmarks
  21. //
  22. // Functions of the form
  23. // func BenchmarkXxx(*testing.B)
  24. // are considered benchmarks, and are executed by the "go test" command when
  25. // its -bench flag is provided. Benchmarks are run sequentially.
  26. //
  27. // For a description of the testing flags, see
  28. // http://golang.org/cmd/go/#hdr-Description_of_testing_flags.
  29. //
  30. // A sample benchmark function looks like this:
  31. // func BenchmarkHello(b *testing.B) {
  32. // for i := 0; i < b.N; i++ {
  33. // fmt.Sprintf("hello")
  34. // }
  35. // }
  36. //
  37. // The benchmark function must run the target code b.N times.
  38. // The benchmark package will vary b.N until the benchmark function lasts
  39. // long enough to be timed reliably. The output
  40. // BenchmarkHello 10000000 282 ns/op
  41. // means that the loop ran 10000000 times at a speed of 282 ns per loop.
  42. //
  43. // If a benchmark needs some expensive setup before running, the timer
  44. // may be reset:
  45. // func BenchmarkBigLen(b *testing.B) {
  46. // big := NewBig()
  47. // b.ResetTimer()
  48. // for i := 0; i < b.N; i++ {
  49. // big.Len()
  50. // }
  51. // }
  52. //
  53. // Examples
  54. //
  55. // The package also runs and verifies example code. Example functions may
  56. // include a concluding line comment that begins with "Output:" and is compared with
  57. // the standard output of the function when the tests are run. (The comparison
  58. // ignores leading and trailing space.) These are examples of an example:
  59. //
  60. // func ExampleHello() {
  61. // fmt.Println("hello")
  62. // // Output: hello
  63. // }
  64. //
  65. // func ExampleSalutations() {
  66. // fmt.Println("hello, and")
  67. // fmt.Println("goodbye")
  68. // // Output:
  69. // // hello, and
  70. // // goodbye
  71. // }
  72. //
  73. // Example functions without output comments are compiled but not executed.
  74. //
  75. // The naming convention to declare examples for a function F, a type T and
  76. // method M on type T are:
  77. //
  78. // func ExampleF() { ... }
  79. // func ExampleT() { ... }
  80. // func ExampleT_M() { ... }
  81. //
  82. // Multiple example functions for a type/function/method may be provided by
  83. // appending a distinct suffix to the name. The suffix must start with a
  84. // lower-case letter.
  85. //
  86. // func ExampleF_suffix() { ... }
  87. // func ExampleT_suffix() { ... }
  88. // func ExampleT_M_suffix() { ... }
  89. //
  90. // The entire test file is presented as the example when it contains a single
  91. // example function, at least one other function, type, variable, or constant
  92. // declaration, and no test or benchmark functions.
  93. package testing
  94. import (
  95. "bytes"
  96. "flag"
  97. "fmt"
  98. "os"
  99. "runtime"
  100. "runtime/pprof"
  101. "strconv"
  102. "strings"
  103. "sync"
  104. "time"
  105. )
  106. var (
  107. // The short flag requests that tests run more quickly, but its functionality
  108. // is provided by test writers themselves. The testing package is just its
  109. // home. The all.bash installation script sets it to make installation more
  110. // efficient, but by default the flag is off so a plain "go test" will do a
  111. // full test of the package.
  112. short = flag.Bool("test.short", false, "run smaller test suite to save time")
  113. // The directory in which to create profile files and the like. When run from
  114. // "go test", the binary always runs in the source directory for the package;
  115. // this flag lets "go test" tell the binary to write the files in the directory where
  116. // the "go test" command is run.
  117. outputDir = flag.String("test.outputdir", "", "directory in which to write profiles")
  118. // Report as tests are run; default is silent for success.
  119. chatty = flag.Bool("test.v", false, "verbose: print additional output")
  120. coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to the named file after execution")
  121. match = flag.String("test.run", "", "regular expression to select tests and examples to run")
  122. memProfile = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
  123. memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
  124. cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
  125. blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to the named file after execution")
  126. blockProfileRate = flag.Int("test.blockprofilerate", 1, "if >= 0, calls runtime.SetBlockProfileRate()")
  127. timeout = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
  128. cpuListStr = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
  129. parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
  130. haveExamples bool // are there examples?
  131. cpuList []int
  132. )
  133. // common holds the elements common between T and B and
  134. // captures common methods such as Errorf.
  135. type common struct {
  136. mu sync.RWMutex // guards output and failed
  137. output []byte // Output generated by test or benchmark.
  138. failed bool // Test or benchmark has failed.
  139. skipped bool // Test of benchmark has been skipped.
  140. start time.Time // Time test or benchmark started
  141. duration time.Duration
  142. self interface{} // To be sent on signal channel when done.
  143. signal chan interface{} // Output for serial tests.
  144. }
  145. // Short reports whether the -test.short flag is set.
  146. func Short() bool {
  147. return *short
  148. }
  149. // Verbose reports whether the -test.v flag is set.
  150. func Verbose() bool {
  151. return *chatty
  152. }
  153. // decorate prefixes the string with the file and line of the call site
  154. // and inserts the final newline if needed and indentation tabs for formatting.
  155. func decorate(s string) string {
  156. _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
  157. if ok {
  158. // Truncate file name at last file name separator.
  159. if index := strings.LastIndex(file, "/"); index >= 0 {
  160. file = file[index+1:]
  161. } else if index = strings.LastIndex(file, "\\"); index >= 0 {
  162. file = file[index+1:]
  163. }
  164. } else {
  165. file = "???"
  166. line = 1
  167. }
  168. buf := new(bytes.Buffer)
  169. // Every line is indented at least one tab.
  170. buf.WriteByte('\t')
  171. fmt.Fprintf(buf, "%s:%d: ", file, line)
  172. lines := strings.Split(s, "\n")
  173. if l := len(lines); l > 1 && lines[l-1] == "" {
  174. lines = lines[:l-1]
  175. }
  176. for i, line := range lines {
  177. if i > 0 {
  178. // Second and subsequent lines are indented an extra tab.
  179. buf.WriteString("\n\t\t")
  180. }
  181. buf.WriteString(line)
  182. }
  183. buf.WriteByte('\n')
  184. return buf.String()
  185. }
  186. // TB is the interface common to T and B.
  187. type TB interface {
  188. Error(args ...interface{})
  189. Errorf(format string, args ...interface{})
  190. Fail()
  191. FailNow()
  192. Failed() bool
  193. Fatal(args ...interface{})
  194. Fatalf(format string, args ...interface{})
  195. Log(args ...interface{})
  196. Logf(format string, args ...interface{})
  197. Skip(args ...interface{})
  198. SkipNow()
  199. Skipf(format string, args ...interface{})
  200. Skipped() bool
  201. // A private method to prevent users implementing the
  202. // interface and so future additions to it will not
  203. // violate Go 1 compatibility.
  204. private()
  205. }
  206. var _ TB = (*T)(nil)
  207. var _ TB = (*B)(nil)
  208. // T is a type passed to Test functions to manage test state and support formatted test logs.
  209. // Logs are accumulated during execution and dumped to standard error when done.
  210. type T struct {
  211. common
  212. name string // Name of test.
  213. startParallel chan bool // Parallel tests will wait on this.
  214. }
  215. func (c *common) private() {}
  216. // Fail marks the function as having failed but continues execution.
  217. func (c *common) Fail() {
  218. c.mu.Lock()
  219. defer c.mu.Unlock()
  220. c.failed = true
  221. }
  222. // Failed reports whether the function has failed.
  223. func (c *common) Failed() bool {
  224. c.mu.RLock()
  225. defer c.mu.RUnlock()
  226. return c.failed
  227. }
  228. // FailNow marks the function as having failed and stops its execution.
  229. // Execution will continue at the next test or benchmark.
  230. // FailNow must be called from the goroutine running the
  231. // test or benchmark function, not from other goroutines
  232. // created during the test. Calling FailNow does not stop
  233. // those other goroutines.
  234. func (c *common) FailNow() {
  235. c.Fail()
  236. // Calling runtime.Goexit will exit the goroutine, which
  237. // will run the deferred functions in this goroutine,
  238. // which will eventually run the deferred lines in tRunner,
  239. // which will signal to the test loop that this test is done.
  240. //
  241. // A previous version of this code said:
  242. //
  243. // c.duration = ...
  244. // c.signal <- c.self
  245. // runtime.Goexit()
  246. //
  247. // This previous version duplicated code (those lines are in
  248. // tRunner no matter what), but worse the goroutine teardown
  249. // implicit in runtime.Goexit was not guaranteed to complete
  250. // before the test exited. If a test deferred an important cleanup
  251. // function (like removing temporary files), there was no guarantee
  252. // it would run on a test failure. Because we send on c.signal during
  253. // a top-of-stack deferred function now, we know that the send
  254. // only happens after any other stacked defers have completed.
  255. runtime.Goexit()
  256. }
  257. // log generates the output. It's always at the same stack depth.
  258. func (c *common) log(s string) {
  259. c.mu.Lock()
  260. defer c.mu.Unlock()
  261. c.output = append(c.output, decorate(s)...)
  262. }
  263. // Log formats its arguments using default formatting, analogous to Println,
  264. // and records the text in the error log. The text will be printed only if
  265. // the test fails or the -test.v flag is set.
  266. func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
  267. // Logf formats its arguments according to the format, analogous to Printf,
  268. // and records the text in the error log. The text will be printed only if
  269. // the test fails or the -test.v flag is set.
  270. func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
  271. // Error is equivalent to Log followed by Fail.
  272. func (c *common) Error(args ...interface{}) {
  273. c.log(fmt.Sprintln(args...))
  274. c.Fail()
  275. }
  276. // Errorf is equivalent to Logf followed by Fail.
  277. func (c *common) Errorf(format string, args ...interface{}) {
  278. c.log(fmt.Sprintf(format, args...))
  279. c.Fail()
  280. }
  281. // Fatal is equivalent to Log followed by FailNow.
  282. func (c *common) Fatal(args ...interface{}) {
  283. c.log(fmt.Sprintln(args...))
  284. c.FailNow()
  285. }
  286. // Fatalf is equivalent to Logf followed by FailNow.
  287. func (c *common) Fatalf(format string, args ...interface{}) {
  288. c.log(fmt.Sprintf(format, args...))
  289. c.FailNow()
  290. }
  291. // Skip is equivalent to Log followed by SkipNow.
  292. func (c *common) Skip(args ...interface{}) {
  293. c.log(fmt.Sprintln(args...))
  294. c.SkipNow()
  295. }
  296. // Skipf is equivalent to Logf followed by SkipNow.
  297. func (c *common) Skipf(format string, args ...interface{}) {
  298. c.log(fmt.Sprintf(format, args...))
  299. c.SkipNow()
  300. }
  301. // SkipNow marks the test as having been skipped and stops its execution.
  302. // Execution will continue at the next test or benchmark. See also FailNow.
  303. // SkipNow must be called from the goroutine running the test, not from
  304. // other goroutines created during the test. Calling SkipNow does not stop
  305. // those other goroutines.
  306. func (c *common) SkipNow() {
  307. c.skip()
  308. runtime.Goexit()
  309. }
  310. func (c *common) skip() {
  311. c.mu.Lock()
  312. defer c.mu.Unlock()
  313. c.skipped = true
  314. }
  315. // Skipped reports whether the test was skipped.
  316. func (c *common) Skipped() bool {
  317. c.mu.RLock()
  318. defer c.mu.RUnlock()
  319. return c.skipped
  320. }
  321. // Parallel signals that this test is to be run in parallel with (and only with)
  322. // other parallel tests.
  323. func (t *T) Parallel() {
  324. t.signal <- (*T)(nil) // Release main testing loop
  325. <-t.startParallel // Wait for serial tests to finish
  326. // Assuming Parallel is the first thing a test does, which is reasonable,
  327. // reinitialize the test's start time because it's actually starting now.
  328. t.start = time.Now()
  329. }
  330. // An internal type but exported because it is cross-package; part of the implementation
  331. // of the "go test" command.
  332. type InternalTest struct {
  333. Name string
  334. F func(*T)
  335. }
  336. func tRunner(t *T, test *InternalTest) {
  337. // When this goroutine is done, either because test.F(t)
  338. // returned normally or because a test failure triggered
  339. // a call to runtime.Goexit, record the duration and send
  340. // a signal saying that the test is done.
  341. defer func() {
  342. t.duration = time.Now().Sub(t.start)
  343. // If the test panicked, print any test output before dying.
  344. if err := recover(); err != nil {
  345. t.Fail()
  346. t.report()
  347. panic(err)
  348. }
  349. t.signal <- t
  350. }()
  351. t.start = time.Now()
  352. test.F(t)
  353. }
  354. // An internal function but exported because it is cross-package; part of the implementation
  355. // of the "go test" command.
  356. func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
  357. flag.Parse()
  358. parseCpuList()
  359. before()
  360. startAlarm()
  361. haveExamples = len(examples) > 0
  362. testOk := RunTests(matchString, tests)
  363. exampleOk := RunExamples(matchString, examples)
  364. stopAlarm()
  365. if !testOk || !exampleOk {
  366. fmt.Println("FAIL")
  367. os.Exit(1)
  368. }
  369. fmt.Println("PASS")
  370. RunBenchmarks(matchString, benchmarks)
  371. after()
  372. }
  373. func (t *T) report() {
  374. tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
  375. format := "--- %s: %s %s\n%s"
  376. if t.Failed() {
  377. fmt.Printf(format, "FAIL", t.name, tstr, t.output)
  378. } else if *chatty {
  379. if t.Skipped() {
  380. fmt.Printf(format, "SKIP", t.name, tstr, t.output)
  381. } else {
  382. fmt.Printf(format, "PASS", t.name, tstr, t.output)
  383. }
  384. }
  385. }
  386. func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
  387. ok = true
  388. if len(tests) == 0 && !haveExamples {
  389. fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
  390. return
  391. }
  392. for _, procs := range cpuList {
  393. runtime.GOMAXPROCS(procs)
  394. // We build a new channel tree for each run of the loop.
  395. // collector merges in one channel all the upstream signals from parallel tests.
  396. // If all tests pump to the same channel, a bug can occur where a test
  397. // kicks off a goroutine that Fails, yet the test still delivers a completion signal,
  398. // which skews the counting.
  399. var collector = make(chan interface{})
  400. numParallel := 0
  401. startParallel := make(chan bool)
  402. for i := 0; i < len(tests); i++ {
  403. matched, err := matchString(*match, tests[i].Name)
  404. if err != nil {
  405. fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
  406. os.Exit(1)
  407. }
  408. if !matched {
  409. continue
  410. }
  411. testName := tests[i].Name
  412. if procs != 1 {
  413. testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
  414. }
  415. t := &T{
  416. common: common{
  417. signal: make(chan interface{}),
  418. },
  419. name: testName,
  420. startParallel: startParallel,
  421. }
  422. t.self = t
  423. if *chatty {
  424. fmt.Printf("=== RUN %s\n", t.name)
  425. }
  426. go tRunner(t, &tests[i])
  427. out := (<-t.signal).(*T)
  428. if out == nil { // Parallel run.
  429. go func() {
  430. collector <- <-t.signal
  431. }()
  432. numParallel++
  433. continue
  434. }
  435. t.report()
  436. ok = ok && !out.Failed()
  437. }
  438. running := 0
  439. for numParallel+running > 0 {
  440. if running < *parallel && numParallel > 0 {
  441. startParallel <- true
  442. running++
  443. numParallel--
  444. continue
  445. }
  446. t := (<-collector).(*T)
  447. t.report()
  448. ok = ok && !t.Failed()
  449. running--
  450. }
  451. }
  452. return
  453. }
  454. // before runs before all testing.
  455. func before() {
  456. if *memProfileRate > 0 {
  457. runtime.MemProfileRate = *memProfileRate
  458. }
  459. if *cpuProfile != "" {
  460. f, err := os.Create(toOutputDir(*cpuProfile))
  461. if err != nil {
  462. fmt.Fprintf(os.Stderr, "testing: %s", err)
  463. return
  464. }
  465. if err := pprof.StartCPUProfile(f); err != nil {
  466. fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s", err)
  467. f.Close()
  468. return
  469. }
  470. // Could save f so after can call f.Close; not worth the effort.
  471. }
  472. if *blockProfile != "" && *blockProfileRate >= 0 {
  473. runtime.SetBlockProfileRate(*blockProfileRate)
  474. }
  475. if *coverProfile != "" && cover.Mode == "" {
  476. fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
  477. os.Exit(2)
  478. }
  479. }
  480. // after runs after all testing.
  481. func after() {
  482. if *cpuProfile != "" {
  483. pprof.StopCPUProfile() // flushes profile to disk
  484. }
  485. if *memProfile != "" {
  486. f, err := os.Create(toOutputDir(*memProfile))
  487. if err != nil {
  488. fmt.Fprintf(os.Stderr, "testing: %s\n", err)
  489. os.Exit(2)
  490. }
  491. if err = pprof.WriteHeapProfile(f); err != nil {
  492. fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err)
  493. os.Exit(2)
  494. }
  495. f.Close()
  496. }
  497. if *blockProfile != "" && *blockProfileRate >= 0 {
  498. f, err := os.Create(toOutputDir(*blockProfile))
  499. if err != nil {
  500. fmt.Fprintf(os.Stderr, "testing: %s\n", err)
  501. os.Exit(2)
  502. }
  503. if err = pprof.Lookup("block").WriteTo(f, 0); err != nil {
  504. fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
  505. os.Exit(2)
  506. }
  507. f.Close()
  508. }
  509. if cover.Mode != "" {
  510. coverReport()
  511. }
  512. }
  513. // toOutputDir returns the file name relocated, if required, to outputDir.
  514. // Simple implementation to avoid pulling in path/filepath.
  515. func toOutputDir(path string) string {
  516. if *outputDir == "" || path == "" {
  517. return path
  518. }
  519. if runtime.GOOS == "windows" {
  520. // On Windows, it's clumsy, but we can be almost always correct
  521. // by just looking for a drive letter and a colon.
  522. // Absolute paths always have a drive letter (ignoring UNC).
  523. // Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
  524. // what to do, but even then path/filepath doesn't help.
  525. // TODO: Worth doing better? Probably not, because we're here only
  526. // under the management of go test.
  527. if len(path) >= 2 {
  528. letter, colon := path[0], path[1]
  529. if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
  530. // If path starts with a drive letter we're stuck with it regardless.
  531. return path
  532. }
  533. }
  534. }
  535. if os.IsPathSeparator(path[0]) {
  536. return path
  537. }
  538. return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
  539. }
  540. var timer *time.Timer
  541. // startAlarm starts an alarm if requested.
  542. func startAlarm() {
  543. if *timeout > 0 {
  544. timer = time.AfterFunc(*timeout, func() {
  545. panic(fmt.Sprintf("test timed out after %v", *timeout))
  546. })
  547. }
  548. }
  549. // stopAlarm turns off the alarm.
  550. func stopAlarm() {
  551. if *timeout > 0 {
  552. timer.Stop()
  553. }
  554. }
  555. func parseCpuList() {
  556. for _, val := range strings.Split(*cpuListStr, ",") {
  557. val = strings.TrimSpace(val)
  558. if val == "" {
  559. continue
  560. }
  561. cpu, err := strconv.Atoi(val)
  562. if err != nil || cpu <= 0 {
  563. fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
  564. os.Exit(1)
  565. }
  566. cpuList = append(cpuList, cpu)
  567. }
  568. if cpuList == nil {
  569. cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
  570. }
  571. }