@@ -447,34 +447,118 @@ func (s) TestResolverResourceName(t *testing.T) {
447
447
}
448
448
}
449
449
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 ()
455
486
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
+ }
456
498
ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
457
499
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
+ }
461
503
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 )
473
517
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.
474
521
sCtx , sCancel := context .WithTimeout (ctx , defaultTestShortTimeout )
475
522
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" )
478
562
}
479
563
}
480
564
0 commit comments