github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/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 "internal/testenv" 11 "io/ioutil" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "regexp" 16 "runtime" 17 "strings" 18 "testing" 19 ) 20 21 func TestOutput(t *testing.T) { 22 for _, test := range tests { 23 if test.goos != "" && test.goos != runtime.GOOS { 24 t.Logf("test %v runs only on %v, skipping: ", test.name, test.goos) 25 continue 26 } 27 dir, err := ioutil.TempDir("", "go-build") 28 if err != nil { 29 t.Fatalf("failed to create temp directory: %v", err) 30 } 31 defer os.RemoveAll(dir) 32 source := "main.go" 33 if test.run == "test" { 34 source = "main_test.go" 35 } 36 src := filepath.Join(dir, source) 37 f, err := os.Create(src) 38 if err != nil { 39 t.Fatalf("failed to create file: %v", err) 40 } 41 _, err = f.WriteString(test.source) 42 if err != nil { 43 f.Close() 44 t.Fatalf("failed to write: %v", err) 45 } 46 if err := f.Close(); err != nil { 47 t.Fatalf("failed to close file: %v", err) 48 } 49 // Pass -l to the compiler to test stack traces. 50 cmd := exec.Command(testenv.GoToolPath(t), test.run, "-race", "-gcflags=-l", src) 51 // GODEBUG spoils program output, GOMAXPROCS makes it flaky. 52 for _, env := range os.Environ() { 53 if strings.HasPrefix(env, "GODEBUG=") || 54 strings.HasPrefix(env, "GOMAXPROCS=") || 55 strings.HasPrefix(env, "GORACE=") { 56 continue 57 } 58 cmd.Env = append(cmd.Env, env) 59 } 60 cmd.Env = append(cmd.Env, 61 "GOMAXPROCS=1", // see comment in race_test.go 62 "GORACE="+test.gorace, 63 ) 64 got, _ := cmd.CombinedOutput() 65 if !regexp.MustCompile(test.re).MatchString(string(got)) { 66 t.Fatalf("failed test case %v, expect:\n%v\ngot:\n%s", 67 test.name, test.re, got) 68 } 69 } 70 } 71 72 var tests = []struct { 73 name string 74 run string 75 goos string 76 gorace string 77 source string 78 re string 79 }{ 80 {"simple", "run", "", "atexit_sleep_ms=0", ` 81 package main 82 import "time" 83 func main() { 84 done := make(chan bool) 85 x := 0 86 startRacer(&x, done) 87 store(&x, 43) 88 <-done 89 } 90 func store(x *int, v int) { 91 *x = v 92 } 93 func startRacer(x *int, done chan bool) { 94 go racer(x, done) 95 } 96 func racer(x *int, done chan bool) { 97 time.Sleep(10*time.Millisecond) 98 store(x, 42) 99 done <- true 100 } 101 `, `================== 102 WARNING: DATA RACE 103 Write at 0x[0-9,a-f]+ by goroutine [0-9]: 104 main\.store\(\) 105 .+/main\.go:12 \+0x[0-9,a-f]+ 106 main\.racer\(\) 107 .+/main\.go:19 \+0x[0-9,a-f]+ 108 109 Previous write at 0x[0-9,a-f]+ by main goroutine: 110 main\.store\(\) 111 .+/main\.go:12 \+0x[0-9,a-f]+ 112 main\.main\(\) 113 .+/main\.go:8 \+0x[0-9,a-f]+ 114 115 Goroutine [0-9] \(running\) created at: 116 main\.startRacer\(\) 117 .+/main\.go:15 \+0x[0-9,a-f]+ 118 main\.main\(\) 119 .+/main\.go:7 \+0x[0-9,a-f]+ 120 ================== 121 Found 1 data race\(s\) 122 exit status 66 123 `}, 124 125 {"exitcode", "run", "", "atexit_sleep_ms=0 exitcode=13", ` 126 package main 127 func main() { 128 done := make(chan bool) 129 x := 0 130 go func() { 131 x = 42 132 done <- true 133 }() 134 x = 43 135 <-done 136 } 137 `, `exit status 13`}, 138 139 {"strip_path_prefix", "run", "", "atexit_sleep_ms=0 strip_path_prefix=/main.", ` 140 package main 141 func main() { 142 done := make(chan bool) 143 x := 0 144 go func() { 145 x = 42 146 done <- true 147 }() 148 x = 43 149 <-done 150 } 151 `, ` 152 go:7 \+0x[0-9,a-f]+ 153 `}, 154 155 {"halt_on_error", "run", "", "atexit_sleep_ms=0 halt_on_error=1", ` 156 package main 157 func main() { 158 done := make(chan bool) 159 x := 0 160 go func() { 161 x = 42 162 done <- true 163 }() 164 x = 43 165 <-done 166 } 167 `, ` 168 ================== 169 exit status 66 170 `}, 171 172 {"test_fails_on_race", "test", "", "atexit_sleep_ms=0", ` 173 package main_test 174 import "testing" 175 func TestFail(t *testing.T) { 176 done := make(chan bool) 177 x := 0 178 go func() { 179 x = 42 180 done <- true 181 }() 182 x = 43 183 <-done 184 t.Log(t.Failed()) 185 } 186 `, ` 187 ================== 188 --- FAIL: TestFail \(0...s\) 189 .*main_test.go:13: true 190 .*testing.go:.*: race detected during execution of test 191 FAIL`}, 192 193 {"slicebytetostring_pc", "run", "", "atexit_sleep_ms=0", ` 194 package main 195 func main() { 196 done := make(chan string) 197 data := make([]byte, 10) 198 go func() { 199 done <- string(data) 200 }() 201 data[0] = 1 202 <-done 203 } 204 `, ` 205 runtime\.slicebytetostring\(\) 206 .*/runtime/string\.go:.* 207 main\.main\.func1\(\) 208 .*/main.go:7`}, 209 210 // Test for http://golang.org/issue/17190 211 {"external_cgo_thread", "run", "linux", "atexit_sleep_ms=0", ` 212 package main 213 214 /* 215 #include <pthread.h> 216 typedef struct cb { 217 int foo; 218 } cb; 219 extern void goCallback(); 220 static inline void *threadFunc(void *p) { 221 goCallback(); 222 return 0; 223 } 224 static inline void startThread(cb* c) { 225 pthread_t th; 226 pthread_create(&th, 0, threadFunc, 0); 227 } 228 */ 229 import "C" 230 231 import "time" 232 233 var racy int 234 235 //export goCallback 236 func goCallback() { 237 racy++ 238 } 239 240 func main() { 241 var c C.cb 242 C.startThread(&c) 243 time.Sleep(time.Second) 244 racy++ 245 } 246 `, `================== 247 WARNING: DATA RACE 248 Read at 0x[0-9,a-f]+ by main goroutine: 249 main\.main\(\) 250 .*/main\.go:34 \+0x[0-9,a-f]+ 251 252 Previous write at 0x[0-9,a-f]+ by goroutine [0-9]: 253 main\.goCallback\(\) 254 .*/main\.go:27 \+0x[0-9,a-f]+ 255 main._cgoexpwrap_[0-9a-z]+_goCallback\(\) 256 .*/_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+ 257 258 Goroutine [0-9] \(running\) created at: 259 runtime\.newextram\(\) 260 .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+ 261 ==================`}, 262 {"second_test_passes", "test", "", "atexit_sleep_ms=0", ` 263 package main_test 264 import "testing" 265 func TestFail(t *testing.T) { 266 done := make(chan bool) 267 x := 0 268 go func() { 269 x = 42 270 done <- true 271 }() 272 x = 43 273 <-done 274 } 275 276 func TestPass(t *testing.T) { 277 } 278 `, ` 279 ================== 280 --- FAIL: TestFail \(0...s\) 281 .*testing.go:.*: race detected during execution of test 282 FAIL`}, 283 }