notify/release_p0_test.go

234 lines
7.8 KiB
Go
Raw Normal View History

package notify
import (
"context"
"errors"
"net"
"strings"
"testing"
"time"
)
type releaseP0TestAddr string
func (a releaseP0TestAddr) Network() string { return "tcp" }
func (a releaseP0TestAddr) String() string { return string(a) }
func TestGetLogicalConnRuntimeSnapshotWithoutCompatClient(t *testing.T) {
server := NewServer().(*ServerCommon)
logical := &LogicalConn{server: server}
logical.setID("logical-only")
logical.setRemoteAddr(releaseP0TestAddr("127.0.0.1:28080"))
logical.markSessionStarted()
logical.markIdentityBound()
logical.markStreamTransport()
logical.markTransportAttached()
logical.setClientConnLastHeartbeatUnix(time.Now().Unix())
logical.markTransportDetached("read error", errors.New("boom"))
snapshot, err := GetLogicalConnRuntimeSnapshot(logical)
if err != nil {
t.Fatalf("GetLogicalConnRuntimeSnapshot failed: %v", err)
}
if got, want := snapshot.ClientID, "logical-only"; got != want {
t.Fatalf("ClientID = %q, want %q", got, want)
}
if got, want := snapshot.RemoteAddress, "127.0.0.1:28080"; got != want {
t.Fatalf("RemoteAddress = %q, want %q", got, want)
}
if !snapshot.Alive {
t.Fatal("Alive should be true")
}
if !snapshot.IdentityBound {
t.Fatal("IdentityBound should be true")
}
if !snapshot.UsesStreamTransport {
t.Fatal("UsesStreamTransport should be true")
}
if got, want := snapshot.TransportGeneration, uint64(1); got != want {
t.Fatalf("TransportGeneration = %d, want %d", got, want)
}
if got, want := snapshot.TransportDetachReason, "read error"; got != want {
t.Fatalf("TransportDetachReason = %q, want %q", got, want)
}
if got, want := snapshot.TransportDetachError, "boom"; got != want {
t.Fatalf("TransportDetachError = %q, want %q", got, want)
}
if !snapshot.ReattachEligible {
t.Fatal("ReattachEligible should be true")
}
}
func TestPendingWaitClosedErrorWithTransportDetail(t *testing.T) {
logical := &LogicalConn{}
logical.markSessionStarted()
logical.markStreamTransport()
logical.markTransportAttached()
logical.markTransportDetached("read error", errors.New("boom"))
err := pendingWaitClosedErrorWith(nil, transportDetachedErrorForLogical(logical))
if !errors.Is(err, errTransportDetached) {
t.Fatalf("pendingWaitClosedErrorWith = %v, want transport detached", err)
}
if !strings.Contains(err.Error(), "read error") || !strings.Contains(err.Error(), "boom") {
t.Fatalf("pendingWaitClosedErrorWith detail = %q, want read error and boom", err.Error())
}
}
func TestHandleDedicatedBulkReadErrorPreservesUnderlyingCause(t *testing.T) {
runtime := newBulkRuntime("dedicated-read-error")
bulk := newBulkHandle(context.Background(), runtime, clientFileScope(), BulkOpenRequest{
BulkID: "dedicated-read-error",
DataID: 1,
Dedicated: true,
Range: BulkRange{
Length: 1,
},
}, 0, nil, nil, 0, nil, nil, nil, nil, nil)
if err := runtime.register(clientFileScope(), bulk); err != nil {
t.Fatalf("register bulk failed: %v", err)
}
handleDedicatedBulkReadError(bulk, errors.New("boom read"))
resetErr := bulk.resetErrSnapshot()
if !errors.Is(resetErr, errTransportDetached) {
t.Fatalf("resetErr = %v, want transport detached", resetErr)
}
if !strings.Contains(resetErr.Error(), "dedicated bulk read error") || !strings.Contains(resetErr.Error(), "boom read") {
t.Fatalf("resetErr detail = %q, want dedicated read detail", resetErr.Error())
}
}
func TestRegisterAcceptedLogicalWithoutCompatClient(t *testing.T) {
server := NewServer().(*ServerCommon)
UseLegacySecurityServer(server)
logical := &LogicalConn{}
logical.setID("logical-only")
logical.setRemoteAddr(releaseP0TestAddr("127.0.0.1:28081"))
got := server.registerAcceptedLogical(logical)
if got != logical {
t.Fatalf("registerAcceptedLogical returned %p, want %p", got, logical)
}
if logical.compatClientConn() != nil {
t.Fatal("logical-only peer should not grow a compatibility client")
}
if logical.Server() != server {
t.Fatal("logical-only peer should inherit server owner")
}
if logical.msgEnSnapshot() == nil || logical.msgDeSnapshot() == nil {
t.Fatal("logical-only peer should inherit transport codec profile")
}
if found := server.GetLogicalConn("logical-only"); found != logical {
t.Fatalf("GetLogicalConn returned %p, want %p", found, logical)
}
if err := server.renameAcceptedLogical(logical, "logical-only-renamed"); err != nil {
t.Fatalf("renameAcceptedLogical failed: %v", err)
}
if found := server.GetLogicalConn("logical-only"); found != nil {
t.Fatalf("old logical id should be removed, got %p", found)
}
if found := server.GetLogicalConn("logical-only-renamed"); found != logical {
t.Fatalf("renamed logical lookup returned %p, want %p", found, logical)
}
server.removeLogical(logical)
if found := server.GetLogicalConn("logical-only-renamed"); found != nil {
t.Fatalf("removeLogical should delete logical-only peer, got %p", found)
}
}
func TestEncodeDecodeEnvelopeLogicalWithoutCompatClient(t *testing.T) {
server := NewServer().(*ServerCommon)
UseLegacySecurityServer(server)
logical := &LogicalConn{}
logical.setID("logical-codec")
server.registerAcceptedLogical(logical)
env := newSignalAckEnvelope(42)
payload, err := server.encodeEnvelopePayloadLogical(logical, env)
if err != nil {
t.Fatalf("encodeEnvelopePayloadLogical failed: %v", err)
}
decoded, err := server.decodeEnvelopeLogical(logical, payload)
if err != nil {
t.Fatalf("decodeEnvelopeLogical failed: %v", err)
}
if got, want := decoded.Kind, env.Kind; got != want {
t.Fatalf("decoded Kind = %v, want %v", got, want)
}
if got, want := decoded.ID, env.ID; got != want {
t.Fatalf("decoded ID = %d, want %d", got, want)
}
}
func TestAttachAcceptedLogicalTransportWithoutCompatClient(t *testing.T) {
server := NewServer().(*ServerCommon)
UseLegacySecurityServer(server)
logical := &LogicalConn{}
logical.setID("logical-transport")
left, right := net.Pipe()
defer left.Close()
defer right.Close()
if err := server.attachAcceptedLogicalTransport(logical, releaseP0TestAddr("127.0.0.1:28082"), left); err != nil {
t.Fatalf("attachAcceptedLogicalTransport failed: %v", err)
}
if logical.Server() != server {
t.Fatal("attachAcceptedLogicalTransport should bind server owner")
}
transport := logical.CurrentTransportConn()
if transport == nil {
t.Fatal("CurrentTransportConn should expose attached transport")
}
if !transport.Attached() || !transport.HasRuntimeConn() {
t.Fatalf("transport snapshot mismatch: %+v", transport)
}
inbound := logical.transportConnSnapshotForInbound(left, nil, transport.TransportGeneration(), true)
if inbound == nil {
t.Fatal("transportConnSnapshotForInbound should work without compatibility client")
}
if !inbound.Attached() {
t.Fatalf("inbound transport should be attached: %+v", inbound)
}
if stopFn := logical.stopFuncSnapshot(); stopFn != nil {
stopFn()
}
}
func TestResolveInboundSourceValueWithoutCompatClient(t *testing.T) {
server := NewServer().(*ServerCommon)
UseLegacySecurityServer(server)
logical := &LogicalConn{}
logical.setID("logical-source")
logical.setRemoteAddr(releaseP0TestAddr("127.0.0.1:28083"))
server.registerAcceptedLogical(logical)
resolved, transport := server.resolveInboundSourceValue(serverInboundSource{
Source: logical.ID(),
Logical: logical,
RemoteAddr: logical.RemoteAddr(),
TransportGeneration: 1,
})
if resolved != logical {
t.Fatalf("resolved logical = %p, want %p", resolved, logical)
}
if transport == nil {
t.Fatal("resolveInboundSourceValue should return transport snapshot for logical-only peer")
}
if transport.LogicalConn() != logical {
t.Fatalf("transport logical = %p, want %p", transport.LogicalConn(), logical)
}
if got, want := transportConnAddrString(transport.RemoteAddr()), transportConnAddrString(logical.RemoteAddr()); got != want {
t.Fatalf("transport remote addr = %q, want %q", got, want)
}
}