1
2
3
4
5 package synctest_test
6
7 import (
8 "fmt"
9 "internal/testenv"
10 "os"
11 "regexp"
12 "testing"
13 "testing/synctest"
14 )
15
16
17
18
19 func TestSuccess(t *testing.T) {
20 synctest.Test(t, func(t *testing.T) {
21 })
22 }
23
24 func TestFatal(t *testing.T) {
25 runTest(t, nil, func() {
26 synctest.Test(t, func(t *testing.T) {
27 t.Fatal("fatal")
28 })
29 }, `^--- FAIL: TestFatal.*
30 synctest_test.go:.* fatal
31 FAIL
32 $`)
33 }
34
35 func TestError(t *testing.T) {
36 runTest(t, nil, func() {
37 synctest.Test(t, func(t *testing.T) {
38 t.Error("error")
39 })
40 }, `^--- FAIL: TestError.*
41 synctest_test.go:.* error
42 FAIL
43 $`)
44 }
45
46 func TestVerboseError(t *testing.T) {
47 runTest(t, []string{"-test.v"}, func() {
48 synctest.Test(t, func(t *testing.T) {
49 t.Error("error")
50 })
51 }, `^=== RUN TestVerboseError
52 synctest_test.go:.* error
53 --- FAIL: TestVerboseError.*
54 FAIL
55 $`)
56 }
57
58 func TestSkip(t *testing.T) {
59 runTest(t, nil, func() {
60 synctest.Test(t, func(t *testing.T) {
61 t.Skip("skip")
62 })
63 }, `^PASS
64 $`)
65 }
66
67 func TestVerboseSkip(t *testing.T) {
68 runTest(t, []string{"-test.v"}, func() {
69 synctest.Test(t, func(t *testing.T) {
70 t.Skip("skip")
71 })
72 }, `^=== RUN TestVerboseSkip
73 synctest_test.go:.* skip
74 --- PASS: TestVerboseSkip.*
75 PASS
76 $`)
77 }
78
79 func TestCleanup(t *testing.T) {
80 done := false
81 synctest.Test(t, func(t *testing.T) {
82 ch := make(chan struct{})
83 t.Cleanup(func() {
84
85
86 close(ch)
87 })
88
89
90 go func() {
91 <-ch
92 done = true
93 }()
94 })
95 if !done {
96 t.Fatalf("background goroutine did not return")
97 }
98 }
99
100 func TestContext(t *testing.T) {
101 state := "not started"
102 synctest.Test(t, func(t *testing.T) {
103 go func() {
104 state = "waiting on context"
105 <-t.Context().Done()
106 state = "done"
107 }()
108
109 synctest.Wait()
110 if got, want := state, "waiting on context"; got != want {
111 t.Fatalf("state = %q, want %q", got, want)
112 }
113 })
114
115
116 if got, want := state, "done"; got != want {
117 t.Fatalf("state = %q, want %q", got, want)
118 }
119 }
120
121 func TestDeadline(t *testing.T) {
122 synctest.Test(t, func(t *testing.T) {
123 defer wantPanic(t, "testing: t.Deadline called inside synctest bubble")
124 _, _ = t.Deadline()
125 })
126 }
127
128 func TestParallel(t *testing.T) {
129 synctest.Test(t, func(t *testing.T) {
130 defer wantPanic(t, "testing: t.Parallel called inside synctest bubble")
131 t.Parallel()
132 })
133 }
134
135 func TestRun(t *testing.T) {
136 synctest.Test(t, func(t *testing.T) {
137 defer wantPanic(t, "testing: t.Run called inside synctest bubble")
138 t.Run("subtest", func(t *testing.T) {
139 })
140 })
141 }
142
143 func wantPanic(t *testing.T, want string) {
144 if e := recover(); e != nil {
145 if got := fmt.Sprint(e); got != want {
146 t.Errorf("got panic message %q, want %q", got, want)
147 }
148 } else {
149 t.Errorf("got no panic, want one")
150 }
151 }
152
153 func runTest(t *testing.T, args []string, f func(), pattern string) {
154 if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
155 f()
156 return
157 }
158 t.Helper()
159 re := regexp.MustCompile(pattern)
160 testenv.MustHaveExec(t)
161 cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^"+regexp.QuoteMeta(t.Name())+"$", "-test.count=1")
162 cmd.Args = append(cmd.Args, args...)
163 cmd = testenv.CleanCmdEnv(cmd)
164 cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1")
165 out, _ := cmd.CombinedOutput()
166 if !re.Match(out) {
167 t.Errorf("got output:\n%s\nwant matching:\n%s", out, pattern)
168 }
169 }
170
View as plain text