I am using the dockerclient https://github.com/samalba/dockerclient which has a channel-based API to listen for events client.MonitorEvents()
and a convenient callback method client.StartMonitorEvents(callbackHandler)
.
I want to test that the handler gets called. Of course, the dockerclient handles the events in a goroutine.
For now, my handler just spits out a log. If I wait in my test, everything is handled. If I do not, it exits before it handles anything:
func eventCallback(event *dockerclient.Event, ec chan error, args ...interface{}) {
log.Printf("Received event: %#v
", *event)
}
My test seems straightforward:
func TestReceiveEvent(t *testing.T) {
createAndMonitorEvents(server.URL)
<- eventReady
eventWriter.Write([]byte(someEvent))
// test for something here
}
Of course, it doesn't work unless I put in a time.Sleep()
because of the goroutine.
How do I tell my test, "wait for the other routine to do its work before running the test", other than putting in some arbitrary sleep? I am looking to test that the event is processed correctly by my handler.
The alternate interface, client.MonitorEvents()
returns a channel, which gives me greater control, but the receive off the channel spits out infinite nil
events.
UPDATE:
As requested, createAndMonitorEvents is:
func createAndMonitorEvents(url string) {
// Init the client
docker, _ := dockerclient.NewDockerClient(url, nil)
// Listen to events
stopchan := make(chan struct{})
go func() {
eventErrChan, err := docker.MonitorEvents(nil, stopchan)
if err != nil {
return
}
for e := range eventErrChan {
if e.Error != nil {
return
}
eventCallback(&e.Event, nil)
}
fmt.Println("monitor in place")
}()
}