From 68dd3ee6216ce976954b2bd3a19626a12d96e40a Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Tue, 6 Oct 2015 11:37:08 +0900 Subject: [PATCH] etcdserver, test: don't access testing.T in time.AfterFunc()'s own goroutine time.AfterFunc() creates its own goroutine and calls the callback function in the goroutine. It can cause datarace like the problem fixed in the commit de1a16e0f107c4e1ffcc7128f7f343baf9631e30 . This commit also fixes the potential dataraces of tests in etcdserver/server_test.go . --- etcdserver/server_test.go | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index fe2d22775..b5bd113aa 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -604,11 +604,18 @@ func TestSync(t *testing.T) { reqIDGen: idutil.NewGenerator(0, time.Time{}), } // check that sync is non-blocking - timer := time.AfterFunc(time.Second, func() { - t.Fatalf("sync should be non-blocking but did not return after 1s!") - }) - srv.sync(10 * time.Second) - timer.Stop() + done := make(chan struct{}) + go func() { + srv.sync(10 * time.Second) + done <- struct{}{} + }() + + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("sync should be non-blocking but did not return after 1s!") + } + testutil.WaitSchedule() action := n.Action() @@ -637,11 +644,17 @@ func TestSyncTimeout(t *testing.T) { reqIDGen: idutil.NewGenerator(0, time.Time{}), } // check that sync is non-blocking - timer := time.AfterFunc(time.Second, func() { - t.Fatalf("sync should be non-blocking but did not return after 1s!") - }) - srv.sync(0) - timer.Stop() + done := make(chan struct{}) + go func() { + srv.sync(0) + done <- struct{}{} + }() + + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("sync should be non-blocking but did not return after 1s!") + } // give time for goroutine in sync to cancel testutil.WaitSchedule()