Home | History | Annotate | Download | only in testdata
      1 // Copyright 2011 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 package race_test
      6 
      7 import (
      8 	"sync"
      9 	"testing"
     10 	"time"
     11 )
     12 
     13 func TestNoRaceCond(t *testing.T) {
     14 	x := 0
     15 	condition := 0
     16 	var mu sync.Mutex
     17 	cond := sync.NewCond(&mu)
     18 	go func() {
     19 		x = 1
     20 		mu.Lock()
     21 		condition = 1
     22 		cond.Signal()
     23 		mu.Unlock()
     24 	}()
     25 	mu.Lock()
     26 	for condition != 1 {
     27 		cond.Wait()
     28 	}
     29 	mu.Unlock()
     30 	x = 2
     31 }
     32 
     33 func TestRaceCond(t *testing.T) {
     34 	done := make(chan bool)
     35 	var mu sync.Mutex
     36 	cond := sync.NewCond(&mu)
     37 	x := 0
     38 	condition := 0
     39 	go func() {
     40 		time.Sleep(10 * time.Millisecond) // Enter cond.Wait loop
     41 		x = 1
     42 		mu.Lock()
     43 		condition = 1
     44 		cond.Signal()
     45 		mu.Unlock()
     46 		time.Sleep(10 * time.Millisecond) // Exit cond.Wait loop
     47 		mu.Lock()
     48 		x = 3
     49 		mu.Unlock()
     50 		done <- true
     51 	}()
     52 	mu.Lock()
     53 	for condition != 1 {
     54 		cond.Wait()
     55 	}
     56 	mu.Unlock()
     57 	x = 2
     58 	<-done
     59 }
     60 
     61 // We do not currently automatically
     62 // parse this test. It is intended that the creation
     63 // stack is observed manually not to contain
     64 // off-by-one errors
     65 func TestRaceAnnounceThreads(t *testing.T) {
     66 	const N = 7
     67 	allDone := make(chan bool, N)
     68 
     69 	var x int
     70 
     71 	var f, g, h func()
     72 	f = func() {
     73 		x = 1
     74 		go g()
     75 		go func() {
     76 			x = 1
     77 			allDone <- true
     78 		}()
     79 		x = 2
     80 		allDone <- true
     81 	}
     82 
     83 	g = func() {
     84 		for i := 0; i < 2; i++ {
     85 			go func() {
     86 				x = 1
     87 				allDone <- true
     88 			}()
     89 			allDone <- true
     90 		}
     91 	}
     92 
     93 	h = func() {
     94 		x = 1
     95 		x = 2
     96 		go f()
     97 		allDone <- true
     98 	}
     99 
    100 	go h()
    101 
    102 	for i := 0; i < N; i++ {
    103 		<-allDone
    104 	}
    105 }
    106 
    107 func TestNoRaceAfterFunc1(t *testing.T) {
    108 	i := 2
    109 	c := make(chan bool)
    110 	var f func()
    111 	f = func() {
    112 		i--
    113 		if i >= 0 {
    114 			time.AfterFunc(0, f)
    115 		} else {
    116 			c <- true
    117 		}
    118 	}
    119 
    120 	time.AfterFunc(0, f)
    121 	<-c
    122 }
    123 
    124 func TestNoRaceAfterFunc2(t *testing.T) {
    125 	var x int
    126 	timer := time.AfterFunc(10, func() {
    127 		x = 1
    128 	})
    129 	defer timer.Stop()
    130 	_ = x
    131 }
    132 
    133 func TestNoRaceAfterFunc3(t *testing.T) {
    134 	c := make(chan bool, 1)
    135 	x := 0
    136 	time.AfterFunc(1e7, func() {
    137 		x = 1
    138 		c <- true
    139 	})
    140 	<-c
    141 }
    142 
    143 func TestRaceAfterFunc3(t *testing.T) {
    144 	c := make(chan bool, 2)
    145 	x := 0
    146 	time.AfterFunc(1e7, func() {
    147 		x = 1
    148 		c <- true
    149 	})
    150 	time.AfterFunc(2e7, func() {
    151 		x = 2
    152 		c <- true
    153 	})
    154 	<-c
    155 	<-c
    156 }
    157 
    158 // This test's output is intended to be
    159 // observed manually. One should check
    160 // that goroutine creation stack is
    161 // comprehensible.
    162 func TestRaceGoroutineCreationStack(t *testing.T) {
    163 	var x int
    164 	var ch = make(chan bool, 1)
    165 
    166 	f1 := func() {
    167 		x = 1
    168 		ch <- true
    169 	}
    170 	f2 := func() { go f1() }
    171 	f3 := func() { go f2() }
    172 	f4 := func() { go f3() }
    173 
    174 	go f4()
    175 	x = 2
    176 	<-ch
    177 }
    178 
    179 // A nil pointer in a mutex method call should not
    180 // corrupt the race detector state.
    181 // Used to hang indefinitely.
    182 func TestNoRaceNilMutexCrash(t *testing.T) {
    183 	var mutex sync.Mutex
    184 	panics := 0
    185 	defer func() {
    186 		if x := recover(); x != nil {
    187 			mutex.Lock()
    188 			panics++
    189 			mutex.Unlock()
    190 		} else {
    191 			panic("no panic")
    192 		}
    193 	}()
    194 	var othermutex *sync.RWMutex
    195 	othermutex.RLock()
    196 }
    197