mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-29 20:24:11 +08:00
127 lines
2.8 KiB
Go
127 lines
2.8 KiB
Go
|
package fastcgi
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func TestLoadbalancingDialer(t *testing.T) {
|
||
|
// given
|
||
|
runs := 100
|
||
|
mockDialer1 := new(mockDialer)
|
||
|
mockDialer2 := new(mockDialer)
|
||
|
|
||
|
dialer := &loadBalancingDialer{dialers: []dialer{mockDialer1, mockDialer2}}
|
||
|
|
||
|
// when
|
||
|
for i := 0; i < runs; i++ {
|
||
|
client, err := dialer.Dial()
|
||
|
dialer.Close(client)
|
||
|
|
||
|
if err != nil {
|
||
|
t.Errorf("Expected error to be nil")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// then
|
||
|
if mockDialer1.dialCalled != mockDialer2.dialCalled && mockDialer1.dialCalled != 50 {
|
||
|
t.Errorf("Expected dialer to call Dial() on multiple backend dialers %d times [actual: %d, %d]", 50, mockDialer1.dialCalled, mockDialer2.dialCalled)
|
||
|
}
|
||
|
|
||
|
if mockDialer1.closeCalled != mockDialer2.closeCalled && mockDialer1.closeCalled != 50 {
|
||
|
t.Errorf("Expected dialer to call Close() on multiple backend dialers %d times [actual: %d, %d]", 50, mockDialer1.closeCalled, mockDialer2.closeCalled)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestLoadBalancingDialerShouldReturnDialerAwareClient(t *testing.T) {
|
||
|
// given
|
||
|
mockDialer1 := new(mockDialer)
|
||
|
dialer := &loadBalancingDialer{dialers: []dialer{mockDialer1}}
|
||
|
|
||
|
// when
|
||
|
client, err := dialer.Dial()
|
||
|
|
||
|
// then
|
||
|
if err != nil {
|
||
|
t.Errorf("Expected error to be nil")
|
||
|
}
|
||
|
|
||
|
if awareClient, ok := client.(*dialerAwareClient); !ok {
|
||
|
t.Error("Expected dialer to wrap client")
|
||
|
} else {
|
||
|
if awareClient.dialer != mockDialer1 {
|
||
|
t.Error("Expected wrapped client to have reference to dialer")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestLoadBalancingDialerShouldUnderlyingReturnDialerError(t *testing.T) {
|
||
|
// given
|
||
|
mockDialer1 := new(errorReturningDialer)
|
||
|
dialer := &loadBalancingDialer{dialers: []dialer{mockDialer1}}
|
||
|
|
||
|
// when
|
||
|
_, err := dialer.Dial()
|
||
|
|
||
|
// then
|
||
|
if err.Error() != "Error during dial" {
|
||
|
t.Errorf("Expected 'Error during dial', got: '%s'", err.Error())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestLoadBalancingDialerShouldCloseClient(t *testing.T) {
|
||
|
// given
|
||
|
mockDialer1 := new(mockDialer)
|
||
|
mockDialer2 := new(mockDialer)
|
||
|
|
||
|
dialer := &loadBalancingDialer{dialers: []dialer{mockDialer1, mockDialer2}}
|
||
|
client, _ := dialer.Dial()
|
||
|
|
||
|
// when
|
||
|
err := dialer.Close(client)
|
||
|
|
||
|
// then
|
||
|
if err != nil {
|
||
|
t.Error("Expected error not to occur")
|
||
|
}
|
||
|
|
||
|
// load balancing starts from index 1
|
||
|
if mockDialer2.client != client {
|
||
|
t.Errorf("Expected Close() to be called on referenced dialer")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type mockDialer struct {
|
||
|
dialCalled int
|
||
|
closeCalled int
|
||
|
client Client
|
||
|
}
|
||
|
|
||
|
type mockClient struct {
|
||
|
Client
|
||
|
}
|
||
|
|
||
|
func (m *mockDialer) Dial() (Client, error) {
|
||
|
m.dialCalled++
|
||
|
return mockClient{Client: &FCGIClient{}}, nil
|
||
|
}
|
||
|
|
||
|
func (m *mockDialer) Close(c Client) error {
|
||
|
m.client = c
|
||
|
m.closeCalled++
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type errorReturningDialer struct {
|
||
|
client Client
|
||
|
}
|
||
|
|
||
|
func (m *errorReturningDialer) Dial() (Client, error) {
|
||
|
return mockClient{Client: &FCGIClient{}}, errors.New("Error during dial")
|
||
|
}
|
||
|
|
||
|
func (m *errorReturningDialer) Close(c Client) error {
|
||
|
m.client = c
|
||
|
return errors.New("Error during close")
|
||
|
}
|