@@ -2614,6 +2614,58 @@ public void cdsResourceDeleted() {
26142614 verifySubscribedResourcesMetadataSizes (0 , 1 , 0 , 0 );
26152615 }
26162616
2617+ @ Test
2618+ public void cdsResourcesDelete_edsUnsubscribed () {
2619+ Assume .assumeFalse (ignoreResourceDeletion ());
2620+
2621+ List <String > subscribedResourceNames = ImmutableList .of ("A" );
2622+ xdsClient .watchXdsResource (XdsClusterResource .getInstance (), "A" , cdsResourceWatcher );
2623+ xdsClient .watchXdsResource (XdsEndpointResource .getInstance (), "A.1" , edsResourceWatcher );
2624+ DiscoveryRpcCall call = resourceDiscoveryCalls .poll ();
2625+ assertThat (call ).isNotNull ();
2626+ verifyResourceMetadataRequested (CDS , "A" );
2627+ verifyResourceMetadataRequested (EDS , "A.1" );
2628+ verifySubscribedResourcesMetadataSizes (0 , 1 , 0 , 1 );
2629+
2630+ // CDS -> {A}, version 1
2631+ ImmutableMap <String , Any > resourcesV1 = ImmutableMap .of (
2632+ "A" , Any .pack (mf .buildEdsCluster ("A" , "A.1" , "round_robin" , null , null , false , null ,
2633+ "envoy.transport_sockets.tls" , null , null
2634+ )));
2635+ call .sendResponse (CDS , resourcesV1 .values ().asList (), VERSION_1 , "0000" );
2636+ // {A, B} -> ACK, version 1
2637+ verifyResourceMetadataAcked (CDS , "A" , resourcesV1 .get ("A" ), VERSION_1 , TIME_INCREMENT );
2638+ call .verifyRequest (CDS , subscribedResourceNames , VERSION_1 , "0000" , NODE );
2639+
2640+ // EDS -> {A.1}, version 1
2641+ List <Message > dropOverloads = ImmutableList .of ();
2642+ List <Message > endpointsV1 = ImmutableList .of (lbEndpointHealthy );
2643+ ImmutableMap <String , Any > resourcesV11 = ImmutableMap .of (
2644+ "A.1" , Any .pack (mf .buildClusterLoadAssignment ("A.1" , endpointsV1 , dropOverloads )));
2645+ call .sendResponse (EDS , resourcesV11 .values ().asList (), VERSION_1 , "0000" );
2646+ // {A.1} -> ACK, version 1
2647+ verifyResourceMetadataAcked (EDS , "A.1" , resourcesV11 .get ("A.1" ), VERSION_1 , TIME_INCREMENT * 2 );
2648+ verify (cdsResourceWatcher , times (1 )).onChanged (any ());
2649+
2650+ // Empty CDS response deletes the cluster.
2651+ call .sendResponse (CDS , Collections .<Any >emptyList (), VERSION_2 , "0001" );
2652+ call .verifyRequest (CDS , "A" , VERSION_2 , "0001" , NODE );
2653+ verify (cdsResourceWatcher ).onResourceDoesNotExist ("A" );
2654+ verifyResourceMetadataDoesNotExist (CDS , "A" );
2655+ verifySubscribedResourcesMetadataSizes (0 , 1 , 0 , 1 );
2656+ // Empty CDS leads to EDS resource "A.1" unsubscribed.
2657+ xdsClient .cancelXdsResourceWatch (XdsEndpointResource .getInstance (), "A.1" , edsResourceWatcher );
2658+ verifySubscribedResourcesMetadataSizes (0 , 1 , 0 , 0 );
2659+
2660+ // Send any EDS will not trigger any ACK/NACK response
2661+ Any updatedClusterLoadAssignment = Any .pack (mf .buildClusterLoadAssignment ("A.1" ,
2662+ ImmutableList .of (mf .buildLocalityLbEndpoints ("region2" , "zone2" , "subzone2" ,
2663+ mf .buildLbEndpoint ("172.44.2.2" , 8000 , "unknown" , 3 ), 2 , 0 )),
2664+ ImmutableList .<Message >of ()));
2665+ call .sendResponse (EDS , updatedClusterLoadAssignment , VERSION_2 , "0001" );
2666+ call .verifyNoMoreRequest ();
2667+ }
2668+
26172669 /**
26182670 * When ignore_resource_deletion server feature is on, xDS client should keep the deleted cluster
26192671 * on empty response, and resume the normal work when CDS contains the cluster again.
0 commit comments