github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/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  }