1 // Copyright 2013 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.
21 func TestOutput(t *testing.T) {
23 out, err := exec.Command(testenv.GoToolPath(t), "install", "-race", "-pkgdir="+pkgdir, "testing").CombinedOutput()
25 t.Fatalf("go install -race: %v\n%s", err, out)
28 for _, test := range tests {
29 if test.goos != "" && test.goos != runtime.GOOS {
30 t.Logf("test %v runs only on %v, skipping: ", test.name, test.goos)
35 if test.run == "test" {
36 source = "main_test.go"
38 src := filepath.Join(dir, source)
39 f, err := os.Create(src)
41 t.Fatalf("failed to create file: %v", err)
43 _, err = f.WriteString(test.source)
46 t.Fatalf("failed to write: %v", err)
48 if err := f.Close(); err != nil {
49 t.Fatalf("failed to close file: %v", err)
52 cmd := exec.Command(testenv.GoToolPath(t), test.run, "-race", "-pkgdir="+pkgdir, src)
53 // GODEBUG spoils program output, GOMAXPROCS makes it flaky.
54 for _, env := range os.Environ() {
55 if strings.HasPrefix(env, "GODEBUG=") ||
56 strings.HasPrefix(env, "GOMAXPROCS=") ||
57 strings.HasPrefix(env, "GORACE=") {
60 cmd.Env = append(cmd.Env, env)
62 cmd.Env = append(cmd.Env,
63 "GOMAXPROCS=1", // see comment in race_test.go
64 "GORACE="+test.gorace,
66 got, _ := cmd.CombinedOutput()
68 for _, re := range test.re {
69 if regexp.MustCompile(re).MatchString(string(got)) {
75 exp := fmt.Sprintf("expect:\n%v\n", test.re[0])
77 exp = fmt.Sprintf("expected one of %d patterns:\n",
79 for k, re := range test.re {
80 exp += fmt.Sprintf("pattern %d:\n%v\n", k, re)
83 t.Fatalf("failed test case %v, %sgot:\n%s",
89 var tests = []struct {
97 {"simple", "run", "", "atexit_sleep_ms=0", `
101 var donechan chan bool
103 done := make(chan bool)
109 func store(x *int, v int) {
112 func startRacer(x *int, done chan bool) {
118 time.Sleep(10*time.Millisecond)
122 `, []string{`==================
124 Write at 0x[0-9,a-f]+ by goroutine [0-9]:
126 .+/main\.go:14 \+0x[0-9,a-f]+
128 .+/main\.go:23 \+0x[0-9,a-f]+
130 Previous write at 0x[0-9,a-f]+ by main goroutine:
132 .+/main\.go:14 \+0x[0-9,a-f]+
134 .+/main\.go:10 \+0x[0-9,a-f]+
136 Goroutine [0-9] \(running\) created at:
138 .+/main\.go:19 \+0x[0-9,a-f]+
140 .+/main\.go:9 \+0x[0-9,a-f]+
142 Found 1 data race\(s\)
146 {"exitcode", "run", "", "atexit_sleep_ms=0 exitcode=13", `
149 done := make(chan bool)
158 `, []string{`exit status 13`}},
160 {"strip_path_prefix", "run", "", "atexit_sleep_ms=0 strip_path_prefix=/main.", `
163 done := make(chan bool)
176 {"halt_on_error", "run", "", "atexit_sleep_ms=0 halt_on_error=1", `
179 done := make(chan bool)
193 {"test_fails_on_race", "test", "", "atexit_sleep_ms=0", `
196 func TestFail(t *testing.T) {
197 done := make(chan bool)
210 --- FAIL: TestFail \([0-9.]+s\)
211 .*main_test.go:14: true
212 .*testing.go:.*: race detected during execution of test
215 {"slicebytetostring_pc", "run", "", "atexit_sleep_ms=0", `
218 done := make(chan string)
219 data := make([]byte, 10)
227 runtime\.slicebytetostring\(\)
228 .*/runtime/string\.go:.*
229 main\.main\.func1\(\)
232 // Test for https://golang.org/issue/33309
233 {"midstack_inlining_traceback", "run", "linux", "atexit_sleep_ms=0", `
256 `, []string{`==================
258 Read at 0x[0-9,a-f]+ by goroutine [0-9]:
260 .+/main\.go:22 \+0x[0-9,a-f]+
262 .+/main\.go:18 \+0x[0-9,a-f]+
264 .+/main\.go:14 \+0x[0-9,a-f]+
266 Previous write at 0x[0-9,a-f]+ by main goroutine:
268 .+/main\.go:9 \+0x[0-9,a-f]+
270 Goroutine [0-9] \(running\) created at:
272 .+/main\.go:8 \+0x[0-9,a-f]+
274 Found 1 data race\(s\)
278 // Test for https://golang.org/issue/17190
279 {"external_cgo_thread", "run", "linux", "atexit_sleep_ms=0", `
287 extern void goCallback();
288 static inline void *threadFunc(void *p) {
292 static inline void startThread(cb* c) {
294 pthread_create(&th, 0, threadFunc, 0);
309 done = make(chan bool)
315 `, []string{`==================
317 Read at 0x[0-9,a-f]+ by main goroutine:
319 .*/main\.go:34 \+0x[0-9,a-f]+
321 Previous write at 0x[0-9,a-f]+ by goroutine [0-9]:
323 .*/main\.go:27 \+0x[0-9,a-f]+
324 _cgoexp_[0-9a-z]+_goCallback\(\)
325 .*_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
326 _cgoexp_[0-9a-z]+_goCallback\(\)
327 <autogenerated>:1 \+0x[0-9,a-f]+
329 Goroutine [0-9] \(running\) created at:
330 runtime\.newextram\(\)
331 .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
335 Read at 0x[0-9,a-f]+ by .*:
337 .*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
339 Previous write at 0x[0-9,a-f]+ by .*:
341 .*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
343 Goroutine [0-9] \(running\) created at:
344 runtime\.newextram\(\)
345 .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
346 ==================`}},
347 {"second_test_passes", "test", "", "atexit_sleep_ms=0", `
350 func TestFail(t *testing.T) {
351 done := make(chan bool)
362 func TestPass(t *testing.T) {
366 --- FAIL: TestFail \([0-9.]+s\)
367 .*testing.go:.*: race detected during execution of test
369 {"mutex", "run", "", "atexit_sleep_ms=0", `
376 c := make(chan bool, 1)
380 var wg sync.WaitGroup
381 for i := 0; i < threads; i++ {
385 for i := 0; i < iterations; i++ {
392 for i := 0; i < iterations; i++ {
398 if (data == iterations*(threads+1)) { fmt.Println("pass") }
399 }`, []string{`pass`}},
400 // Test for https://github.com/golang/go/issues/37355
401 {"chanmm", "run", "", "atexit_sleep_ms=0", `
408 c := make(chan bool, 1)
410 var wg sync.WaitGroup
419 time.Sleep(time.Second)
428 `, []string{`==================
430 Write at 0x[0-9,a-f]+ by goroutine [0-9]:
431 main\.main\.func2\(\)
432 .*/main\.go:21 \+0x[0-9,a-f]+
434 Previous write at 0x[0-9,a-f]+ by main goroutine:
436 .*/main\.go:23 \+0x[0-9,a-f]+
438 Goroutine [0-9] \(running\) created at:
440 .*/main.go:[0-9]+ \+0x[0-9,a-f]+
441 ==================`}},
442 // Test symbolizing wrappers. Both (*T).f and main.gowrap1 are wrappers.
443 // go.dev/issue/60245
444 {"wrappersym", "run", "", "atexit_sleep_ms=0", `
447 var wg sync.WaitGroup
461 `, []string{`==================
463 Write at 0x[0-9,a-f]+ by goroutine [0-9]:
465 .*/main.go:15 \+0x[0-9,a-f]+
467 <autogenerated>:1 \+0x[0-9,a-f]+
468 main\.main\.gowrap1\(\)
469 .*/main.go:9 \+0x[0-9,a-f]+
471 Previous write at 0x[0-9,a-f]+ by main goroutine:
473 .*/main.go:15 \+0x[0-9,a-f]+
475 <autogenerated>:1 \+0x[0-9,a-f]+
477 .*/main.go:10 \+0x[0-9,a-f]+