Skip to content

Commit 4adb2a7

Browse files
authoredJan 24, 2023
xds/resolver: cleanup tests to use real xDS client 2/n (#5952)
1 parent 52a8392 commit 4adb2a7

File tree

1 file changed

+105
-21
lines changed

1 file changed

+105
-21
lines changed
 

‎xds/internal/resolver/xds_resolver_test.go

+105-21
Original file line numberDiff line numberDiff line change
@@ -447,34 +447,118 @@ func (s) TestResolverResourceName(t *testing.T) {
447447
}
448448
}
449449

450-
// TestXDSResolverWatchCallbackAfterClose tests the case where a service update
451-
// from the underlying xdsClient is received after the resolver is closed.
452-
func (s) TestXDSResolverWatchCallbackAfterClose(t *testing.T) {
453-
xdsR, xdsC, tcc, cancel := testSetup(t, setupOpts{target: target})
454-
defer cancel()
450+
// TestResolverWatchCallbackAfterClose tests the case where a service update
451+
// from the underlying xDS client is received after the resolver is closed, and
452+
// verifies that the update is not propagated to the ClientConn.
453+
func (s) TestResolverWatchCallbackAfterClose(t *testing.T) {
454+
// Setup the management server that synchronizes with the test goroutine
455+
// using two channels. The management server signals the test goroutine when
456+
// it receives a discovery request for a route configuration resource. And
457+
// the test goroutine signals the management server when the resolver is
458+
// closed.
459+
waitForRouteConfigDiscoveryReqCh := make(chan struct{})
460+
waitForResolverCloseCh := make(chan struct{})
461+
mgmtServer, err := e2e.StartManagementServer(e2e.ManagementServerOptions{
462+
OnStreamRequest: func(_ int64, req *v3discoverypb.DiscoveryRequest) error {
463+
if req.GetTypeUrl() == version.V3RouteConfigURL {
464+
close(waitForRouteConfigDiscoveryReqCh)
465+
<-waitForResolverCloseCh
466+
}
467+
return nil
468+
},
469+
})
470+
if err != nil {
471+
t.Fatalf("Failed to start xDS management server: %v", err)
472+
}
473+
defer mgmtServer.Stop()
474+
475+
// Create a bootstrap configuration specifying the above management server.
476+
nodeID := uuid.New().String()
477+
cleanup, err := xdsbootstrap.CreateFile(xdsbootstrap.Options{
478+
NodeID: nodeID,
479+
ServerURI: mgmtServer.Address,
480+
Version: xdsbootstrap.TransportV3,
481+
})
482+
if err != nil {
483+
t.Fatal(err)
484+
}
485+
defer cleanup()
455486

487+
// Configure listener and route configuration resources on the management
488+
// server.
489+
const serviceName = "my-service-client-side-xds"
490+
rdsName := "route-" + serviceName
491+
cdsName := "cluster-" + serviceName
492+
resources := e2e.UpdateOptions{
493+
NodeID: nodeID,
494+
Listeners: []*v3listenerpb.Listener{e2e.DefaultClientListener(serviceName, rdsName)},
495+
Routes: []*v3routepb.RouteConfiguration{e2e.DefaultRouteConfig(rdsName, serviceName, cdsName)},
496+
SkipValidation: true,
497+
}
456498
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
457499
defer cancel()
458-
waitForWatchListener(ctx, t, xdsC, targetStr)
459-
xdsC.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{RouteConfigName: routeStr, HTTPFilters: routerFilterList}, nil)
460-
waitForWatchRouteConfig(ctx, t, xdsC, routeStr)
500+
if err := mgmtServer.Update(ctx, resources); err != nil {
501+
t.Fatal(err)
502+
}
461503

462-
// Call the watchAPI callback after closing the resolver, and make sure no
463-
// update is triggerred on the ClientConn.
464-
xdsR.Close()
465-
xdsC.InvokeWatchRouteConfigCallback("", xdsresource.RouteConfigUpdate{
466-
VirtualHosts: []*xdsresource.VirtualHost{
467-
{
468-
Domains: []string{targetStr},
469-
Routes: []*xdsresource.Route{{Prefix: newStringP(""), WeightedClusters: map[string]xdsresource.WeightedCluster{cluster: {Weight: 1}}}},
470-
},
471-
},
472-
}, nil)
504+
tcc, rClose := buildResolverForTarget(t, resolver.Target{URL: *testutils.MustParseURL("xds:///" + serviceName)})
505+
defer rClose()
506+
507+
// Wait for a discovery request for a route configuration resource.
508+
select {
509+
case <-waitForRouteConfigDiscoveryReqCh:
510+
case <-ctx.Done():
511+
t.Fatal("Timeout when waiting for a discovery request for a route configuration resource")
512+
}
513+
514+
// Close the resolver and unblock the management server.
515+
rClose()
516+
close(waitForResolverCloseCh)
473517

518+
// Verify that the update from the management server is not propagated to
519+
// the ClientConn. The xDS resolver, once closed, is expected to drop
520+
// updates from the xDS client.
474521
sCtx, sCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
475522
defer sCancel()
476-
if gotVal, gotErr := tcc.stateCh.Receive(sCtx); gotErr != context.DeadlineExceeded {
477-
t.Fatalf("ClientConn.UpdateState called after xdsResolver is closed: %v", gotVal)
523+
if _, err := tcc.stateCh.Receive(sCtx); err != context.DeadlineExceeded {
524+
t.Fatalf("ClientConn received an update from the resolver that was closed: %v", err)
525+
}
526+
}
527+
528+
// TestResolverCloseClosesXDSClient tests that the xDS resolver's Close method
529+
// closes the xDS client.
530+
func (s) TestResolverCloseClosesXDSClient(t *testing.T) {
531+
bootstrapCfg := &bootstrap.Config{
532+
XDSServer: &bootstrap.ServerConfig{
533+
ServerURI: "dummy-management-server-address",
534+
Creds: grpc.WithTransportCredentials(insecure.NewCredentials()),
535+
TransportAPI: version.TransportV3,
536+
},
537+
}
538+
539+
// Override xDS client creation to use bootstrap configuration pointing to a
540+
// dummy management server. Also close a channel when the returned xDS
541+
// client is closed.
542+
closeCh := make(chan struct{})
543+
origNewClient := newXDSClient
544+
newXDSClient = func() (xdsclient.XDSClient, func(), error) {
545+
c, cancel, err := xdsclient.NewWithConfigForTesting(bootstrapCfg, defaultTestTimeout, defaultTestTimeout)
546+
return c, func() {
547+
close(closeCh)
548+
cancel()
549+
}, err
550+
}
551+
defer func() {
552+
newXDSClient = origNewClient
553+
}()
554+
555+
_, rClose := buildResolverForTarget(t, resolver.Target{URL: *testutils.MustParseURL("xds:///my-service-client-side-xds")})
556+
rClose()
557+
558+
select {
559+
case <-closeCh:
560+
case <-time.After(defaultTestTimeout):
561+
t.Fatal("Timeout when waiting for xDS client to be closed")
478562
}
479563
}
480564

0 commit comments

Comments
 (0)