Skip to content

Commit 3610578

Browse files
committed
add ReResolution test
1 parent 8420f3f commit 3610578

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

internal/xds/balancer/clusterimpl/tests/balancer_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,3 +663,114 @@ func (s) TestLRSLogicalDNS(t *testing.T) {
663663
t.Fatalf("Server did not receive load due to error: %v", err)
664664
}
665665
}
666+
667+
// TestReResolution verifies that when a SubConn turns transient failure,
668+
// re-resolution is triggered.
669+
func (s) TestReResolution(t *testing.T) {
670+
// Create an xDS management server that serves ADS requests.
671+
mgmtServer := e2e.StartManagementServer(t, e2e.ManagementServerOptions{})
672+
673+
// Create bootstrap configuration pointing to the above management server.
674+
nodeID := uuid.New().String()
675+
bc := e2e.DefaultBootstrapContents(t, nodeID, mgmtServer.Address)
676+
testutils.CreateBootstrapFileForTesting(t, bc)
677+
678+
// Create an xDS resolver with the above bootstrap configuration.
679+
if internal.NewXDSResolverWithConfigForTesting == nil {
680+
t.Fatalf("internal.NewXDSResolverWithConfigForTesting is nil")
681+
}
682+
resolverBuilder, err := internal.NewXDSResolverWithConfigForTesting.(func([]byte) (resolver.Builder, error))(bc)
683+
if err != nil {
684+
t.Fatalf("Failed to create xDS resolver for testing: %v", err)
685+
}
686+
687+
// Start two server backends exposing the test service.
688+
backend1 := stubserver.StartTestService(t, nil)
689+
defer backend1.Stop()
690+
backend1Host, backend1Port := hostAndPortFromAddress(t, backend1.Address)
691+
692+
backend2 := stubserver.StartTestService(t, nil)
693+
defer backend2.Stop()
694+
backend2Host, backend2Port := hostAndPortFromAddress(t, backend2.Address)
695+
696+
// Configure the xDS management server with Logical DNS cluster pointing to backend1.
697+
const serviceName = "test-xds-service"
698+
resources := e2e.DefaultClientResources(e2e.ResourceParams{
699+
DialTarget: serviceName,
700+
NodeID: nodeID,
701+
Host: backend1Host,
702+
Port: backend1Port,
703+
})
704+
resources.Clusters = []*v3clusterpb.Cluster{
705+
e2e.ClusterResourceWithOptions(e2e.ClusterOptions{
706+
ClusterName: "cluster-" + serviceName,
707+
Type: e2e.ClusterTypeLogicalDNS,
708+
DNSHostName: backend1Host,
709+
DNSPort: backend1Port,
710+
}),
711+
}
712+
resources.Endpoints = nil
713+
714+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
715+
defer cancel()
716+
717+
if err := mgmtServer.Update(ctx, resources); err != nil {
718+
t.Fatal(err)
719+
}
720+
721+
// Create a ClientConn and make a successful RPC.
722+
cc, err := grpc.NewClient(fmt.Sprintf("xds:///%s", serviceName), grpc.WithTransportCredentials(insecure.NewCredentials()),
723+
grpc.WithResolvers(resolverBuilder),
724+
)
725+
if err != nil {
726+
t.Fatalf("failed to dial local test server: %v", err)
727+
}
728+
defer cc.Close()
729+
730+
cc.Connect()
731+
client := testgrpc.NewTestServiceClient(cc)
732+
testutils.AwaitState(ctx, t, cc, connectivity.Ready)
733+
734+
// Perform initial RPC to backend1, expect success.
735+
var peer peer.Peer
736+
if _, err := client.EmptyCall(ctx, &testpb.Empty{}, grpc.Peer(&peer)); err != nil {
737+
t.Fatalf("Expected initial rpc to backend1 to succeed, got: %v", err)
738+
}
739+
740+
// Verify that the request was sent to backend 1.
741+
if got, want := peer.Addr.String(), backend1.Address; got != want {
742+
t.Fatalf("EmptyCall() routed to backend %q, want %q", peer.Addr, backend1.Address)
743+
}
744+
745+
// Stop backend1 to simulate failure.
746+
backend1.Stop()
747+
748+
// Update management server with Logical DNS cluster pointing to backend2 now.
749+
resources.Clusters[0] = e2e.ClusterResourceWithOptions(e2e.ClusterOptions{
750+
ClusterName: "cluster-" + serviceName,
751+
Type: e2e.ClusterTypeLogicalDNS,
752+
DNSHostName: backend2Host,
753+
DNSPort: backend2Port,
754+
})
755+
756+
if err := mgmtServer.Update(ctx, resources); err != nil {
757+
t.Fatalf("failed to update management server resources to backend2: %v", err)
758+
}
759+
760+
// Wait for client to re-resolve and start routing to backend2.
761+
for {
762+
if ctx.Err() != nil {
763+
t.Fatalf("Timed out while waiting for RPC to be routed to backend2: %v", ctx.Err())
764+
}
765+
if _, err := client.EmptyCall(ctx, &testpb.Empty{}, grpc.Peer(&peer), grpc.WaitForReady(true)); err != nil {
766+
t.Logf("RPC failed, possibly during switchover: %v", err)
767+
time.Sleep(100 * time.Millisecond)
768+
continue
769+
}
770+
if peer.Addr.String() == backend2.Address {
771+
break
772+
}
773+
t.Logf("RPC routed to %q, waiting for %q", peer.Addr.String(), backend2.Address)
774+
time.Sleep(100 * time.Millisecond)
775+
}
776+
}

0 commit comments

Comments
 (0)