Changed send to be synchronous. Wrote session inner gorountines.
This commit is contained in:
@@ -5,10 +5,7 @@ import (
|
||||
"git.wisehodl.dev/jay/go-honeybee/honeybeetest"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestStartReader(t *testing.T) {
|
||||
@@ -88,198 +85,3 @@ func TestStartReader(t *testing.T) {
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStartWriter(t *testing.T) {
|
||||
t.Run("data from outgoing triggers write", func(t *testing.T) {
|
||||
conn, _, _, outgoingData := setupTestConnection(t, nil)
|
||||
defer conn.Close()
|
||||
|
||||
testData := []byte("test message")
|
||||
err := conn.Send(testData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
honeybeetest.ExpectWrite(t, outgoingData, websocket.TextMessage, testData)
|
||||
})
|
||||
|
||||
t.Run("multiple messages processed sequentially", func(t *testing.T) {
|
||||
conn, _, _, outgoingData := setupTestConnection(t, nil)
|
||||
defer conn.Close()
|
||||
|
||||
messages := [][]byte{[]byte("first"), []byte("second"), []byte("third")}
|
||||
for _, msg := range messages {
|
||||
err := conn.Send(msg)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, expected := range messages {
|
||||
honeybeetest.ExpectWrite(t, outgoingData, websocket.TextMessage, expected)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("write timeout disabled when zero", func(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
|
||||
config := &ConnectionConfig{WriteTimeout: 0}
|
||||
|
||||
outgoingData := make(chan honeybeetest.MockOutgoingData, 10)
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
|
||||
mockSocket.CloseFunc = func() error {
|
||||
mockSocket.Once.Do(func() {
|
||||
close(mockSocket.Closed)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
deadlineCalled := make(chan struct{}, 1)
|
||||
mockSocket.SetWriteDeadlineFunc = func(t time.Time) error {
|
||||
deadlineCalled <- struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
mockSocket.WriteMessageFunc = func(msgType int, data []byte) error {
|
||||
select {
|
||||
case outgoingData <- honeybeetest.MockOutgoingData{
|
||||
MsgType: msgType, Data: data}:
|
||||
case <-mockSocket.Closed:
|
||||
return io.EOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
conn, err := NewConnectionFromSocket(mockSocket, config, nil)
|
||||
assert.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
err = conn.Send([]byte("test"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Never(t, func() bool {
|
||||
select {
|
||||
case <-deadlineCalled:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, honeybeetest.NegativeTestTimeout, honeybeetest.TestTick,
|
||||
"SetWriteDeadline should not be called when timeout is zero")
|
||||
})
|
||||
|
||||
t.Run("write timeout sets deadline when positive", func(t *testing.T) {
|
||||
config := &ConnectionConfig{WriteTimeout: 30 * time.Millisecond}
|
||||
|
||||
outgoingData := make(chan honeybeetest.MockOutgoingData, 10)
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
|
||||
mockSocket.CloseFunc = func() error {
|
||||
mockSocket.Once.Do(func() {
|
||||
close(mockSocket.Closed)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
deadlineCalled := make(chan struct{}, 1)
|
||||
mockSocket.SetWriteDeadlineFunc = func(t time.Time) error {
|
||||
deadlineCalled <- struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
mockSocket.WriteMessageFunc = func(msgType int, data []byte) error {
|
||||
select {
|
||||
case outgoingData <- honeybeetest.MockOutgoingData{
|
||||
MsgType: msgType, Data: data}:
|
||||
case <-mockSocket.Closed:
|
||||
return io.EOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
conn, err := NewConnectionFromSocket(mockSocket, config, nil)
|
||||
assert.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
err = conn.Send([]byte("test"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
select {
|
||||
case <-deadlineCalled:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick,
|
||||
"SetWriteDeadline should be called when timeout is positive")
|
||||
})
|
||||
|
||||
t.Run("writer exits on deadline error", func(t *testing.T) {
|
||||
config := &ConnectionConfig{WriteTimeout: 1 * time.Millisecond}
|
||||
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
|
||||
mockSocket.CloseFunc = func() error {
|
||||
mockSocket.Once.Do(func() {
|
||||
close(mockSocket.Closed)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
mockSocket.SetWriteDeadlineFunc = func(t time.Time) error {
|
||||
return fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
conn, err := NewConnectionFromSocket(mockSocket, config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Send([]byte("test"))
|
||||
assert.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
select {
|
||||
case err := <-conn.Errors():
|
||||
return err != nil &&
|
||||
strings.Contains(err.Error(), "failed to set write deadline")
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
return conn.State() == StateClosed
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick)
|
||||
})
|
||||
|
||||
t.Run("writer exits on socket write error", func(t *testing.T) {
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
|
||||
writeErr := fmt.Errorf("write failed")
|
||||
mockSocket.WriteMessageFunc = func(msgType int, data []byte) error {
|
||||
return writeErr
|
||||
}
|
||||
|
||||
conn, err := NewConnectionFromSocket(mockSocket, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
err = conn.Send([]byte("test"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
select {
|
||||
case err := <-conn.Errors():
|
||||
return err == writeErr
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
return conn.State() == StateClosed
|
||||
}, honeybeetest.TestTimeout, honeybeetest.TestTick)
|
||||
})
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
Reference in New Issue
Block a user