Fix a deadlock in the monitor test

A deadlock would happen if the monitor attempted to write multiple
points. Since the test only reads the first set of points written to the
channel and does not read from the channel on the second read, the
WritePoints call deadlocks while the monitor is trying to close since
the monitor requires all of its goroutines to end. But, one of the
goroutines is attempting to call WritePoints which is waiting for the
test to read the point it is trying to write.

This change ensures that the done channel is closed before calling close
so the WritePoints call can exit.
pull/9426/head
Jonathan A. Sternberg 2018-02-09 14:18:25 -06:00
parent e451c6cadf
commit b740567fe4
1 changed files with 7 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
"os"
"reflect"
"sort"
"sync"
"testing"
"time"
@ -283,7 +284,9 @@ func expvarMap(name string, tags map[string]string, fields map[string]interface{
func TestMonitor_Expvar(t *testing.T) {
done := make(chan struct{})
defer close(done)
var once sync.Once
// Ensure the done channel will always be closed by calling this early.
defer once.Do(func() { close(done) })
ch := make(chan models.Points)
var mc MetaClient
@ -339,6 +342,9 @@ 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) })
hostname, _ := os.Hostname()
timer := time.NewTimer(100 * time.Millisecond)