github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/runtime/race/output_test.go (about) 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. 4 5 // +build race 6 7 package race_test 8 9 import ( 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "regexp" 15 "strings" 16 "testing" 17 ) 18 19 func TestOutput(t *testing.T) { 20 for _, test := range tests { 21 dir, err := ioutil.TempDir("", "go-build") 22 if err != nil { 23 t.Fatalf("failed to create temp directory: %v", err) 24 } 25 defer os.RemoveAll(dir) 26 src := filepath.Join(dir, "main.go") 27 f, err := os.Create(src) 28 if err != nil { 29 t.Fatalf("failed to create file: %v", err) 30 } 31 _, err = f.WriteString(test.source) 32 if err != nil { 33 f.Close() 34 t.Fatalf("failed to write: %v", err) 35 } 36 if err := f.Close(); err != nil { 37 t.Fatalf("failed to close file: %v", err) 38 } 39 // Pass -l to the compiler to test stack traces. 40 cmd := exec.Command("go", "run", "-race", "-gcflags=-l", src) 41 // GODEBUG spoils program output, GOMAXPROCS makes it flaky. 42 for _, env := range os.Environ() { 43 if strings.HasPrefix(env, "GODEBUG=") || 44 strings.HasPrefix(env, "GOMAXPROCS=") || 45 strings.HasPrefix(env, "GORACE=") { 46 continue 47 } 48 cmd.Env = append(cmd.Env, env) 49 } 50 cmd.Env = append(cmd.Env, "GORACE="+test.gorace) 51 got, _ := cmd.CombinedOutput() 52 if !regexp.MustCompile(test.re).MatchString(string(got)) { 53 t.Fatalf("failed test case %v, expect:\n%v\ngot:\n%s", 54 test.name, test.re, got) 55 } 56 } 57 } 58 59 var tests = []struct { 60 name string 61 gorace string 62 source string 63 re string 64 }{ 65 {"simple", "atexit_sleep_ms=0", ` 66 package main 67 import "time" 68 func main() { 69 done := make(chan bool) 70 x := 0 71 startRacer(&x, done) 72 store(&x, 43) 73 <-done 74 } 75 func store(x *int, v int) { 76 *x = v 77 } 78 func startRacer(x *int, done chan bool) { 79 go racer(x, done) 80 } 81 func racer(x *int, done chan bool) { 82 time.Sleep(10*time.Millisecond) 83 store(x, 42) 84 done <- true 85 } 86 `, `================== 87 WARNING: DATA RACE 88 Write by goroutine [0-9]: 89 main\.store\(\) 90 .+/main\.go:12 \+0x[0-9,a-f]+ 91 main\.racer\(\) 92 .+/main\.go:19 \+0x[0-9,a-f]+ 93 94 Previous write by main goroutine: 95 main\.store\(\) 96 .+/main\.go:12 \+0x[0-9,a-f]+ 97 main\.main\(\) 98 .+/main\.go:8 \+0x[0-9,a-f]+ 99 100 Goroutine [0-9] \(running\) created at: 101 main\.startRacer\(\) 102 .+/main\.go:15 \+0x[0-9,a-f]+ 103 main\.main\(\) 104 .+/main\.go:7 \+0x[0-9,a-f]+ 105 ================== 106 Found 1 data race\(s\) 107 exit status 66 108 `}, 109 110 {"exitcode", "atexit_sleep_ms=0 exitcode=13", ` 111 package main 112 func main() { 113 done := make(chan bool) 114 x := 0 115 go func() { 116 x = 42 117 done <- true 118 }() 119 x = 43 120 <-done 121 } 122 `, `exit status 13`}, 123 124 {"strip_path_prefix", "atexit_sleep_ms=0 strip_path_prefix=/main.", ` 125 package main 126 func main() { 127 done := make(chan bool) 128 x := 0 129 go func() { 130 x = 42 131 done <- true 132 }() 133 x = 43 134 <-done 135 } 136 `, ` 137 go:7 \+0x[0-9,a-f]+ 138 `}, 139 140 {"halt_on_error", "atexit_sleep_ms=0 halt_on_error=1", ` 141 package main 142 func main() { 143 done := make(chan bool) 144 x := 0 145 go func() { 146 x = 42 147 done <- true 148 }() 149 x = 43 150 <-done 151 } 152 `, ` 153 ================== 154 exit status 66 155 `}, 156 }