Skip to content

Commit

Permalink
test: Add unit test for channel state waiting for first resolver upda…
Browse files Browse the repository at this point in the history
…te (#7768)
  • Loading branch information
janardhanvissa authored Nov 19, 2024
1 parent 36d5ca0 commit 1e7fde9
Showing 1 changed file with 77 additions and 0 deletions.
77 changes: 77 additions & 0 deletions test/clientconn_state_transition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ import (
"google.golang.org/grpc/internal/balancer/stub"
"google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/stubserver"
"google.golang.org/grpc/internal/testutils"
testgrpc "google.golang.org/grpc/interop/grpc_testing"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/resolver/manual"
)
Expand Down Expand Up @@ -616,3 +618,78 @@ func (s) TestConnectivityStateSubscriber(t *testing.T) {
}
}
}

// TestChannelStateWaitingForFirstResolverUpdate verifies the initial
// state of the channel when a manual name resolver doesn't provide any updates.
func (s) TestChannelStateWaitingForFirstResolverUpdate(t *testing.T) {
t.Skip("The channel remains in IDLE until the LB policy updates the state to CONNECTING. This is a bug and the channel should transition to CONNECTING as soon as Connect() is called. See issue #7686.")

backend := stubserver.StartTestService(t, nil)
defer backend.Stop()

mr := manual.NewBuilderWithScheme("e2e-test")
defer mr.Close()

cc, err := grpc.NewClient(mr.Scheme()+":///", grpc.WithResolvers(mr), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("Failed to create new client: %v", err)
}
defer cc.Close()

if state := cc.GetState(); state != connectivity.Idle {
t.Fatalf("Expected initial state to be IDLE, got %v", state)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()

// The channel should transition to CONNECTING automatically when Connect()
// is called.
cc.Connect()
testutils.AwaitState(ctx, t, cc, connectivity.Connecting)

// Verify that the channel remains in CONNECTING state for a short time.
shortCtx, shortCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
defer shortCancel()
testutils.AwaitNoStateChange(shortCtx, t, cc, connectivity.Connecting)
}

func (s) TestChannelStateTransitionWithRPC(t *testing.T) {
t.Skip("The channel remains in IDLE until the LB policy updates the state to CONNECTING. This is a bug and the channel should transition to CONNECTING as soon as an RPC call is made. See issue #7686.")

backend := stubserver.StartTestService(t, nil)
defer backend.Stop()

mr := manual.NewBuilderWithScheme("e2e-test")
defer mr.Close()

cc, err := grpc.NewClient(mr.Scheme()+":///", grpc.WithResolvers(mr), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("Failed to create new client: %v", err)
}
defer cc.Close()

if state := cc.GetState(); state != connectivity.Idle {
t.Fatalf("Expected initial state to be IDLE, got %v", state)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()

// Make an RPC call to transition the channel to CONNECTING.
go func() {
_, err := testgrpc.NewTestServiceClient(cc).EmptyCall(ctx, &testgrpc.Empty{})
if err == nil {
t.Errorf("Expected RPC to fail, but it succeeded")
}
}()

// The channel should transition to CONNECTING automatically when an RPC
// is made.
testutils.AwaitState(ctx, t, cc, connectivity.Connecting)

// The channel remains in CONNECTING state for a short time.
shortCtx, shortCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
defer shortCancel()
testutils.AwaitNoStateChange(shortCtx, t, cc, connectivity.Connecting)
}

0 comments on commit 1e7fde9

Please sign in to comment.