1010import io .reactivex .subscribers .TestSubscriber ;
1111import org .mockito .Mockito ;
1212import org .testng .Assert ;
13+ import org .testng .annotations .DataProvider ;
1314import org .testng .annotations .Test ;
1415import reactor .core .publisher .Mono ;
1516
2324
2425public class ClientRetryPolicyTest {
2526 private final static int TIMEOUT = 10000 ;
27+ private final static String TEST_DOCUMENT_PATH = "/dbs/db/colls/col/docs/doc" ;
28+ private final static String TEST_DATABASE_PATH = "/dbs/db" ;
29+
30+ @ DataProvider (name = "operationProvider" )
31+ public static Object [][] operationProvider () {
32+ return new Object [][]{
33+ // OperationType, ResourceType, isAddressRequest, RequestFullPath, ShouldRetryCrossRegion
34+ { OperationType .Read , ResourceType .Document , Boolean .FALSE , TEST_DOCUMENT_PATH , Boolean .TRUE },
35+ { OperationType .Read , ResourceType .Document , Boolean .TRUE , TEST_DOCUMENT_PATH , Boolean .FALSE },
36+ { OperationType .Create , ResourceType .Document , Boolean .FALSE , TEST_DOCUMENT_PATH , Boolean .FALSE },
37+ { OperationType .Read , ResourceType .Database , Boolean .FALSE , TEST_DATABASE_PATH , Boolean .TRUE },
38+ { OperationType .Create , ResourceType .Database , Boolean .FALSE , TEST_DATABASE_PATH , Boolean .FALSE },
39+ { OperationType .QueryPlan , ResourceType .Document , Boolean .FALSE , TEST_DOCUMENT_PATH , Boolean .TRUE }
40+ };
41+ }
2642
2743 @ Test (groups = "unit" )
2844 public void networkFailureOnRead () throws Exception {
@@ -58,13 +74,24 @@ public void networkFailureOnRead() throws Exception {
5874 }
5975 }
6076
61- @ Test (groups = "unit" )
62- public void shouldRetryOnGatewayTimeout () throws Exception {
77+ @ Test (groups = { "unit" }, dataProvider = "operationProvider" )
78+ public void shouldRetryOnGatewayTimeout (
79+ OperationType operationType ,
80+ ResourceType resourceType ,
81+ boolean isAddressRefresh ,
82+ String resourceFullPath ,
83+ boolean shouldCrossRegionRetry ) throws Exception {
6384 ThrottlingRetryOptions throttlingRetryOptions = new ThrottlingRetryOptions ();
6485 GlobalEndpointManager endpointManager = Mockito .mock (GlobalEndpointManager .class );
6586 Mockito .doReturn (new URI ("http://localhost" )).when (endpointManager ).resolveServiceEndpoint (Mockito .any (RxDocumentServiceRequest .class ));
6687 Mockito .doReturn (Mono .empty ()).when (endpointManager ).refreshLocationAsync (Mockito .eq (null ), Mockito .eq (true ));
67- ClientRetryPolicy clientRetryPolicy = new ClientRetryPolicy (mockDiagnosticsClientContext (), endpointManager , true , throttlingRetryOptions , null );
88+ ClientRetryPolicy clientRetryPolicy =
89+ new ClientRetryPolicy (
90+ mockDiagnosticsClientContext (),
91+ endpointManager ,
92+ true ,
93+ throttlingRetryOptions ,
94+ null );
6895
6996 Exception exception = ReadTimeoutException .INSTANCE ;
7097 CosmosException cosmosException = BridgeInternal .createCosmosException (null , HttpConstants .StatusCodes .REQUEST_TIMEOUT , exception );
@@ -73,71 +100,23 @@ public void shouldRetryOnGatewayTimeout() throws Exception {
73100 RxDocumentServiceRequest dsr ;
74101 Mono <ShouldRetryResult > shouldRetry ;
75102
76- //Data Plane Read
77- dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
78- OperationType .Read , "/dbs/db/colls/col/docs/doc" , ResourceType .Document );
79-
80- clientRetryPolicy .onBeforeSendRequest (dsr );
81- shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
82-
83- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
84- .nullException ()
85- .shouldRetry (true )
86- .backOffTime (Duration .ofMillis (1000 ))
87- .build ());
88-
89- //Metadata Read
90- dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
91- OperationType .Read , "/dbs/db/clls/col/docs/doc" , ResourceType .Database );
92-
93- clientRetryPolicy .onBeforeSendRequest (dsr );
94-
95- shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
96-
97- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
98- .nullException ()
99- .shouldRetry (true )
100- .backOffTime (Duration .ofMillis (1000 ))
101- .build ());
102-
103- //Query Plan
104- dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
105- OperationType .QueryPlan , "/dbs/db/colls/col/docs/doc" , ResourceType .Document );
106-
107- clientRetryPolicy .onBeforeSendRequest (dsr );
108-
109- shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
110-
111- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
112- .nullException ()
113- .shouldRetry (true )
114- .backOffTime (Duration .ofMillis (1000 ))
115- .build ());
116-
117- //Data Plane Write - Should not retry
118- dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
119- OperationType .Create , "/dbs/db/colls/col/docs/doc" , ResourceType .Document );
120-
121- clientRetryPolicy .onBeforeSendRequest (dsr );
122- shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
123-
124- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
125- .nullException ()
126- .shouldRetry (false )
127- .build ());
128-
129- //Metadata Write - Should not Retry
130- dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
131- OperationType .Create , "/dbs/db/colls/col/docs/docId" , ResourceType .Database );
103+ dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (), operationType , resourceFullPath , resourceType );
104+ dsr .setAddressRefresh (isAddressRefresh , false );
132105
133106 clientRetryPolicy .onBeforeSendRequest (dsr );
134-
135107 shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
136-
137- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
138- .nullException ()
139- .shouldRetry (false )
140- .build ());
108+ if (shouldCrossRegionRetry ) {
109+ validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
110+ .nullException ()
111+ .shouldRetry (true )
112+ .backOffTime (Duration .ofMillis (1000 ))
113+ .build ());
114+ } else {
115+ validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
116+ .nullException ()
117+ .shouldRetry (false )
118+ .build ());
119+ }
141120 }
142121
143122 @ Test (groups = "unit" )
@@ -412,40 +391,6 @@ public void tcpNetworkFailureOnDelete() throws Exception {
412391 }
413392 }
414393
415- @ Test (groups = "unit" )
416- public void httpNetworkFailureOnQueryPlan () throws Exception {
417- ThrottlingRetryOptions retryOptions = new ThrottlingRetryOptions ();
418- GlobalEndpointManager endpointManager = Mockito .mock (GlobalEndpointManager .class );
419- Mockito .doReturn (new URI ("http://localhost" )).when (endpointManager ).resolveServiceEndpoint (Mockito .any (RxDocumentServiceRequest .class ));
420- Mockito .doReturn (Mono .empty ()).when (endpointManager ).refreshLocationAsync (Mockito .eq (null ), Mockito .eq (true ));
421- Mockito .doReturn (2 ).when (endpointManager ).getPreferredLocationCount ();
422- ClientRetryPolicy clientRetryPolicy = new ClientRetryPolicy (mockDiagnosticsClientContext (), endpointManager , true , retryOptions , null );
423-
424- Exception exception = ReadTimeoutException .INSTANCE ;
425- CosmosException cosmosException =
426- BridgeInternal .createCosmosException (null , HttpConstants .StatusCodes .REQUEST_TIMEOUT , exception );
427- BridgeInternal .setSubStatusCode (cosmosException , HttpConstants .SubStatusCodes .GATEWAY_ENDPOINT_READ_TIMEOUT );
428-
429- RxDocumentServiceRequest dsr = RxDocumentServiceRequest .createFromName (mockDiagnosticsClientContext (),
430- OperationType .QueryPlan , "/dbs/db/colls/col/docs/" , ResourceType .Document );
431- dsr .requestContext = new DocumentServiceRequestContext ();
432-
433- clientRetryPolicy .onBeforeSendRequest (dsr );
434-
435- for (int i = 0 ; i < 10 ; i ++) {
436- Mono <ShouldRetryResult > shouldRetry = clientRetryPolicy .shouldRetry (cosmosException );
437-
438- validateSuccess (shouldRetry , ShouldRetryValidator .builder ()
439- .nullException ()
440- .shouldRetry (true )
441- .backOffTime (Duration .ofMillis (1000 ))
442- .build ());
443-
444- Mockito .verify (endpointManager , Mockito .times (i +1 )).markEndpointUnavailableForRead (Mockito .any ());
445- Mockito .verify (endpointManager , Mockito .times (0 )).markEndpointUnavailableForWrite (Mockito .any ());
446- }
447- }
448-
449394 @ Test (groups = "unit" )
450395 public void onBeforeSendRequestNotInvoked () {
451396 ThrottlingRetryOptions throttlingRetryOptions = new ThrottlingRetryOptions ();
0 commit comments