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) } }