1// Copyright 2016 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
5package testing
6
7import (
8	"bytes"
9	"fmt"
10	"reflect"
11	"regexp"
12	"runtime"
13	"strings"
14	"sync"
15	"sync/atomic"
16	"time"
17)
18
19func init() {
20	// Make benchmark tests run 10x faster.
21	benchTime.d = 100 * time.Millisecond
22}
23
24func TestTestContext(t *T) {
25	const (
26		add1 = 0
27		done = 1
28	)
29	// After each of the calls are applied to the context, the
30	type call struct {
31		typ int // run or done
32		// result from applying the call
33		running int
34		waiting int
35		started bool
36	}
37	testCases := []struct {
38		max int
39		run []call
40	}{{
41		max: 1,
42		run: []call{
43			{typ: add1, running: 1, waiting: 0, started: true},
44			{typ: done, running: 0, waiting: 0, started: false},
45		},
46	}, {
47		max: 1,
48		run: []call{
49			{typ: add1, running: 1, waiting: 0, started: true},
50			{typ: add1, running: 1, waiting: 1, started: false},
51			{typ: done, running: 1, waiting: 0, started: true},
52			{typ: done, running: 0, waiting: 0, started: false},
53			{typ: add1, running: 1, waiting: 0, started: true},
54		},
55	}, {
56		max: 3,
57		run: []call{
58			{typ: add1, running: 1, waiting: 0, started: true},
59			{typ: add1, running: 2, waiting: 0, started: true},
60			{typ: add1, running: 3, waiting: 0, started: true},
61			{typ: add1, running: 3, waiting: 1, started: false},
62			{typ: add1, running: 3, waiting: 2, started: false},
63			{typ: add1, running: 3, waiting: 3, started: false},
64			{typ: done, running: 3, waiting: 2, started: true},
65			{typ: add1, running: 3, waiting: 3, started: false},
66			{typ: done, running: 3, waiting: 2, started: true},
67			{typ: done, running: 3, waiting: 1, started: true},
68			{typ: done, running: 3, waiting: 0, started: true},
69			{typ: done, running: 2, waiting: 0, started: false},
70			{typ: done, running: 1, waiting: 0, started: false},
71			{typ: done, running: 0, waiting: 0, started: false},
72		},
73	}}
74	for i, tc := range testCases {
75		ctx := &testContext{
76			startParallel: make(chan bool),
77			maxParallel:   tc.max,
78		}
79		for j, call := range tc.run {
80			doCall := func(f func()) chan bool {
81				done := make(chan bool)
82				go func() {
83					f()
84					done <- true
85				}()
86				return done
87			}
88			started := false
89			switch call.typ {
90			case add1:
91				signal := doCall(ctx.waitParallel)
92				select {
93				case <-signal:
94					started = true
95				case ctx.startParallel <- true:
96					<-signal
97				}
98			case done:
99				signal := doCall(ctx.release)
100				select {
101				case <-signal:
102				case <-ctx.startParallel:
103					started = true
104					<-signal
105				}
106			}
107			if started != call.started {
108				t.Errorf("%d:%d:started: got %v; want %v", i, j, started, call.started)
109			}
110			if ctx.running != call.running {
111				t.Errorf("%d:%d:running: got %v; want %v", i, j, ctx.running, call.running)
112			}
113			if ctx.numWaiting != call.waiting {
114				t.Errorf("%d:%d:waiting: got %v; want %v", i, j, ctx.numWaiting, call.waiting)
115			}
116		}
117	}
118}
119
120func TestTRun(t *T) {
121	realTest := t
122	testCases := []struct {
123		desc   string
124		ok     bool
125		maxPar int
126		chatty bool
127		json   bool
128		output string
129		f      func(*T)
130	}{{
131		desc:   "failnow skips future sequential and parallel tests at same level",
132		ok:     false,
133		maxPar: 1,
134		output: `
135--- FAIL: failnow skips future sequential and parallel tests at same level (N.NNs)
136    --- FAIL: failnow skips future sequential and parallel tests at same level/#00 (N.NNs)
137    `,
138		f: func(t *T) {
139			ranSeq := false
140			ranPar := false
141			t.Run("", func(t *T) {
142				t.Run("par", func(t *T) {
143					t.Parallel()
144					ranPar = true
145				})
146				t.Run("seq", func(t *T) {
147					ranSeq = true
148				})
149				t.FailNow()
150				t.Run("seq", func(t *T) {
151					realTest.Error("test must be skipped")
152				})
153				t.Run("par", func(t *T) {
154					t.Parallel()
155					realTest.Error("test must be skipped.")
156				})
157			})
158			if !ranPar {
159				realTest.Error("parallel test was not run")
160			}
161			if !ranSeq {
162				realTest.Error("sequential test was not run")
163			}
164		},
165	}, {
166		desc:   "failure in parallel test propagates upwards",
167		ok:     false,
168		maxPar: 1,
169		output: `
170--- FAIL: failure in parallel test propagates upwards (N.NNs)
171    --- FAIL: failure in parallel test propagates upwards/#00 (N.NNs)
172        --- FAIL: failure in parallel test propagates upwards/#00/par (N.NNs)
173        `,
174		f: func(t *T) {
175			t.Run("", func(t *T) {
176				t.Parallel()
177				t.Run("par", func(t *T) {
178					t.Parallel()
179					t.Fail()
180				})
181			})
182		},
183	}, {
184		desc:   "skipping without message, chatty",
185		ok:     true,
186		chatty: true,
187		output: `
188=== RUN   skipping without message, chatty
189--- SKIP: skipping without message, chatty (N.NNs)`,
190		f: func(t *T) { t.SkipNow() },
191	}, {
192		desc:   "chatty with recursion",
193		ok:     true,
194		chatty: true,
195		output: `
196=== RUN   chatty with recursion
197=== RUN   chatty with recursion/#00
198=== RUN   chatty with recursion/#00/#00
199--- PASS: chatty with recursion (N.NNs)
200    --- PASS: chatty with recursion/#00 (N.NNs)
201        --- PASS: chatty with recursion/#00/#00 (N.NNs)`,
202		f: func(t *T) {
203			t.Run("", func(t *T) {
204				t.Run("", func(t *T) {})
205			})
206		},
207	}, {
208		desc:   "chatty with recursion and json",
209		ok:     false,
210		chatty: true,
211		json:   true,
212		output: `
213^V=== RUN   chatty with recursion and json
214^V=== RUN   chatty with recursion and json/#00
215^V=== RUN   chatty with recursion and json/#00/#00
216^V--- PASS: chatty with recursion and json/#00/#00 (N.NNs)
217^V=== NAME  chatty with recursion and json/#00
218^V=== RUN   chatty with recursion and json/#00/#01
219    sub_test.go:NNN: skip
220^V--- SKIP: chatty with recursion and json/#00/#01 (N.NNs)
221^V=== NAME  chatty with recursion and json/#00
222^V=== RUN   chatty with recursion and json/#00/#02
223    sub_test.go:NNN: fail
224^V--- FAIL: chatty with recursion and json/#00/#02 (N.NNs)
225^V=== NAME  chatty with recursion and json/#00
226^V--- FAIL: chatty with recursion and json/#00 (N.NNs)
227^V=== NAME  chatty with recursion and json
228^V--- FAIL: chatty with recursion and json (N.NNs)
229^V=== NAME  `,
230		f: func(t *T) {
231			t.Run("", func(t *T) {
232				t.Run("", func(t *T) {})
233				t.Run("", func(t *T) { t.Skip("skip") })
234				t.Run("", func(t *T) { t.Fatal("fail") })
235			})
236		},
237	}, {
238		desc: "skipping without message, not chatty",
239		ok:   true,
240		f:    func(t *T) { t.SkipNow() },
241	}, {
242		desc: "skipping after error",
243		output: `
244--- FAIL: skipping after error (N.NNs)
245    sub_test.go:NNN: an error
246    sub_test.go:NNN: skipped`,
247		f: func(t *T) {
248			t.Error("an error")
249			t.Skip("skipped")
250		},
251	}, {
252		desc:   "use Run to locally synchronize parallelism",
253		ok:     true,
254		maxPar: 1,
255		f: func(t *T) {
256			var count uint32
257			t.Run("waitGroup", func(t *T) {
258				for i := 0; i < 4; i++ {
259					t.Run("par", func(t *T) {
260						t.Parallel()
261						atomic.AddUint32(&count, 1)
262					})
263				}
264			})
265			if count != 4 {
266				t.Errorf("count was %d; want 4", count)
267			}
268		},
269	}, {
270		desc: "alternate sequential and parallel",
271		// Sequential tests should partake in the counting of running threads.
272		// Otherwise, if one runs parallel subtests in sequential tests that are
273		// itself subtests of parallel tests, the counts can get askew.
274		ok:     true,
275		maxPar: 1,
276		f: func(t *T) {
277			t.Run("a", func(t *T) {
278				t.Parallel()
279				t.Run("b", func(t *T) {
280					// Sequential: ensure running count is decremented.
281					t.Run("c", func(t *T) {
282						t.Parallel()
283					})
284
285				})
286			})
287		},
288	}, {
289		desc: "alternate sequential and parallel 2",
290		// Sequential tests should partake in the counting of running threads.
291		// Otherwise, if one runs parallel subtests in sequential tests that are
292		// itself subtests of parallel tests, the counts can get askew.
293		ok:     true,
294		maxPar: 2,
295		f: func(t *T) {
296			for i := 0; i < 2; i++ {
297				t.Run("a", func(t *T) {
298					t.Parallel()
299					time.Sleep(time.Nanosecond)
300					for i := 0; i < 2; i++ {
301						t.Run("b", func(t *T) {
302							time.Sleep(time.Nanosecond)
303							for i := 0; i < 2; i++ {
304								t.Run("c", func(t *T) {
305									t.Parallel()
306									time.Sleep(time.Nanosecond)
307								})
308							}
309
310						})
311					}
312				})
313			}
314		},
315	}, {
316		desc:   "stress test",
317		ok:     true,
318		maxPar: 4,
319		f: func(t *T) {
320			t.Parallel()
321			for i := 0; i < 12; i++ {
322				t.Run("a", func(t *T) {
323					t.Parallel()
324					time.Sleep(time.Nanosecond)
325					for i := 0; i < 12; i++ {
326						t.Run("b", func(t *T) {
327							time.Sleep(time.Nanosecond)
328							for i := 0; i < 12; i++ {
329								t.Run("c", func(t *T) {
330									t.Parallel()
331									time.Sleep(time.Nanosecond)
332									t.Run("d1", func(t *T) {})
333									t.Run("d2", func(t *T) {})
334									t.Run("d3", func(t *T) {})
335									t.Run("d4", func(t *T) {})
336								})
337							}
338						})
339					}
340				})
341			}
342		},
343	}, {
344		desc:   "skip output",
345		ok:     true,
346		maxPar: 4,
347		f: func(t *T) {
348			t.Skip()
349		},
350	}, {
351		desc: "subtest calls error on parent",
352		ok:   false,
353		output: `
354--- FAIL: subtest calls error on parent (N.NNs)
355    sub_test.go:NNN: first this
356    sub_test.go:NNN: and now this!
357    sub_test.go:NNN: oh, and this too`,
358		maxPar: 1,
359		f: func(t *T) {
360			t.Errorf("first this")
361			outer := t
362			t.Run("", func(t *T) {
363				outer.Errorf("and now this!")
364			})
365			t.Errorf("oh, and this too")
366		},
367	}, {
368		desc: "subtest calls fatal on parent",
369		ok:   false,
370		output: `
371--- FAIL: subtest calls fatal on parent (N.NNs)
372    sub_test.go:NNN: first this
373    sub_test.go:NNN: and now this!
374    --- FAIL: subtest calls fatal on parent/#00 (N.NNs)
375        testing.go:NNN: test executed panic(nil) or runtime.Goexit: subtest may have called FailNow on a parent test`,
376		maxPar: 1,
377		f: func(t *T) {
378			outer := t
379			t.Errorf("first this")
380			t.Run("", func(t *T) {
381				outer.Fatalf("and now this!")
382			})
383			t.Errorf("Should not reach here.")
384		},
385	}, {
386		desc: "subtest calls error on ancestor",
387		ok:   false,
388		output: `
389--- FAIL: subtest calls error on ancestor (N.NNs)
390    sub_test.go:NNN: Report to ancestor
391    --- FAIL: subtest calls error on ancestor/#00 (N.NNs)
392        sub_test.go:NNN: Still do this
393    sub_test.go:NNN: Also do this`,
394		maxPar: 1,
395		f: func(t *T) {
396			outer := t
397			t.Run("", func(t *T) {
398				t.Run("", func(t *T) {
399					outer.Errorf("Report to ancestor")
400				})
401				t.Errorf("Still do this")
402			})
403			t.Errorf("Also do this")
404		},
405	}, {
406		desc: "subtest calls fatal on ancestor",
407		ok:   false,
408		output: `
409--- FAIL: subtest calls fatal on ancestor (N.NNs)
410    sub_test.go:NNN: Nope`,
411		maxPar: 1,
412		f: func(t *T) {
413			outer := t
414			t.Run("", func(t *T) {
415				for i := 0; i < 4; i++ {
416					t.Run("", func(t *T) {
417						outer.Fatalf("Nope")
418					})
419					t.Errorf("Don't do this")
420				}
421				t.Errorf("And neither do this")
422			})
423			t.Errorf("Nor this")
424		},
425	}, {
426		desc:   "panic on goroutine fail after test exit",
427		ok:     false,
428		maxPar: 4,
429		f: func(t *T) {
430			ch := make(chan bool)
431			t.Run("", func(t *T) {
432				go func() {
433					<-ch
434					defer func() {
435						if r := recover(); r == nil {
436							realTest.Errorf("expected panic")
437						}
438						ch <- true
439					}()
440					t.Errorf("failed after success")
441				}()
442			})
443			ch <- true
444			<-ch
445		},
446	}, {
447		desc: "log in finished sub test logs to parent",
448		ok:   false,
449		output: `
450		--- FAIL: log in finished sub test logs to parent (N.NNs)
451    sub_test.go:NNN: message2
452    sub_test.go:NNN: message1
453    sub_test.go:NNN: error`,
454		maxPar: 1,
455		f: func(t *T) {
456			ch := make(chan bool)
457			t.Run("sub", func(t2 *T) {
458				go func() {
459					<-ch
460					t2.Log("message1")
461					ch <- true
462				}()
463			})
464			t.Log("message2")
465			ch <- true
466			<-ch
467			t.Errorf("error")
468		},
469	}, {
470		// A chatty test should always log with fmt.Print, even if the
471		// parent test has completed.
472		desc:   "log in finished sub test with chatty",
473		ok:     false,
474		chatty: true,
475		output: `
476		--- FAIL: log in finished sub test with chatty (N.NNs)`,
477		maxPar: 1,
478		f: func(t *T) {
479			ch := make(chan bool)
480			t.Run("sub", func(t2 *T) {
481				go func() {
482					<-ch
483					t2.Log("message1")
484					ch <- true
485				}()
486			})
487			t.Log("message2")
488			ch <- true
489			<-ch
490			t.Errorf("error")
491		},
492	}, {
493		// If a subtest panics we should run cleanups.
494		desc:   "cleanup when subtest panics",
495		ok:     false,
496		chatty: false,
497		output: `
498--- FAIL: cleanup when subtest panics (N.NNs)
499    --- FAIL: cleanup when subtest panics/sub (N.NNs)
500    sub_test.go:NNN: running cleanup`,
501		f: func(t *T) {
502			t.Cleanup(func() { t.Log("running cleanup") })
503			t.Run("sub", func(t2 *T) {
504				t2.FailNow()
505			})
506		},
507	}}
508	for _, tc := range testCases {
509		t.Run(tc.desc, func(t *T) {
510			ctx := newTestContext(tc.maxPar, allMatcher())
511			buf := &strings.Builder{}
512			root := &T{
513				common: common{
514					signal:  make(chan bool),
515					barrier: make(chan bool),
516					name:    "",
517					w:       buf,
518				},
519				context: ctx,
520			}
521			if tc.chatty {
522				root.chatty = newChattyPrinter(root.w)
523				root.chatty.json = tc.json
524			}
525			ok := root.Run(tc.desc, tc.f)
526			ctx.release()
527
528			if ok != tc.ok {
529				t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, tc.ok)
530			}
531			if ok != !root.Failed() {
532				t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
533			}
534			if ctx.running != 0 || ctx.numWaiting != 0 {
535				t.Errorf("%s:running and waiting non-zero: got %d and %d", tc.desc, ctx.running, ctx.numWaiting)
536			}
537			got := strings.TrimSpace(buf.String())
538			want := strings.TrimSpace(tc.output)
539			re := makeRegexp(want)
540			if ok, err := regexp.MatchString(re, got); !ok || err != nil {
541				t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
542			}
543		})
544	}
545}
546
547func TestBRun(t *T) {
548	work := func(b *B) {
549		for i := 0; i < b.N; i++ {
550			time.Sleep(time.Nanosecond)
551		}
552	}
553	testCases := []struct {
554		desc   string
555		failed bool
556		chatty bool
557		output string
558		f      func(*B)
559	}{{
560		desc: "simulate sequential run of subbenchmarks.",
561		f: func(b *B) {
562			b.Run("", func(b *B) { work(b) })
563			time1 := b.result.NsPerOp()
564			b.Run("", func(b *B) { work(b) })
565			time2 := b.result.NsPerOp()
566			if time1 >= time2 {
567				t.Errorf("no time spent in benchmark t1 >= t2 (%d >= %d)", time1, time2)
568			}
569		},
570	}, {
571		desc: "bytes set by all benchmarks",
572		f: func(b *B) {
573			b.Run("", func(b *B) { b.SetBytes(10); work(b) })
574			b.Run("", func(b *B) { b.SetBytes(10); work(b) })
575			if b.result.Bytes != 20 {
576				t.Errorf("bytes: got: %d; want 20", b.result.Bytes)
577			}
578		},
579	}, {
580		desc: "bytes set by some benchmarks",
581		// In this case the bytes result is meaningless, so it must be 0.
582		f: func(b *B) {
583			b.Run("", func(b *B) { b.SetBytes(10); work(b) })
584			b.Run("", func(b *B) { work(b) })
585			b.Run("", func(b *B) { b.SetBytes(10); work(b) })
586			if b.result.Bytes != 0 {
587				t.Errorf("bytes: got: %d; want 0", b.result.Bytes)
588			}
589		},
590	}, {
591		desc:   "failure carried over to root",
592		failed: true,
593		output: "--- FAIL: root",
594		f:      func(b *B) { b.Fail() },
595	}, {
596		desc:   "skipping without message, chatty",
597		chatty: true,
598		output: "--- SKIP: root",
599		f:      func(b *B) { b.SkipNow() },
600	}, {
601		desc:   "chatty with recursion",
602		chatty: true,
603		f: func(b *B) {
604			b.Run("", func(b *B) {
605				b.Run("", func(b *B) {})
606			})
607		},
608	}, {
609		desc: "skipping without message, not chatty",
610		f:    func(b *B) { b.SkipNow() },
611	}, {
612		desc:   "skipping after error",
613		failed: true,
614		output: `
615--- FAIL: root
616    sub_test.go:NNN: an error
617    sub_test.go:NNN: skipped`,
618		f: func(b *B) {
619			b.Error("an error")
620			b.Skip("skipped")
621		},
622	}, {
623		desc: "memory allocation",
624		f: func(b *B) {
625			const bufSize = 256
626			alloc := func(b *B) {
627				var buf [bufSize]byte
628				for i := 0; i < b.N; i++ {
629					_ = append([]byte(nil), buf[:]...)
630				}
631			}
632			b.Run("", func(b *B) {
633				alloc(b)
634				b.ReportAllocs()
635			})
636			b.Run("", func(b *B) {
637				alloc(b)
638				b.ReportAllocs()
639			})
640			// runtime.MemStats sometimes reports more allocations than the
641			// benchmark is responsible for. Luckily the point of this test is
642			// to ensure that the results are not underreported, so we can
643			// simply verify the lower bound.
644			if got := b.result.MemAllocs; got < 2 {
645				t.Errorf("MemAllocs was %v; want 2", got)
646			}
647			if got := b.result.MemBytes; got < 2*bufSize {
648				t.Errorf("MemBytes was %v; want %v", got, 2*bufSize)
649			}
650		},
651	}, {
652		desc: "cleanup is called",
653		f: func(b *B) {
654			var calls, cleanups, innerCalls, innerCleanups int
655			b.Run("", func(b *B) {
656				calls++
657				b.Cleanup(func() {
658					cleanups++
659				})
660				b.Run("", func(b *B) {
661					b.Cleanup(func() {
662						innerCleanups++
663					})
664					innerCalls++
665				})
666				work(b)
667			})
668			if calls == 0 || calls != cleanups {
669				t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
670			}
671			if innerCalls == 0 || innerCalls != innerCleanups {
672				t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
673			}
674		},
675	}, {
676		desc:   "cleanup is called on failure",
677		failed: true,
678		f: func(b *B) {
679			var calls, cleanups int
680			b.Run("", func(b *B) {
681				calls++
682				b.Cleanup(func() {
683					cleanups++
684				})
685				b.Fatalf("failure")
686			})
687			if calls == 0 || calls != cleanups {
688				t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
689			}
690		},
691	}}
692	hideStdoutForTesting = true
693	defer func() {
694		hideStdoutForTesting = false
695	}()
696	for _, tc := range testCases {
697		t.Run(tc.desc, func(t *T) {
698			var ok bool
699			buf := &strings.Builder{}
700			// This is almost like the Benchmark function, except that we override
701			// the benchtime and catch the failure result of the subbenchmark.
702			root := &B{
703				common: common{
704					signal: make(chan bool),
705					name:   "root",
706					w:      buf,
707				},
708				benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
709				benchTime: durationOrCountFlag{d: 1 * time.Microsecond},
710			}
711			if tc.chatty {
712				root.chatty = newChattyPrinter(root.w)
713			}
714			root.runN(1)
715			if ok != !tc.failed {
716				t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, !tc.failed)
717			}
718			if !ok != root.Failed() {
719				t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
720			}
721			// All tests are run as subtests
722			if root.result.N != 1 {
723				t.Errorf("%s: N for parent benchmark was %d; want 1", tc.desc, root.result.N)
724			}
725			got := strings.TrimSpace(buf.String())
726			want := strings.TrimSpace(tc.output)
727			re := makeRegexp(want)
728			if ok, err := regexp.MatchString(re, got); !ok || err != nil {
729				t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
730			}
731		})
732	}
733}
734
735func makeRegexp(s string) string {
736	s = regexp.QuoteMeta(s)
737	s = strings.ReplaceAll(s, "^V", "\x16")
738	s = strings.ReplaceAll(s, ":NNN:", `:\d\d\d\d?:`)
739	s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`)
740	return s
741}
742
743func TestBenchmarkOutput(t *T) {
744	// Ensure Benchmark initialized common.w by invoking it with an error and
745	// normal case.
746	Benchmark(func(b *B) { b.Error("do not print this output") })
747	Benchmark(func(b *B) {})
748}
749
750func TestBenchmarkStartsFrom1(t *T) {
751	var first = true
752	Benchmark(func(b *B) {
753		if first && b.N != 1 {
754			panic(fmt.Sprintf("Benchmark() first N=%v; want 1", b.N))
755		}
756		first = false
757	})
758}
759
760func TestBenchmarkReadMemStatsBeforeFirstRun(t *T) {
761	var first = true
762	Benchmark(func(b *B) {
763		if first && (b.startAllocs == 0 || b.startBytes == 0) {
764			panic("ReadMemStats not called before first run")
765		}
766		first = false
767	})
768}
769
770type funcWriter struct {
771	write func([]byte) (int, error)
772}
773
774func (fw *funcWriter) Write(b []byte) (int, error) {
775	return fw.write(b)
776}
777
778func TestRacyOutput(t *T) {
779	var runs int32  // The number of running Writes
780	var races int32 // Incremented for each race detected
781	raceDetector := func(b []byte) (int, error) {
782		// Check if some other goroutine is concurrently calling Write.
783		if atomic.LoadInt32(&runs) > 0 {
784			atomic.AddInt32(&races, 1) // Race detected!
785		}
786		atomic.AddInt32(&runs, 1)
787		defer atomic.AddInt32(&runs, -1)
788		runtime.Gosched() // Increase probability of a race
789		return len(b), nil
790	}
791
792	root := &T{
793		common:  common{w: &funcWriter{raceDetector}},
794		context: newTestContext(1, allMatcher()),
795	}
796	root.chatty = newChattyPrinter(root.w)
797	root.Run("", func(t *T) {
798		var wg sync.WaitGroup
799		for i := 0; i < 100; i++ {
800			wg.Add(1)
801			go func(i int) {
802				defer wg.Done()
803				t.Run(fmt.Sprint(i), func(t *T) {
804					t.Logf("testing run %d", i)
805				})
806			}(i)
807		}
808		wg.Wait()
809	})
810
811	if races > 0 {
812		t.Errorf("detected %d racy Writes", races)
813	}
814}
815
816// The late log message did not include the test name.  Issue 29388.
817func TestLogAfterComplete(t *T) {
818	ctx := newTestContext(1, allMatcher())
819	var buf bytes.Buffer
820	t1 := &T{
821		common: common{
822			// Use a buffered channel so that tRunner can write
823			// to it although nothing is reading from it.
824			signal: make(chan bool, 1),
825			w:      &buf,
826		},
827		context: ctx,
828	}
829
830	c1 := make(chan bool)
831	c2 := make(chan string)
832	tRunner(t1, func(t *T) {
833		t.Run("TestLateLog", func(t *T) {
834			go func() {
835				defer close(c2)
836				defer func() {
837					p := recover()
838					if p == nil {
839						c2 <- "subtest did not panic"
840						return
841					}
842					s, ok := p.(string)
843					if !ok {
844						c2 <- fmt.Sprintf("subtest panic with unexpected value %v", p)
845						return
846					}
847					const want = "Log in goroutine after TestLateLog has completed: log after test"
848					if !strings.Contains(s, want) {
849						c2 <- fmt.Sprintf("subtest panic %q does not contain %q", s, want)
850					}
851				}()
852
853				<-c1
854				t.Log("log after test")
855			}()
856		})
857	})
858	close(c1)
859
860	if s := <-c2; s != "" {
861		t.Error(s)
862	}
863}
864
865func TestBenchmark(t *T) {
866	if Short() {
867		t.Skip("skipping in short mode")
868	}
869	res := Benchmark(func(b *B) {
870		for i := 0; i < 5; i++ {
871			b.Run("", func(b *B) {
872				for i := 0; i < b.N; i++ {
873					time.Sleep(time.Millisecond)
874				}
875			})
876		}
877	})
878	if res.NsPerOp() < 4000000 {
879		t.Errorf("want >5ms; got %v", time.Duration(res.NsPerOp()))
880	}
881}
882
883func TestCleanup(t *T) {
884	var cleanups []int
885	t.Run("test", func(t *T) {
886		t.Cleanup(func() { cleanups = append(cleanups, 1) })
887		t.Cleanup(func() { cleanups = append(cleanups, 2) })
888	})
889	if got, want := cleanups, []int{2, 1}; !reflect.DeepEqual(got, want) {
890		t.Errorf("unexpected cleanup record; got %v want %v", got, want)
891	}
892}
893
894func TestConcurrentCleanup(t *T) {
895	cleanups := 0
896	t.Run("test", func(t *T) {
897		var wg sync.WaitGroup
898		wg.Add(2)
899		for i := 0; i < 2; i++ {
900			i := i
901			go func() {
902				t.Cleanup(func() {
903					// Although the calls to Cleanup are concurrent, the functions passed
904					// to Cleanup should be called sequentially, in some nondeterministic
905					// order based on when the Cleanup calls happened to be scheduled.
906					// So these assignments to the cleanups variable should not race.
907					cleanups |= 1 << i
908				})
909				wg.Done()
910			}()
911		}
912		wg.Wait()
913	})
914	if cleanups != 1|2 {
915		t.Errorf("unexpected cleanup; got %d want 3", cleanups)
916	}
917}
918
919func TestCleanupCalledEvenAfterGoexit(t *T) {
920	cleanups := 0
921	t.Run("test", func(t *T) {
922		t.Cleanup(func() {
923			cleanups++
924		})
925		t.Cleanup(func() {
926			runtime.Goexit()
927		})
928	})
929	if cleanups != 1 {
930		t.Errorf("unexpected cleanup count; got %d want 1", cleanups)
931	}
932}
933
934func TestRunCleanup(t *T) {
935	outerCleanup := 0
936	innerCleanup := 0
937	t.Run("test", func(t *T) {
938		t.Cleanup(func() { outerCleanup++ })
939		t.Run("x", func(t *T) {
940			t.Cleanup(func() { innerCleanup++ })
941		})
942	})
943	if innerCleanup != 1 {
944		t.Errorf("unexpected inner cleanup count; got %d want 1", innerCleanup)
945	}
946	if outerCleanup != 1 {
947		t.Errorf("unexpected outer cleanup count; got %d want 0", outerCleanup)
948	}
949}
950
951func TestCleanupParallelSubtests(t *T) {
952	ranCleanup := 0
953	t.Run("test", func(t *T) {
954		t.Cleanup(func() { ranCleanup++ })
955		t.Run("x", func(t *T) {
956			t.Parallel()
957			if ranCleanup > 0 {
958				t.Error("outer cleanup ran before parallel subtest")
959			}
960		})
961	})
962	if ranCleanup != 1 {
963		t.Errorf("unexpected cleanup count; got %d want 1", ranCleanup)
964	}
965}
966
967func TestNestedCleanup(t *T) {
968	ranCleanup := 0
969	t.Run("test", func(t *T) {
970		t.Cleanup(func() {
971			if ranCleanup != 2 {
972				t.Errorf("unexpected cleanup count in first cleanup: got %d want 2", ranCleanup)
973			}
974			ranCleanup++
975		})
976		t.Cleanup(func() {
977			if ranCleanup != 0 {
978				t.Errorf("unexpected cleanup count in second cleanup: got %d want 0", ranCleanup)
979			}
980			ranCleanup++
981			t.Cleanup(func() {
982				if ranCleanup != 1 {
983					t.Errorf("unexpected cleanup count in nested cleanup: got %d want 1", ranCleanup)
984				}
985				ranCleanup++
986			})
987		})
988	})
989	if ranCleanup != 3 {
990		t.Errorf("unexpected cleanup count: got %d want 3", ranCleanup)
991	}
992}
993