mirror of https://github.com/fluffle/goirc
Add tests for explicit and implicit (via EOF) shutdown; fix bug ;-)
This commit is contained in:
parent
770c5eb5ac
commit
7d9b8c3099
|
@ -265,11 +265,11 @@ func (conn *Conn) shutdown() {
|
|||
// Guard against double-call of shutdown() if we get an error in send()
|
||||
// as calling sock.Close() will cause recv() to recieve EOF in readstring()
|
||||
if conn.Connected {
|
||||
conn.Dispatcher.Dispatch("disconnected", conn, &Line{})
|
||||
conn.Connected = false
|
||||
conn.sock.Close()
|
||||
conn.cSend <- true
|
||||
conn.cLoop <- true
|
||||
conn.Dispatcher.Dispatch("disconnected", conn, &Line{})
|
||||
// reinit datastructures ready for next connection
|
||||
// do this here rather than after runLoop()'s for due to race
|
||||
conn.initialise()
|
||||
|
|
|
@ -3,6 +3,7 @@ package client
|
|||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func setUp(t *testing.T) (*mockNetConn, *Conn) {
|
||||
|
@ -14,6 +15,89 @@ func setUp(t *testing.T) (*mockNetConn, *Conn) {
|
|||
return m, c
|
||||
}
|
||||
|
||||
func tearDown(m *mockNetConn, c *Conn) {
|
||||
// This is enough to cause all the associated goroutines in m and c stop
|
||||
// (tested below in TestShutdown to make sure this is the case)
|
||||
m.Close()
|
||||
}
|
||||
|
||||
func TestShutdown(t *testing.T) {
|
||||
_, c := setUp(t)
|
||||
|
||||
// Shutdown won't clean things up unless we're "connected" already
|
||||
c.Connected = true
|
||||
|
||||
// Setup a mock event dispatcher to test correct triggering of "disconnected"
|
||||
flag := false
|
||||
c.Dispatcher = WasEventDispatched("disconnected", &flag)
|
||||
|
||||
// Call shutdown manually
|
||||
c.shutdown()
|
||||
|
||||
// Check that we get an EOF from Read()
|
||||
timer := time.NewTimer(5e6)
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Errorf("No error received for shutdown.")
|
||||
case err := <-c.Err:
|
||||
timer.Stop()
|
||||
if err.String() != "irc.recv(): EOF" {
|
||||
t.Errorf("Expected EOF, got: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the connection no longer thinks it's connected
|
||||
if c.Connected {
|
||||
t.Errorf("Conn still thinks it's connected to the server.")
|
||||
}
|
||||
|
||||
// Verify that the "disconnected" event fired correctly
|
||||
if !flag {
|
||||
t.Errorf("Calling Close() didn't result in dispatch of disconnected event.")
|
||||
}
|
||||
|
||||
// TODO(fluffle): Try to work out a way of testing that the background
|
||||
// goroutines were *actually* stopped? Test m a bit more?
|
||||
}
|
||||
|
||||
// Practically the same as the above test, but shutdown is called implicitly
|
||||
// by recv() getting an EOF from the mock connection.
|
||||
func TestEOF(t *testing.T) {
|
||||
m, c := setUp(t)
|
||||
|
||||
// Shutdown won't clean things up unless we're "connected" already
|
||||
c.Connected = true
|
||||
|
||||
// Setup a mock event dispatcher to test correct triggering of "disconnected"
|
||||
flag := false
|
||||
c.Dispatcher = WasEventDispatched("disconnected", &flag)
|
||||
|
||||
// Simulate EOF from server
|
||||
m.Close()
|
||||
|
||||
// Check that we get an EOF from Read()
|
||||
timer := time.NewTimer(5e6)
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.Errorf("No error received for shutdown.")
|
||||
case err := <-c.Err:
|
||||
timer.Stop()
|
||||
if err.String() != "irc.recv(): EOF" {
|
||||
t.Errorf("Expected EOF, got: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the connection no longer thinks it's connected
|
||||
if c.Connected {
|
||||
t.Errorf("Conn still thinks it's connected to the server.")
|
||||
}
|
||||
|
||||
// Verify that the "disconnected" event fired correctly
|
||||
if !flag {
|
||||
t.Errorf("Calling Close() didn't result in dispatch of disconnected event.")
|
||||
}
|
||||
}
|
||||
|
||||
// Mock dispatcher to verify that events are triggered successfully
|
||||
type mockDispatcher func(string, ...interface{})
|
||||
|
||||
|
|
Loading…
Reference in New Issue