Fix the deadlocks in the monitor tests

This was previous fixed in b740567 for one test, but the other tests in
the package were still vulnerable. The tests are all updated to use a
cancel context instead since then it doesn't need to be wrapped in a
sync.Once.
pull/9536/head
Jonathan A. Sternberg 2018-03-09 10:48:02 -06:00
parent 46a5a66136
commit af5612faa3
1 changed files with 13 additions and 15 deletions

View File

@ -2,12 +2,12 @@ package monitor_test
import (
"bytes"
"context"
"expvar"
"fmt"
"os"
"reflect"
"sort"
"sync"
"testing"
"time"
@ -85,8 +85,8 @@ func TestMonitor_SetPointsWriter_StoreDisabled(t *testing.T) {
}
func TestMonitor_StoreStatistics(t *testing.T) {
done := make(chan struct{})
defer close(done)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := make(chan models.Points)
var mc MetaClient
@ -126,7 +126,7 @@ func TestMonitor_StoreStatistics(t *testing.T) {
// Attempt to write the points to the main goroutine.
select {
case <-done:
case <-ctx.Done():
case ch <- points:
}
return nil
@ -142,6 +142,7 @@ func TestMonitor_StoreStatistics(t *testing.T) {
t.Fatalf("unexpected error: %s", err)
}
defer s.Close()
defer cancel()
timer := time.NewTimer(100 * time.Millisecond)
select {
@ -188,8 +189,8 @@ func TestMonitor_Reporter(t *testing.T) {
}
})
done := make(chan struct{})
defer close(done)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := make(chan models.Points)
var mc MetaClient
@ -201,7 +202,7 @@ func TestMonitor_Reporter(t *testing.T) {
pw.WritePointsFn = func(database, policy string, points models.Points) error {
// Attempt to write the points to the main goroutine.
select {
case <-done:
case <-ctx.Done():
case ch <- points:
}
return nil
@ -217,6 +218,7 @@ func TestMonitor_Reporter(t *testing.T) {
t.Fatalf("unexpected error: %s", err)
}
defer s.Close()
defer cancel()
timer := time.NewTimer(100 * time.Millisecond)
select {
@ -283,10 +285,8 @@ func expvarMap(name string, tags map[string]string, fields map[string]interface{
}
func TestMonitor_Expvar(t *testing.T) {
done := make(chan struct{})
var once sync.Once
// Ensure the done channel will always be closed by calling this early.
defer once.Do(func() { close(done) })
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := make(chan models.Points)
var mc MetaClient
@ -298,7 +298,7 @@ func TestMonitor_Expvar(t *testing.T) {
pw.WritePointsFn = func(database, policy string, points models.Points) error {
// Attempt to write the points to the main goroutine.
select {
case <-done:
case <-ctx.Done():
case ch <- points:
}
return nil
@ -342,9 +342,7 @@ func TestMonitor_Expvar(t *testing.T) {
t.Fatalf("unexpected error: %s", err)
}
defer s.Close()
// Call this again here. Since defers run in first in, last out order, we want to close
// the done channel before we call close on the monitor. This prevents a deadlock in the test.
defer once.Do(func() { close(done) })
defer cancel()
hostname, _ := os.Hostname()
timer := time.NewTimer(100 * time.Millisecond)