Skip to content

Instantly share code, notes, and snippets.

@kylelemons
Last active April 11, 2019 20:21
Show Gist options
  • Save kylelemons/2cc8fd2da48b1bdba4ec58491fff9762 to your computer and use it in GitHub Desktop.
Save kylelemons/2cc8fd2da48b1bdba4ec58491fff9762 to your computer and use it in GitHub Desktop.
Creating a channel asynchronously - race detector testing
package gorace // run with go test -race
import (
"sync"
"testing"
"time"
)
var (
every = 100 * time.Millisecond
after = 150 * time.Millisecond
delay = 200 * time.Millisecond
)
func TestSafe_mutex(t *testing.T) {
tick := time.Tick(every)
var mu sync.Mutex
var tock <-chan time.Time
getTock := func() <-chan time.Time {
mu.Lock()
defer mu.Unlock()
return tock
}
go func() {
time.Sleep(after)
mu.Lock()
defer mu.Unlock()
tock = time.Tick(delay)
}()
for i := 0; i < 10; i++ {
select {
case <-tick:
t.Logf("Tick %s\n", time.Now())
case <-getTock():
t.Logf("Tock %s\n", time.Now())
}
}
}
func TestSafe_channel(t *testing.T) {
tick := time.Tick(every)
tockReady := make(chan (<-chan time.Time))
go func() {
time.Sleep(after)
tockReady <- time.Tick(delay)
}()
var tock <-chan time.Time
for i := 0; i < 10; i++ {
select {
case tock = <-tockReady:
t.Logf("Tock ready\n")
case <-tick:
t.Logf("Tick %s\n", time.Now())
case <-tock:
t.Logf("Tock %s\n", time.Now())
}
}
}
func TestRace_var(t *testing.T) {
tick := time.Tick(every)
var mu sync.Mutex
var tock <-chan time.Time
go func() {
time.Sleep(after)
mu.Lock()
tock = time.Tick(delay)
}()
for i := 0; i < 10; i++ {
select {
case <-tick:
t.Logf("Tick %s\n", time.Now())
case <-tock:
t.Logf("Tock %s\n", time.Now())
}
}
}
func TestRace_ptr(t *testing.T) {
tick := time.Tick(every)
var mu sync.Mutex
var tock <-chan time.Time
p := &tock
go func() {
time.Sleep(after)
mu.Lock()
*p = time.Tick(delay)
}()
for i := 0; i < 10; i++ {
select {
case <-tick:
t.Logf("Tick %s\n", time.Now())
case <-*p:
t.Logf("Tock %s\n", time.Now())
}
}
}
==================
WARNING: DATA RACE
Write at 0x00c000010020 by goroutine 14:
_/tmp/gorace.TestRace_var.func1()
/tmp/gorace/race_test.go:75 +0x8e
Previous read at 0x00c000010020 by goroutine 13:
_/tmp/gorace.TestRace_var()
/tmp/gorace/race_test.go:82 +0x189
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
Goroutine 14 (running) created at:
_/tmp/gorace.TestRace_var()
/tmp/gorace/race_test.go:72 +0x102
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
Goroutine 13 (running) created at:
testing.(*T).Run()
/usr/lib/google-golang/src/testing/testing.go:916 +0x699
testing.runTests.func1()
/usr/lib/google-golang/src/testing/testing.go:1159 +0xa8
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
testing.runTests()
/usr/lib/google-golang/src/testing/testing.go:1157 +0x523
testing.(*M).Run()
/usr/lib/google-golang/src/testing/testing.go:1074 +0x2eb
main.main()
_testmain.go:48 +0x222
==================
--- FAIL: TestRace_var (0.75s)
race_test.go:81: Tick 2019-04-11 13:21:29.965519506 -0700 PDT m=+1.553782437
race_test.go:81: Tick 2019-04-11 13:21:30.065483846 -0700 PDT m=+1.653746663
race_test.go:81: Tick 2019-04-11 13:21:30.165504594 -0700 PDT m=+1.753767529
race_test.go:83: Tock 2019-04-11 13:21:30.215938983 -0700 PDT m=+1.804201852
race_test.go:81: Tick 2019-04-11 13:21:30.265532886 -0700 PDT m=+1.853795820
race_test.go:81: Tick 2019-04-11 13:21:30.365505412 -0700 PDT m=+1.953768348
race_test.go:83: Tock 2019-04-11 13:21:30.415963429 -0700 PDT m=+2.004226365
race_test.go:81: Tick 2019-04-11 13:21:30.465525752 -0700 PDT m=+2.053788687
race_test.go:81: Tick 2019-04-11 13:21:30.565490398 -0700 PDT m=+2.153753342
race_test.go:83: Tock 2019-04-11 13:21:30.615941258 -0700 PDT m=+2.204204207
testing.go:809: race detected during execution of test
==================
WARNING: DATA RACE
Write at 0x00c000114028 by goroutine 16:
_/tmp/gorace.TestRace_ptr.func1()
/tmp/gorace/race_test.go:98 +0x90
Previous read at 0x00c000114028 by goroutine 15:
_/tmp/gorace.TestRace_ptr()
/tmp/gorace/race_test.go:105 +0x12c
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
Goroutine 16 (running) created at:
_/tmp/gorace.TestRace_ptr()
/tmp/gorace/race_test.go:95 +0x102
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
Goroutine 15 (running) created at:
testing.(*T).Run()
/usr/lib/google-golang/src/testing/testing.go:916 +0x699
testing.runTests.func1()
/usr/lib/google-golang/src/testing/testing.go:1159 +0xa8
testing.tRunner()
/usr/lib/google-golang/src/testing/testing.go:865 +0x163
testing.runTests()
/usr/lib/google-golang/src/testing/testing.go:1157 +0x523
testing.(*M).Run()
/usr/lib/google-golang/src/testing/testing.go:1074 +0x2eb
main.main()
_testmain.go:48 +0x222
==================
--- FAIL: TestRace_ptr (0.75s)
race_test.go:104: Tick 2019-04-11 13:21:30.716809242 -0700 PDT m=+2.305072176
race_test.go:104: Tick 2019-04-11 13:21:30.816801624 -0700 PDT m=+2.405064563
race_test.go:104: Tick 2019-04-11 13:21:30.916805626 -0700 PDT m=+2.505068565
race_test.go:106: Tock 2019-04-11 13:21:30.967261682 -0700 PDT m=+2.555524617
race_test.go:104: Tick 2019-04-11 13:21:31.016773655 -0700 PDT m=+2.605036620
race_test.go:104: Tick 2019-04-11 13:21:31.116817055 -0700 PDT m=+2.705079938
race_test.go:106: Tock 2019-04-11 13:21:31.167264561 -0700 PDT m=+2.755527493
race_test.go:104: Tick 2019-04-11 13:21:31.216804368 -0700 PDT m=+2.805067304
race_test.go:104: Tick 2019-04-11 13:21:31.316801462 -0700 PDT m=+2.905064397
race_test.go:106: Tock 2019-04-11 13:21:31.367269934 -0700 PDT m=+2.955532845
testing.go:809: race detected during execution of test
FAIL
exit status 1
FAIL _/tmp/gorace 2.995s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment