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

/src/pkg/go/doc/testdata/testing.go

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