| // Copyright 2012 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package race_test | |
| import ( | |
| "sync" | |
| "testing" | |
| ) | |
| func TestRaceSliceRW(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 2) | |
| go func() { | |
| a[1] = 1 | |
| ch <- true | |
| }() | |
| _ = a[1] | |
| <-ch | |
| } | |
| func TestNoRaceSliceRW(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 2) | |
| go func() { | |
| a[0] = 1 | |
| ch <- true | |
| }() | |
| _ = a[1] | |
| <-ch | |
| } | |
| func TestRaceSliceWW(t *testing.T) { | |
| a := make([]int, 10) | |
| ch := make(chan bool, 1) | |
| go func() { | |
| a[1] = 1 | |
| ch <- true | |
| }() | |
| a[1] = 2 | |
| <-ch | |
| } | |
| func TestNoRaceArrayWW(t *testing.T) { | |
| var a [5]int | |
| ch := make(chan bool, 1) | |
| go func() { | |
| a[0] = 1 | |
| ch <- true | |
| }() | |
| a[1] = 2 | |
| <-ch | |
| } | |
| func TestRaceArrayWW(t *testing.T) { | |
| var a [5]int | |
| ch := make(chan bool, 1) | |
| go func() { | |
| a[1] = 1 | |
| ch <- true | |
| }() | |
| a[1] = 2 | |
| <-ch | |
| } | |
| func TestNoRaceSliceWriteLen(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]bool, 1) | |
| go func() { | |
| a[0] = true | |
| ch <- true | |
| }() | |
| _ = len(a) | |
| <-ch | |
| } | |
| func TestNoRaceSliceWriteCap(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]uint64, 100) | |
| go func() { | |
| a[50] = 123 | |
| ch <- true | |
| }() | |
| _ = cap(a) | |
| <-ch | |
| } | |
| func TestRaceSliceCopyRead(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 10) | |
| b := make([]int, 10) | |
| go func() { | |
| _ = a[5] | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestNoRaceSliceWriteCopy(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 10) | |
| b := make([]int, 10) | |
| go func() { | |
| a[5] = 1 | |
| ch <- true | |
| }() | |
| copy(a[:5], b[:5]) | |
| <-ch | |
| } | |
| func TestRaceSliceCopyWrite2(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 10) | |
| b := make([]int, 10) | |
| go func() { | |
| b[5] = 1 | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestRaceSliceCopyWrite3(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]byte, 10) | |
| go func() { | |
| a[7] = 1 | |
| ch <- true | |
| }() | |
| copy(a, "qwertyqwerty") | |
| <-ch | |
| } | |
| func TestNoRaceSliceCopyRead(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]int, 10) | |
| b := make([]int, 10) | |
| go func() { | |
| _ = b[5] | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestRacePointerSliceCopyRead(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]*int, 10) | |
| b := make([]*int, 10) | |
| go func() { | |
| _ = a[5] | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestNoRacePointerSliceWriteCopy(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]*int, 10) | |
| b := make([]*int, 10) | |
| go func() { | |
| a[5] = new(int) | |
| ch <- true | |
| }() | |
| copy(a[:5], b[:5]) | |
| <-ch | |
| } | |
| func TestRacePointerSliceCopyWrite2(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]*int, 10) | |
| b := make([]*int, 10) | |
| go func() { | |
| b[5] = new(int) | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestNoRacePointerSliceCopyRead(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]*int, 10) | |
| b := make([]*int, 10) | |
| go func() { | |
| _ = b[5] | |
| ch <- true | |
| }() | |
| copy(a, b) | |
| <-ch | |
| } | |
| func TestNoRaceSliceWriteSlice2(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]float64, 10) | |
| go func() { | |
| a[2] = 1.0 | |
| ch <- true | |
| }() | |
| _ = a[0:5] | |
| <-ch | |
| } | |
| func TestRaceSliceWriteSlice(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]float64, 10) | |
| go func() { | |
| a[2] = 1.0 | |
| ch <- true | |
| }() | |
| a = a[5:10] | |
| <-ch | |
| } | |
| func TestNoRaceSliceWriteSlice(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]float64, 10) | |
| go func() { | |
| a[2] = 1.0 | |
| ch <- true | |
| }() | |
| _ = a[5:10] | |
| <-ch | |
| } | |
| func TestNoRaceSliceLenCap(t *testing.T) { | |
| ch := make(chan bool, 1) | |
| a := make([]struct{}, 10) | |
| go func() { | |
| _ = len(a) | |
| ch <- true | |
| }() | |
| _ = cap(a) | |
| <-ch | |
| } | |
| func TestNoRaceStructSlicesRangeWrite(t *testing.T) { | |
| type Str struct { | |
| a []int | |
| b []int | |
| } | |
| ch := make(chan bool, 1) | |
| var s Str | |
| s.a = make([]int, 10) | |
| s.b = make([]int, 10) | |
| go func() { | |
| for range s.a { | |
| } | |
| ch <- true | |
| }() | |
| s.b[5] = 5 | |
| <-ch | |
| } | |
| func TestRaceSliceDifferent(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| s2 := s | |
| go func() { | |
| s[3] = 3 | |
| c <- true | |
| }() | |
| // false negative because s2 is PAUTO w/o PHEAP | |
| // so we do not instrument it | |
| s2[3] = 3 | |
| <-c | |
| } | |
| func TestRaceSliceRangeWrite(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s[3] = 3 | |
| c <- true | |
| }() | |
| for _, v := range s { | |
| _ = v | |
| } | |
| <-c | |
| } | |
| func TestNoRaceSliceRangeWrite(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s[3] = 3 | |
| c <- true | |
| }() | |
| for range s { | |
| } | |
| <-c | |
| } | |
| func TestRaceSliceRangeAppend(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s = append(s, 3) | |
| c <- true | |
| }() | |
| for range s { | |
| } | |
| <-c | |
| } | |
| func TestNoRaceSliceRangeAppend(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| _ = append(s, 3) | |
| c <- true | |
| }() | |
| for range s { | |
| } | |
| <-c | |
| } | |
| func TestRaceSliceVarWrite(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s[3] = 3 | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceVarRead(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| _ = s[3] | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceVarRange(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| for range s { | |
| } | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceVarAppend(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| _ = append(s, 10) | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceVarCopy(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s2 := make([]int, 10) | |
| copy(s, s2) | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceVarCopy2(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s2 := make([]int, 10) | |
| copy(s2, s) | |
| c <- true | |
| }() | |
| s = make([]int, 20) | |
| <-c | |
| } | |
| func TestRaceSliceAppend(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10, 20) | |
| go func() { | |
| _ = append(s, 1) | |
| c <- true | |
| }() | |
| _ = append(s, 2) | |
| <-c | |
| } | |
| func TestRaceSliceAppendWrite(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| _ = append(s, 1) | |
| c <- true | |
| }() | |
| s[0] = 42 | |
| <-c | |
| } | |
| func TestRaceSliceAppendSlice(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| go func() { | |
| s2 := make([]int, 10) | |
| _ = append(s, s2...) | |
| c <- true | |
| }() | |
| s[0] = 42 | |
| <-c | |
| } | |
| func TestRaceSliceAppendSlice2(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| s2foobar := make([]int, 10) | |
| go func() { | |
| _ = append(s, s2foobar...) | |
| c <- true | |
| }() | |
| s2foobar[5] = 42 | |
| <-c | |
| } | |
| func TestRaceSliceAppendString(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]byte, 10) | |
| go func() { | |
| _ = append(s, "qwerty"...) | |
| c <- true | |
| }() | |
| s[0] = 42 | |
| <-c | |
| } | |
| func TestRacePointerSliceAppend(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]*int, 10, 20) | |
| go func() { | |
| _ = append(s, new(int)) | |
| c <- true | |
| }() | |
| _ = append(s, new(int)) | |
| <-c | |
| } | |
| func TestRacePointerSliceAppendWrite(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]*int, 10) | |
| go func() { | |
| _ = append(s, new(int)) | |
| c <- true | |
| }() | |
| s[0] = new(int) | |
| <-c | |
| } | |
| func TestRacePointerSliceAppendSlice(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]*int, 10) | |
| go func() { | |
| s2 := make([]*int, 10) | |
| _ = append(s, s2...) | |
| c <- true | |
| }() | |
| s[0] = new(int) | |
| <-c | |
| } | |
| func TestRacePointerSliceAppendSlice2(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]*int, 10) | |
| s2foobar := make([]*int, 10) | |
| go func() { | |
| _ = append(s, s2foobar...) | |
| c <- true | |
| }() | |
| println("WRITE:", &s2foobar[5]) | |
| s2foobar[5] = nil | |
| <-c | |
| } | |
| func TestNoRaceSliceIndexAccess(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| v := 0 | |
| go func() { | |
| _ = v | |
| c <- true | |
| }() | |
| s[v] = 1 | |
| <-c | |
| } | |
| func TestNoRaceSliceIndexAccess2(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| v := 0 | |
| go func() { | |
| _ = v | |
| c <- true | |
| }() | |
| _ = s[v] | |
| <-c | |
| } | |
| func TestRaceSliceIndexAccess(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| v := 0 | |
| go func() { | |
| v = 1 | |
| c <- true | |
| }() | |
| s[v] = 1 | |
| <-c | |
| } | |
| func TestRaceSliceIndexAccess2(t *testing.T) { | |
| c := make(chan bool, 1) | |
| s := make([]int, 10) | |
| v := 0 | |
| go func() { | |
| v = 1 | |
| c <- true | |
| }() | |
| _ = s[v] | |
| <-c | |
| } | |
| func TestRaceSliceByteToString(t *testing.T) { | |
| c := make(chan string) | |
| s := make([]byte, 10) | |
| go func() { | |
| c <- string(s) | |
| }() | |
| s[0] = 42 | |
| <-c | |
| } | |
| func TestRaceSliceRuneToString(t *testing.T) { | |
| c := make(chan string) | |
| s := make([]rune, 10) | |
| go func() { | |
| c <- string(s) | |
| }() | |
| s[9] = 42 | |
| <-c | |
| } | |
| func TestRaceConcatString(t *testing.T) { | |
| s := "hello" | |
| c := make(chan string, 1) | |
| go func() { | |
| c <- s + " world" | |
| }() | |
| s = "world" | |
| <-c | |
| } | |
| func TestRaceCompareString(t *testing.T) { | |
| s1 := "hello" | |
| s2 := "world" | |
| c := make(chan bool, 1) | |
| go func() { | |
| c <- s1 == s2 | |
| }() | |
| s1 = s2 | |
| <-c | |
| } | |
| func TestRaceSlice3(t *testing.T) { | |
| done := make(chan bool) | |
| x := make([]int, 10) | |
| i := 2 | |
| go func() { | |
| i = 3 | |
| done <- true | |
| }() | |
| _ = x[:1:i] | |
| <-done | |
| } | |
| var saved string | |
| func TestRaceSlice4(t *testing.T) { | |
| // See issue 36794. | |
| data := []byte("hello there") | |
| var wg sync.WaitGroup | |
| wg.Add(1) | |
| go func() { | |
| _ = string(data) | |
| wg.Done() | |
| }() | |
| copy(data, data[2:]) | |
| wg.Wait() | |
| } |