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