18
18
19
19
import static com .google .common .truth .Truth .assertThat ;
20
20
import static com .google .common .truth .Truth .assertWithMessage ;
21
+ import static io .grpc .xds .XdsClientImpl .XdsChannelFactory .DEFAULT_XDS_CHANNEL_FACTORY ;
21
22
import static org .mockito .ArgumentMatchers .any ;
22
23
import static org .mockito .ArgumentMatchers .isA ;
23
24
import static org .mockito .Mockito .mock ;
70
71
import io .grpc .stub .StreamObserver ;
71
72
import io .grpc .testing .GrpcCleanupRule ;
72
73
import io .grpc .xds .Bootstrapper .AuthorityInfo ;
74
+ import io .grpc .xds .Bootstrapper .BootstrapInfo ;
73
75
import io .grpc .xds .Bootstrapper .CertificateProviderInfo ;
74
76
import io .grpc .xds .Bootstrapper .ServerInfo ;
75
77
import io .grpc .xds .Endpoints .DropOverload ;
114
116
import org .junit .runner .RunWith ;
115
117
import org .junit .runners .JUnit4 ;
116
118
import org .mockito .ArgumentCaptor ;
119
+ import org .mockito .ArgumentMatchers ;
117
120
import org .mockito .Captor ;
118
121
import org .mockito .InOrder ;
119
122
import org .mockito .Mock ;
@@ -3226,7 +3229,8 @@ public void streamClosedAndRetryWithBackoff() {
3226
3229
3227
3230
// Management server closes the RPC stream with an error.
3228
3231
call .sendError (Status .UNKNOWN .asException ());
3229
- verify (ldsResourceWatcher ).onError (errorCaptor .capture ());
3232
+ verify (ldsResourceWatcher , Mockito .timeout (1000 ).times (1 ))
3233
+ .onError (errorCaptor .capture ());
3230
3234
verifyStatusWithNodeId (errorCaptor .getValue (), Code .UNKNOWN , "" );
3231
3235
verify (rdsResourceWatcher ).onError (errorCaptor .capture ());
3232
3236
verifyStatusWithNodeId (errorCaptor .getValue (), Code .UNKNOWN , "" );
@@ -3336,7 +3340,8 @@ public void streamClosedAndRetryRaceWithAddRemoveWatchers() {
3336
3340
RDS_RESOURCE , rdsResourceWatcher );
3337
3341
DiscoveryRpcCall call = resourceDiscoveryCalls .poll ();
3338
3342
call .sendError (Status .UNAVAILABLE .asException ());
3339
- verify (ldsResourceWatcher ).onError (errorCaptor .capture ());
3343
+ verify (ldsResourceWatcher , Mockito .timeout (1000 ).times (1 ))
3344
+ .onError (errorCaptor .capture ());
3340
3345
verifyStatusWithNodeId (errorCaptor .getValue (), Code .UNAVAILABLE , "" );
3341
3346
verify (rdsResourceWatcher ).onError (errorCaptor .capture ());
3342
3347
verifyStatusWithNodeId (errorCaptor .getValue (), Code .UNAVAILABLE , "" );
@@ -3573,13 +3578,18 @@ public void sendingToStoppedServer() throws Exception {
3573
3578
.build ()
3574
3579
.start ());
3575
3580
fakeClock .forwardTime (5 , TimeUnit .SECONDS );
3581
+ verify (ldsResourceWatcher , never ()).onResourceDoesNotExist (LDS_RESOURCE );
3582
+ fakeClock .forwardTime (20 , TimeUnit .SECONDS ); // Trigger rpcRetryTimer
3576
3583
DiscoveryRpcCall call = resourceDiscoveryCalls .poll (3 , TimeUnit .SECONDS );
3584
+ if (call == null ) { // The first rpcRetry may have happened before the channel was ready
3585
+ fakeClock .forwardTime (50 , TimeUnit .SECONDS );
3586
+ call = resourceDiscoveryCalls .poll (3 , TimeUnit .SECONDS );
3587
+ }
3577
3588
3578
3589
// NOTE: There is a ScheduledExecutorService that may get involved due to the reconnect
3579
3590
// so you cannot rely on the logic being single threaded. The timeout() in verifyRequest
3580
3591
// is therefore necessary to avoid flakiness.
3581
3592
// Send a response and do verifications
3582
- verify (ldsResourceWatcher , never ()).onResourceDoesNotExist (LDS_RESOURCE );
3583
3593
call .sendResponse (LDS , mf .buildWrappedResource (testListenerVhosts ), VERSION_1 , "0001" );
3584
3594
call .verifyRequest (LDS , LDS_RESOURCE , VERSION_1 , "0001" , NODE );
3585
3595
verify (ldsResourceWatcher ).onChanged (ldsUpdateCaptor .capture ());
@@ -3592,6 +3602,66 @@ public void sendingToStoppedServer() throws Exception {
3592
3602
}
3593
3603
}
3594
3604
3605
+ @ Test
3606
+ public void sendToBadUrl () throws Exception {
3607
+ // Setup xdsClient to fail on stream creation
3608
+ XdsClientImpl client = createXdsClient ("some. garbage" );
3609
+
3610
+ client .watchXdsResource (XdsListenerResource .getInstance (), LDS_RESOURCE , ldsResourceWatcher );
3611
+ fakeClock .forwardTime (20 , TimeUnit .SECONDS );
3612
+ verify (ldsResourceWatcher , Mockito .timeout (5000 ).times (1 )).onError (ArgumentMatchers .any ());
3613
+ client .shutdown ();
3614
+ }
3615
+
3616
+ @ Test
3617
+ public void sendToNonexistentHost () throws Exception {
3618
+ // Setup xdsClient to fail on stream creation
3619
+ XdsClientImpl client = createXdsClient ("some.garbage" );
3620
+ client .watchXdsResource (XdsListenerResource .getInstance (), LDS_RESOURCE , ldsResourceWatcher );
3621
+ fakeClock .forwardTime (20 , TimeUnit .SECONDS );
3622
+
3623
+ verify (ldsResourceWatcher , Mockito .timeout (5000 ).times (1 )).onError (ArgumentMatchers .any ());
3624
+ fakeClock .forwardTime (50 , TimeUnit .SECONDS ); // Trigger rpcRetry if appropriate
3625
+ assertThat (fakeClock .getPendingTasks (LDS_RESOURCE_FETCH_TIMEOUT_TASK_FILTER )).isEmpty ();
3626
+ client .shutdown ();
3627
+ }
3628
+
3629
+ private XdsClientImpl createXdsClient (String serverUri ) {
3630
+ BootstrapInfo bootstrapInfo = buildBootStrap (serverUri );
3631
+ return new XdsClientImpl (
3632
+ DEFAULT_XDS_CHANNEL_FACTORY ,
3633
+ bootstrapInfo ,
3634
+ Context .ROOT ,
3635
+ fakeClock .getScheduledExecutorService (),
3636
+ backoffPolicyProvider ,
3637
+ fakeClock .getStopwatchSupplier (),
3638
+ timeProvider ,
3639
+ tlsContextManager );
3640
+ }
3641
+
3642
+ private BootstrapInfo buildBootStrap (String serverUri ) {
3643
+
3644
+ ServerInfo xdsServerInfo = ServerInfo .create (serverUri , CHANNEL_CREDENTIALS ,
3645
+ ignoreResourceDeletion ());
3646
+
3647
+ return Bootstrapper .BootstrapInfo .builder ()
3648
+ .servers (Collections .singletonList (xdsServerInfo ))
3649
+ .node (NODE )
3650
+ .authorities (ImmutableMap .of (
3651
+ "authority.xds.com" ,
3652
+ AuthorityInfo .create (
3653
+ "xdstp://authority.xds.com/envoy.config.listener.v3.Listener/%s" ,
3654
+ ImmutableList .of (Bootstrapper .ServerInfo .create (
3655
+ SERVER_URI_CUSTOME_AUTHORITY , CHANNEL_CREDENTIALS ))),
3656
+ "" ,
3657
+ AuthorityInfo .create (
3658
+ "xdstp:///envoy.config.listener.v3.Listener/%s" ,
3659
+ ImmutableList .of (Bootstrapper .ServerInfo .create (
3660
+ SERVER_URI_EMPTY_AUTHORITY , CHANNEL_CREDENTIALS )))))
3661
+ .certProviders (ImmutableMap .of ("cert-instance-name" ,
3662
+ CertificateProviderInfo .create ("file-watcher" , ImmutableMap .<String , Object >of ())))
3663
+ .build ();
3664
+ }
3595
3665
3596
3666
private <T extends ResourceUpdate > DiscoveryRpcCall startResourceWatcher (
3597
3667
XdsResourceType <T > type , String name , ResourceWatcher <T > watcher ) {
0 commit comments