transport: copy-on-intake in NewConnection/NewPool; add ConnectionConfig.Clone; remove SetDialer; dialer via config
This commit is contained in:
@@ -2,7 +2,6 @@ package honeybee
|
||||
|
||||
import (
|
||||
"git.wisehodl.dev/jay/go-honeybee/transport"
|
||||
"git.wisehodl.dev/jay/go-honeybee/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -18,7 +17,6 @@ type PoolConfig struct {
|
||||
ConnectionConfig transport.ConnectionConfig
|
||||
WorkerFactory WorkerFactory
|
||||
WorkerConfig WorkerConfig
|
||||
Dialer types.Dialer
|
||||
}
|
||||
|
||||
type PoolOption func(*PoolConfig) error
|
||||
@@ -124,13 +122,6 @@ func WithWorkerConfig(wc WorkerConfig) PoolOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithPoolDialer(d types.Dialer) PoolOption {
|
||||
return func(c *PoolConfig) error {
|
||||
c.Dialer = d
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithWorkerFactory(wf WorkerFactory) PoolOption {
|
||||
return func(c *PoolConfig) error {
|
||||
c.WorkerFactory = wf
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package honeybee
|
||||
|
||||
import (
|
||||
"git.wisehodl.dev/jay/go-honeybee/honeybeetest"
|
||||
"git.wisehodl.dev/jay/go-honeybee/transport"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
@@ -139,10 +138,3 @@ func TestValidatePoolConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithPoolDialer(t *testing.T) {
|
||||
mock := &honeybeetest.MockDialer{}
|
||||
conf, err := NewPoolConfig(WithPoolDialer(mock))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mock, conf.Dialer)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ type PoolPlugin struct {
|
||||
Inbox chan<- types.InboxMessage
|
||||
Events chan<- PoolEvent
|
||||
InboxCounter *atomic.Uint64
|
||||
Dialer types.Dialer
|
||||
ConnectionConfig transport.ConnectionConfig
|
||||
}
|
||||
|
||||
@@ -118,12 +117,19 @@ func NewPool(ctx context.Context, config *PoolConfig, handler slog.Handler,
|
||||
logger = slog.New(handler).With(slog.Any("component", c))
|
||||
}
|
||||
|
||||
var dialer types.Dialer
|
||||
if config.ConnectionConfig.Dialer != nil {
|
||||
dialer = config.ConnectionConfig.Dialer
|
||||
} else {
|
||||
dialer = transport.NewDialer()
|
||||
}
|
||||
|
||||
return &Pool{
|
||||
peers: make(map[string]*Peer),
|
||||
inbox: make(chan types.InboxMessage, config.InboxBufferSize),
|
||||
events: make(chan PoolEvent, config.EventsBufferSize),
|
||||
|
||||
dialer: transport.NewDialer(),
|
||||
dialer: dialer,
|
||||
config: config,
|
||||
handler: handler,
|
||||
logger: logger,
|
||||
@@ -195,13 +201,6 @@ func (p *Pool) PeerStats(id string) (PeerStats, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Pool) SetDialer(d types.Dialer) {
|
||||
if d == nil {
|
||||
panic("dialer cannot be nil")
|
||||
}
|
||||
p.dialer = d
|
||||
}
|
||||
|
||||
func (p *Pool) Close() {
|
||||
if p.logger != nil {
|
||||
p.logger.Info("closing")
|
||||
@@ -259,13 +258,14 @@ func (p *Pool) Connect(id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cc := p.config.ConnectionConfig.Clone()
|
||||
cc.Dialer = p.dialer
|
||||
|
||||
pool := PoolPlugin{
|
||||
Inbox: p.inbox,
|
||||
Events: p.events,
|
||||
InboxCounter: p.inboxCounter,
|
||||
Dialer: p.dialer,
|
||||
ConnectionConfig: p.config.ConnectionConfig,
|
||||
// ConnectionConfig is assigned by value — each worker gets its own copy
|
||||
ConnectionConfig: cc,
|
||||
}
|
||||
|
||||
p.wg.Go(func() {
|
||||
|
||||
+18
-5
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.wisehodl.dev/jay/go-honeybee/honeybeetest"
|
||||
"git.wisehodl.dev/jay/go-honeybee/transport"
|
||||
"git.wisehodl.dev/jay/go-honeybee/types"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -15,14 +16,20 @@ import (
|
||||
|
||||
func setupPool(t *testing.T) (*Pool, *honeybeetest.MockDialer) {
|
||||
t.Helper()
|
||||
pool, err := NewPool(context.Background(), nil, nil)
|
||||
assert.NoError(t, err)
|
||||
dialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return honeybeetest.NewMockSocket(), nil, nil
|
||||
},
|
||||
}
|
||||
pool.dialer = dialer
|
||||
cc := *transport.GetDefaultConnectionConfig()
|
||||
cc.Dialer = dialer
|
||||
pool, err := NewPool(context.Background(), &PoolConfig{
|
||||
InboxBufferSize: 256,
|
||||
EventsBufferSize: 10,
|
||||
ConnectionConfig: cc,
|
||||
WorkerConfig: *GetDefaultWorkerConfig(),
|
||||
}, nil)
|
||||
assert.NoError(t, err)
|
||||
return pool, dialer
|
||||
}
|
||||
|
||||
@@ -152,9 +159,15 @@ func TestPoolSend(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
pool, err := NewPool(context.Background(), nil, nil)
|
||||
cc := *transport.GetDefaultConnectionConfig()
|
||||
cc.Dialer = mockDialer
|
||||
pool, err := NewPool(context.Background(), &PoolConfig{
|
||||
InboxBufferSize: 256,
|
||||
EventsBufferSize: 10,
|
||||
ConnectionConfig: cc,
|
||||
WorkerConfig: *GetDefaultWorkerConfig(),
|
||||
}, nil)
|
||||
assert.NoError(t, err)
|
||||
pool.dialer = mockDialer
|
||||
|
||||
err = pool.Connect("wss://test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -67,6 +67,13 @@ func GetDefaultConnectionConfig() *ConnectionConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func (c ConnectionConfig) Clone() ConnectionConfig {
|
||||
if c.RequestHeader != nil {
|
||||
c.RequestHeader = c.RequestHeader.Clone()
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func applyConnectionOptions(config *ConnectionConfig, options ...ConnectionOption) error {
|
||||
for _, option := range options {
|
||||
if err := option(config); err != nil {
|
||||
|
||||
@@ -255,6 +255,26 @@ func TestValidateConnectionConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectionConfigClone(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Set("X-Test", "val")
|
||||
orig := ConnectionConfig{
|
||||
RequestHeader: header,
|
||||
WriteTimeout: 5 * time.Second,
|
||||
Retry: RetryConfig{Disabled: true},
|
||||
}
|
||||
|
||||
cloned := orig.Clone()
|
||||
|
||||
// values match
|
||||
assert.Equal(t, orig.WriteTimeout, cloned.WriteTimeout)
|
||||
assert.Equal(t, "val", cloned.RequestHeader.Get("X-Test"))
|
||||
|
||||
// header is a distinct copy
|
||||
cloned.RequestHeader.Set("X-Test", "mutated")
|
||||
assert.Equal(t, "val", orig.RequestHeader.Get("X-Test"))
|
||||
}
|
||||
|
||||
func TestWithConnectionDialer(t *testing.T) {
|
||||
mock := &honeybeetest.MockDialer{}
|
||||
conf, err := NewConnectionConfig(WithConnectionDialer(mock))
|
||||
|
||||
+17
-12
@@ -65,7 +65,7 @@ type Connection struct {
|
||||
url *url.URL
|
||||
dialer types.Dialer
|
||||
socket types.Socket
|
||||
config *ConnectionConfig
|
||||
config ConnectionConfig
|
||||
logger *slog.Logger
|
||||
|
||||
incoming chan []byte
|
||||
@@ -107,14 +107,20 @@ func NewConnection(ctx context.Context, urlStr string, config *ConnectionConfig,
|
||||
ctx = component.MustExtend(ctx, "connection")
|
||||
}
|
||||
|
||||
// Clone config to ensure full ownership of all fields.
|
||||
cc := config.Clone()
|
||||
if cc.Dialer == nil {
|
||||
cc.Dialer = NewDialer()
|
||||
}
|
||||
|
||||
conn := &Connection{
|
||||
url: url,
|
||||
dialer: NewDialer(),
|
||||
dialer: cc.Dialer,
|
||||
socket: nil,
|
||||
config: config,
|
||||
incoming: make(chan []byte, config.IncomingBufferSize),
|
||||
config: cc,
|
||||
incoming: make(chan []byte, cc.IncomingBufferSize),
|
||||
heartbeat: make(chan struct{}, 1),
|
||||
errors: make(chan error, config.ErrorsBufferSize),
|
||||
errors: make(chan error, cc.ErrorsBufferSize),
|
||||
incomingCount: &atomic.Uint64{},
|
||||
outgoingCount: &atomic.Uint64{},
|
||||
heartbeatCount: &atomic.Uint64{},
|
||||
@@ -151,14 +157,17 @@ func NewConnectionFromSocket(
|
||||
ctx = component.MustExtend(ctx, "connection")
|
||||
}
|
||||
|
||||
// Clone config to ensure full ownership of all fields.
|
||||
cc := config.Clone()
|
||||
|
||||
conn := &Connection{
|
||||
url: nil,
|
||||
dialer: nil,
|
||||
socket: socket,
|
||||
config: config,
|
||||
incoming: make(chan []byte, config.IncomingBufferSize),
|
||||
config: cc,
|
||||
incoming: make(chan []byte, cc.IncomingBufferSize),
|
||||
heartbeat: make(chan struct{}, 1),
|
||||
errors: make(chan error, config.ErrorsBufferSize),
|
||||
errors: make(chan error, cc.ErrorsBufferSize),
|
||||
incomingCount: &atomic.Uint64{},
|
||||
outgoingCount: &atomic.Uint64{},
|
||||
heartbeatCount: &atomic.Uint64{},
|
||||
@@ -311,10 +320,6 @@ func (c *Connection) Stats() ConnectionStats {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Connection) SetDialer(d types.Dialer) {
|
||||
c.dialer = d
|
||||
}
|
||||
|
||||
// ---------------------------/
|
||||
// Reader loop
|
||||
// -------------------------/
|
||||
|
||||
@@ -121,9 +121,13 @@ func TestNewConnection(t *testing.T) {
|
||||
|
||||
// Verify default config is used if nil is passed
|
||||
if tc.config == nil {
|
||||
assert.Equal(t, GetDefaultConnectionConfig(), conn.config)
|
||||
expected := *GetDefaultConnectionConfig()
|
||||
expected.Dialer = conn.config.Dialer // dialer resolved at construction
|
||||
assert.Equal(t, expected, conn.config)
|
||||
} else {
|
||||
assert.Equal(t, tc.config, conn.config)
|
||||
expected := *tc.config
|
||||
expected.Dialer = conn.config.Dialer
|
||||
assert.Equal(t, expected, conn.config)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -220,11 +224,19 @@ func TestNewConnectionFromSocket(t *testing.T) {
|
||||
assert.Equal(t, StateConnected, conn.state)
|
||||
assert.False(t, conn.closed)
|
||||
|
||||
// Verify default config is used if nil is passed
|
||||
// Verify default config is used if nil is passed.
|
||||
// CloseHandler is a func; exclude it from the struct comparison
|
||||
// (identity is verified separately via closeHandlerSet).
|
||||
gotCfg := conn.config
|
||||
gotCfg.CloseHandler = nil
|
||||
if tc.config == nil {
|
||||
assert.Equal(t, GetDefaultConnectionConfig(), conn.config)
|
||||
expected := *GetDefaultConnectionConfig()
|
||||
expected.CloseHandler = nil
|
||||
assert.Equal(t, expected, gotCfg)
|
||||
} else {
|
||||
assert.Equal(t, tc.config, conn.config)
|
||||
expected := *tc.config
|
||||
expected.CloseHandler = nil
|
||||
assert.Equal(t, expected, gotCfg)
|
||||
}
|
||||
|
||||
// Verify close handler was set if provided
|
||||
@@ -261,9 +273,6 @@ func TestConnect(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("connect succeeds and starts goroutines", func(t *testing.T) {
|
||||
conn, err := NewConnection(context.Background(), "ws://test", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
outgoingData := make(chan honeybeetest.MockOutgoingData, 10)
|
||||
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
@@ -277,7 +286,9 @@ func TestConnect(t *testing.T) {
|
||||
return mockSocket, nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
conn, err := NewConnection(context.Background(), "ws://test",
|
||||
&ConnectionConfig{Retry: RetryConfig{Disabled: true}, Dialer: mockDialer}, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.NoError(t, err)
|
||||
@@ -299,17 +310,6 @@ func TestConnect(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("connect retries on dial failure", func(t *testing.T) {
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 2,
|
||||
InitialDelay: 1 * time.Millisecond,
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
attemptCount := 0
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
@@ -320,7 +320,17 @@ func TestConnect(t *testing.T) {
|
||||
return honeybeetest.NewMockSocket(), nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 2,
|
||||
InitialDelay: 1 * time.Millisecond,
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
Dialer: mockDialer,
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.NoError(t, err)
|
||||
@@ -331,6 +341,11 @@ func TestConnect(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("connect fails after max retries", func(t *testing.T) {
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return nil, nil, fmt.Errorf("dial failed")
|
||||
},
|
||||
}
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 2,
|
||||
@@ -338,17 +353,11 @@ func TestConnect(t *testing.T) {
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
Dialer: mockDialer,
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return nil, nil, fmt.Errorf("dial failed")
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, "dial failed")
|
||||
@@ -356,18 +365,20 @@ func TestConnect(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("state transitions during connect", func(t *testing.T) {
|
||||
conn, err := NewConnection(context.Background(), "ws://test", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, StateDisconnected, conn.State())
|
||||
|
||||
stateDuringDial := StateDisconnected
|
||||
// conn captured after construction; closure safe because dialer runs during Connect
|
||||
var conn *Connection
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
stateDuringDial = conn.state
|
||||
return honeybeetest.NewMockSocket(), nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
var err error
|
||||
conn, err = NewConnection(context.Background(), "ws://test",
|
||||
&ConnectionConfig{Retry: RetryConfig{Disabled: true}, Dialer: mockDialer}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, StateDisconnected, conn.State())
|
||||
|
||||
conn.Connect(context.Background())
|
||||
|
||||
@@ -379,26 +390,24 @@ func TestConnect(t *testing.T) {
|
||||
|
||||
t.Run("close handler configured when provided", func(t *testing.T) {
|
||||
handlerSet := false
|
||||
config := &ConnectionConfig{
|
||||
CloseHandler: func(code int, text string) error {
|
||||
return nil
|
||||
},
|
||||
Retry: RetryConfig{Disabled: true},
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
mockSocket.SetCloseHandlerFunc = func(h func(int, string) error) {
|
||||
handlerSet = true
|
||||
}
|
||||
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return mockSocket, nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
config := &ConnectionConfig{
|
||||
CloseHandler: func(code int, text string) error {
|
||||
return nil
|
||||
},
|
||||
Retry: RetryConfig{Disabled: true},
|
||||
Dialer: mockDialer,
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
conn.Connect(context.Background())
|
||||
|
||||
@@ -409,17 +418,16 @@ func TestConnect(t *testing.T) {
|
||||
|
||||
t.Run("passes headers when configured", func(t *testing.T) {
|
||||
header := http.Header{"X-Custom": []string{"val"}}
|
||||
conf, _ := NewConnectionConfig(WithRequestHeader(header))
|
||||
conn, _ := NewConnection(context.Background(), "ws://test", conf, nil)
|
||||
|
||||
dialCalled := false
|
||||
conn.dialer = &honeybeetest.MockDialer{
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(ctx context.Context, url string, h http.Header) (types.Socket, *http.Response, error) {
|
||||
assert.Equal(t, "val", h.Get("X-Custom"))
|
||||
dialCalled = true
|
||||
return honeybeetest.NewMockSocket(), nil, nil
|
||||
},
|
||||
}
|
||||
conf, _ := NewConnectionConfig(WithRequestHeader(header), WithConnectionDialer(mockDialer))
|
||||
conn, _ := NewConnection(context.Background(), "ws://test", conf, nil)
|
||||
|
||||
err := conn.Connect(context.Background())
|
||||
|
||||
@@ -438,18 +446,18 @@ func TestConnectContextCancellation(t *testing.T) {
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
}
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
dialCount := atomic.Int32{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
conn.dialer = &honeybeetest.MockDialer{
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(ctx context.Context, _ string, _ http.Header) (types.Socket, *http.Response, error) {
|
||||
dialCount.Add(1)
|
||||
return nil, nil, fmt.Errorf("dial failed")
|
||||
},
|
||||
}
|
||||
config.Dialer = mockDialer
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
|
||||
+25
-29
@@ -28,16 +28,15 @@ func TestConnectLogging(t *testing.T) {
|
||||
t.Run("success", func(t *testing.T) {
|
||||
mockHandler := honeybeetest.NewMockSlogHandler()
|
||||
|
||||
conn, err := NewConnection(context.Background(), "ws://test", nil, mockHandler)
|
||||
assert.NoError(t, err)
|
||||
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return mockSocket, nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
conn, err := NewConnection(context.Background(), "ws://test",
|
||||
&ConnectionConfig{Retry: RetryConfig{Disabled: true}, Dialer: mockDialer}, mockHandler)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.NoError(t, err)
|
||||
@@ -58,6 +57,12 @@ func TestConnectLogging(t *testing.T) {
|
||||
t.Run("max retries failure", func(t *testing.T) {
|
||||
mockHandler := honeybeetest.NewMockSlogHandler()
|
||||
|
||||
dialErr := fmt.Errorf("dial error")
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return nil, nil, dialErr
|
||||
},
|
||||
}
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 2,
|
||||
@@ -65,19 +70,12 @@ func TestConnectLogging(t *testing.T) {
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
Dialer: mockDialer,
|
||||
}
|
||||
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, mockHandler)
|
||||
assert.NoError(t, err)
|
||||
|
||||
dialErr := fmt.Errorf("dial error")
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return nil, nil, dialErr
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.Error(t, err)
|
||||
|
||||
@@ -100,18 +98,6 @@ func TestConnectLogging(t *testing.T) {
|
||||
t.Run("success after retry", func(t *testing.T) {
|
||||
mockHandler := honeybeetest.NewMockSlogHandler()
|
||||
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 3,
|
||||
InitialDelay: 1 * time.Millisecond,
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
}
|
||||
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, mockHandler)
|
||||
assert.NoError(t, err)
|
||||
|
||||
attemptCount := 0
|
||||
dialErr := fmt.Errorf("dial error")
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
@@ -123,7 +109,18 @@ func TestConnectLogging(t *testing.T) {
|
||||
return honeybeetest.NewMockSocket(), nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
config := &ConnectionConfig{
|
||||
Retry: RetryConfig{
|
||||
MaxRetries: 3,
|
||||
InitialDelay: 1 * time.Millisecond,
|
||||
MaxDelay: 5 * time.Millisecond,
|
||||
JitterFactor: 0.0,
|
||||
},
|
||||
Dialer: mockDialer,
|
||||
}
|
||||
|
||||
conn, err := NewConnection(context.Background(), "ws://test", config, mockHandler)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.NoError(t, err)
|
||||
@@ -341,16 +338,15 @@ func TestLoggingDisabled(t *testing.T) {
|
||||
t.Run("nil logger produces no logs", func(t *testing.T) {
|
||||
mockHandler := honeybeetest.NewMockSlogHandler()
|
||||
|
||||
conn, err := NewConnection(context.Background(), "ws://test", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
mockDialer := &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return mockSocket, nil, nil
|
||||
},
|
||||
}
|
||||
conn.dialer = mockDialer
|
||||
conn, err := NewConnection(context.Background(), "ws://test",
|
||||
&ConnectionConfig{Retry: RetryConfig{Disabled: true}, Dialer: mockDialer}, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = conn.Connect(context.Background())
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -339,8 +339,6 @@ func connect(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn.SetDialer(pool.Dialer)
|
||||
return conn, conn.Connect(ctx)
|
||||
}
|
||||
|
||||
|
||||
+19
-19
@@ -66,7 +66,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
@@ -90,13 +90,13 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
|
||||
pool.Dialer = &honeybeetest.MockDialer{
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
pool.ConnectionConfig.Dialer = &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(context.Context, string, http.Header) (types.Socket, *http.Response, error) {
|
||||
return nil, nil, errors.New("connection refused")
|
||||
},
|
||||
}
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -144,15 +144,15 @@ func TestWorkerSession(t *testing.T) {
|
||||
_, _, pool := makeWorkerContext(t)
|
||||
|
||||
var dialCount atomic.Uint64
|
||||
pool.Dialer = &honeybeetest.MockDialer{
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
pool.ConnectionConfig.Dialer = &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(dialCtx context.Context, _ string, _ http.Header) (types.Socket, *http.Response, error) {
|
||||
dialCount.Add(1)
|
||||
<-dialCtx.Done()
|
||||
return nil, nil, dialCtx.Err()
|
||||
},
|
||||
}
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -170,14 +170,14 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
|
||||
pool.Dialer = &honeybeetest.MockDialer{
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
pool.ConnectionConfig.Dialer = &honeybeetest.MockDialer{
|
||||
DialContextFunc: func(dialCtx context.Context, _ string, _ http.Header) (types.Socket, *http.Response, error) {
|
||||
<-dialCtx.Done()
|
||||
return nil, nil, dialCtx.Err()
|
||||
},
|
||||
}
|
||||
cc, _ := transport.NewConnectionConfig(transport.WithRetryDisabled())
|
||||
pool.ConnectionConfig = *cc
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -205,7 +205,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
_, mockSocket, _, outgoingData := setupTestConnection(t)
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
@@ -256,7 +256,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
@@ -312,7 +312,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
}
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
_, mockSocket, incomingData, _ := setupTestConnection(t)
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -378,7 +378,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
var pongHandler func(string) error
|
||||
mockSocket, incomingData, _ := honeybeetest.SetupTestSocket(t)
|
||||
mockSocket.SetPongHandlerFunc = func(h func(string) error) { pongHandler = h }
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -440,7 +440,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
}
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
_, mockSocket, _, _ := setupTestConnection(t)
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -482,7 +482,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
_, mockSocket, incomingData, _ := setupTestConnection(t)
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
@@ -526,7 +526,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
_, mockSocket, incomingData, _ := setupTestConnection(t)
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() { w.Start(pool) })
|
||||
@@ -562,7 +562,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, ctx, cancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
@@ -608,7 +608,7 @@ func TestWorkerSession(t *testing.T) {
|
||||
w := makeWorker(t, workerCtx, workerCancel)
|
||||
_, events, pool := makeWorkerContext(t)
|
||||
mockSocket := honeybeetest.NewMockSocket()
|
||||
pool.Dialer = mockDialer(mockSocket)
|
||||
pool.ConnectionConfig.Dialer = mockDialer(mockSocket)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Go(func() {
|
||||
|
||||
Reference in New Issue
Block a user