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()
|
// 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()
|
// as calling sock.Close() will cause recv() to recieve EOF in readstring()
|
||||||
if conn.Connected {
|
if conn.Connected {
|
||||||
|
conn.Dispatcher.Dispatch("disconnected", conn, &Line{})
|
||||||
conn.Connected = false
|
conn.Connected = false
|
||||||
conn.sock.Close()
|
conn.sock.Close()
|
||||||
conn.cSend <- true
|
conn.cSend <- true
|
||||||
conn.cLoop <- true
|
conn.cLoop <- true
|
||||||
conn.Dispatcher.Dispatch("disconnected", conn, &Line{})
|
|
||||||
// reinit datastructures ready for next connection
|
// reinit datastructures ready for next connection
|
||||||
// do this here rather than after runLoop()'s for due to race
|
// do this here rather than after runLoop()'s for due to race
|
||||||
conn.initialise()
|
conn.initialise()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setUp(t *testing.T) (*mockNetConn, *Conn) {
|
func setUp(t *testing.T) (*mockNetConn, *Conn) {
|
||||||
|
@ -14,6 +15,89 @@ func setUp(t *testing.T) (*mockNetConn, *Conn) {
|
||||||
return m, c
|
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
|
// Mock dispatcher to verify that events are triggered successfully
|
||||||
type mockDispatcher func(string, ...interface{})
|
type mockDispatcher func(string, ...interface{})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue