PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/libgo/go/testing/testing.go

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