notify/client_reconnect_test.go

159 lines
4.6 KiB
Go
Raw Normal View History

package notify
import (
"context"
"errors"
"net"
"testing"
)
func TestReconnectClientRejectsDirectConnSource(t *testing.T) {
client := NewClient().(*ClientCommon)
secret := []byte("0123456789abcdef0123456789abcdef")
left, right := net.Pipe()
defer left.Close()
defer right.Close()
server := newRunningPeerAttachServerForTest(t, func(server *ServerCommon) {
server.SetSecretKey(secret)
})
bootstrapPeerAttachConnForTest(t, server, right)
client.SetSecretKey(secret)
if err := client.ConnectByConn(left); err != nil {
t.Fatalf("ConnectByConn failed: %v", err)
}
client.setByeFromServer(true)
if err := client.Stop(); err != nil {
t.Fatalf("Stop failed: %v", err)
}
err := ReconnectClient(context.Background(), client)
if !errors.Is(err, errClientReconnectSourceUnavailable) {
t.Fatalf("ReconnectClient error = %v, want %v", err, errClientReconnectSourceUnavailable)
}
}
func TestReconnectClientWithFactorySource(t *testing.T) {
client := NewClient().(*ClientCommon)
secret := []byte("0123456789abcdef0123456789abcdef")
client.SetSecretKey(secret)
server := newRunningPeerAttachServerForTest(t, func(server *ServerCommon) {
server.SetSecretKey(secret)
})
dialCount := 0
var peers []net.Conn
dialFn := func(context.Context) (net.Conn, error) {
dialCount++
left, right := net.Pipe()
peers = append(peers, right)
bootstrapPeerAttachConnForTest(t, server, right)
return left, nil
}
if err := client.ConnectByFactory(context.Background(), dialFn); err != nil {
t.Fatalf("ConnectByFactory failed: %v", err)
}
client.setByeFromServer(true)
if err := client.Stop(); err != nil {
t.Fatalf("Stop failed: %v", err)
}
before, err := GetClientRuntimeSnapshot(client)
if err != nil {
t.Fatalf("GetClientRuntimeSnapshot before reconnect failed: %v", err)
}
if !before.CanReconnect || before.ConnectSource != clientConnectSourceFactory {
t.Fatalf("unexpected reconnect snapshot before reconnect: %+v", before)
}
if err := ReconnectClient(context.Background(), client); err != nil {
t.Fatalf("ReconnectClient failed: %v", err)
}
after, err := GetClientRuntimeSnapshot(client)
if err != nil {
t.Fatalf("GetClientRuntimeSnapshot after reconnect failed: %v", err)
}
if !after.Alive || !after.HasRuntimeConn || !after.CanReconnect {
t.Fatalf("unexpected reconnect snapshot after reconnect: %+v", after)
}
if got, want := dialCount, 2; got != want {
t.Fatalf("dial count mismatch: got %d want %d", got, want)
}
client.setByeFromServer(true)
if err := client.Stop(); err != nil {
t.Fatalf("final Stop failed: %v", err)
}
for _, peer := range peers {
_ = peer.Close()
}
}
func TestReconnectClientWithRetryRecordsRetryState(t *testing.T) {
client := NewClient().(*ClientCommon)
secret := []byte("0123456789abcdef0123456789abcdef")
client.SetSecretKey(secret)
server := newRunningPeerAttachServerForTest(t, func(server *ServerCommon) {
server.SetSecretKey(secret)
})
dialCount := 0
wantErr := errors.New("dial failed once")
var peers []net.Conn
dialFn := func(context.Context) (net.Conn, error) {
dialCount++
if dialCount == 2 {
return nil, wantErr
}
left, right := net.Pipe()
peers = append(peers, right)
bootstrapPeerAttachConnForTest(t, server, right)
return left, nil
}
if err := client.ConnectByFactory(context.Background(), dialFn); err != nil {
t.Fatalf("ConnectByFactory failed: %v", err)
}
client.setByeFromServer(true)
if err := client.Stop(); err != nil {
t.Fatalf("Stop failed: %v", err)
}
if err := ReconnectClientWithRetry(context.Background(), client, &ConnectRetryOptions{
MaxAttempts: 3,
BaseDelay: 0,
MaxDelay: 0,
}); err != nil {
t.Fatalf("ReconnectClientWithRetry failed: %v", err)
}
snapshot, err := GetClientRuntimeSnapshot(client)
if err != nil {
t.Fatalf("GetClientRuntimeSnapshot failed: %v", err)
}
if got, want := snapshot.Retry.RetryEventTotal, uint64(1); got != want {
t.Fatalf("retry events mismatch: got %d want %d", got, want)
}
if got, want := snapshot.Retry.LastRetryAttempt, 1; got != want {
t.Fatalf("last retry attempt mismatch: got %d want %d", got, want)
}
if got, want := snapshot.Retry.LastRetryError, wantErr.Error(); got != want {
t.Fatalf("last retry error mismatch: got %q want %q", got, want)
}
if snapshot.Retry.LastResultError != "" {
t.Fatalf("last result error should be empty, got %q", snapshot.Retry.LastResultError)
}
if got, want := dialCount, 3; got != want {
t.Fatalf("dial count mismatch: got %d want %d", got, want)
}
client.setByeFromServer(true)
if err := client.Stop(); err != nil {
t.Fatalf("final Stop failed: %v", err)
}
for _, peer := range peers {
_ = peer.Close()
}
}