1// Copyright 2017 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_test
6
7import (
8	"internal/testenv"
9	"os"
10	"regexp"
11	"strings"
12	"testing"
13)
14
15func TestTBHelper(t *testing.T) {
16	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
17		testTestHelper(t)
18
19		// Check that calling Helper from inside a top-level test function
20		// has no effect.
21		t.Helper()
22		t.Error("8")
23		return
24	}
25
26	testenv.MustHaveExec(t)
27	t.Parallel()
28
29	exe, err := os.Executable()
30	if err != nil {
31		t.Fatal(err)
32	}
33
34	cmd := testenv.Command(t, exe, "-test.run=^TestTBHelper$")
35	cmd = testenv.CleanCmdEnv(cmd)
36	cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1")
37	out, _ := cmd.CombinedOutput()
38
39	want := `--- FAIL: TestTBHelper \([^)]+\)
40    helperfuncs_test.go:15: 0
41    helperfuncs_test.go:47: 1
42    helperfuncs_test.go:24: 2
43    helperfuncs_test.go:49: 3
44    helperfuncs_test.go:56: 4
45    --- FAIL: TestTBHelper/sub \([^)]+\)
46        helperfuncs_test.go:59: 5
47        helperfuncs_test.go:24: 6
48        helperfuncs_test.go:58: 7
49    --- FAIL: TestTBHelper/sub2 \([^)]+\)
50        helperfuncs_test.go:80: 11
51    helperfuncs_test.go:84: recover 12
52    helperfuncs_test.go:86: GenericFloat64
53    helperfuncs_test.go:87: GenericInt
54    helper_test.go:22: 8
55    helperfuncs_test.go:73: 9
56    helperfuncs_test.go:69: 10
57`
58	if !regexp.MustCompile(want).Match(out) {
59		t.Errorf("got output:\n\n%s\nwant matching:\n\n%s", out, want)
60	}
61}
62
63func TestTBHelperParallel(t *testing.T) {
64	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
65		parallelTestHelper(t)
66		return
67	}
68
69	testenv.MustHaveExec(t)
70	t.Parallel()
71
72	exe, err := os.Executable()
73	if err != nil {
74		t.Fatal(err)
75	}
76
77	cmd := testenv.Command(t, exe, "-test.run=^TestTBHelperParallel$")
78	cmd = testenv.CleanCmdEnv(cmd)
79	cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1")
80	out, _ := cmd.CombinedOutput()
81
82	t.Logf("output:\n%s", out)
83
84	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
85
86	// We expect to see one "--- FAIL" line at the start
87	// of the log, five lines of "parallel" logging,
88	// and a final "FAIL" line at the end of the test.
89	const wantLines = 7
90
91	if len(lines) != wantLines {
92		t.Fatalf("parallelTestHelper gave %d lines of output; want %d", len(lines), wantLines)
93	}
94	want := "helperfuncs_test.go:24: parallel"
95	if got := strings.TrimSpace(lines[1]); got != want {
96		t.Errorf("got second output line %q; want %q", got, want)
97	}
98}
99
100func BenchmarkTBHelper(b *testing.B) {
101	f1 := func() {
102		b.Helper()
103	}
104	f2 := func() {
105		b.Helper()
106	}
107	b.ResetTimer()
108	b.ReportAllocs()
109	for i := 0; i < b.N; i++ {
110		if i&1 == 0 {
111			f1()
112		} else {
113			f2()
114		}
115	}
116}
117