Browse Source

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 .
Hitoshi Mitake 10 years ago
parent
commit
68dd3ee621
1 changed files with 23 additions and 10 deletions
  1. 23 10
      etcdserver/server_test.go

+ 23 - 10
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()