1919import com .azure .cosmos .implementation .OperationType ;
2020import com .azure .cosmos .implementation .Utils ;
2121import com .azure .cosmos .implementation .throughputControl .TestItem ;
22+ import com .azure .cosmos .models .CosmosItemResponse ;
2223import com .azure .cosmos .models .CosmosQueryRequestOptions ;
2324import com .azure .cosmos .models .FeedRange ;
2425import com .azure .cosmos .models .PartitionKey ;
@@ -208,9 +209,9 @@ public void faultInjectionServerErrorRuleTests_AddressRefresh_ConnectionDelay(bo
208209 // when preferred regions is 2
209210 // Due to issue https://github.com/Azure/azure-sdk-for-java/issues/35779, the request mark the region unavailable will retry
210211 // in the unavailable region again, hence the addressRefresh fault injection will be happened 4 times
211- validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshConnectionDelay , 4 );
212+ validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshConnectionDelay , 4 , false );
212213 } else {
213- validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshConnectionDelay , 3 );
214+ validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshConnectionDelay , 3 , false );
214215 }
215216 } catch (CosmosException e ) {
216217 fail ("Request should be able to succeed by retrying in another region. " + e .getDiagnostics ());
@@ -305,18 +306,34 @@ public void faultInjectionServerErrorRuleTests_AddressRefresh_ResponseDelay(
305306 CosmosDiagnostics cosmosDiagnostics =
306307 this .performDocumentOperation (container , operationType , createdItem );
307308
308- assertThat (cosmosDiagnostics .getContactedRegionNames ().size ()).isEqualTo (1 );
309- assertThat (
310- cosmosDiagnostics
311- .getContactedRegionNames ()
312- .containsAll (Arrays .asList (this .readPreferredLocations .get (0 ).toLowerCase ())))
313- .isTrue ();
314309
315- assertThat (cosmosDiagnostics .getDiagnosticsContext ().getStatusCode ())
316- .isEqualTo (HttpConstants .StatusCodes .REQUEST_TIMEOUT );
317- assertThat (cosmosDiagnostics .getDiagnosticsContext ().getSubStatusCode ())
318- .isEqualTo (HttpConstants .SubStatusCodes .GATEWAY_ENDPOINT_READ_TIMEOUT );
319- validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshResponseDelay , 3 );
310+ if (isNonWriteDocumentOperation (operationType )) {
311+ assertThat (cosmosDiagnostics .getContactedRegionNames ().size ()).isEqualTo (2 );
312+ assertThat (
313+ cosmosDiagnostics
314+ .getContactedRegionNames ()
315+ .containsAll (Arrays .asList (this .readPreferredLocations .get (0 ).toLowerCase (), this .readPreferredLocations .get (0 ).toLowerCase ())))
316+ .isTrue ();
317+
318+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getStatusCode ())
319+ .isNotEqualTo (HttpConstants .StatusCodes .REQUEST_TIMEOUT );
320+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getSubStatusCode ())
321+ .isNotEqualTo (HttpConstants .SubStatusCodes .GATEWAY_ENDPOINT_READ_TIMEOUT );
322+ } else {
323+ assertThat (cosmosDiagnostics .getContactedRegionNames ().size ()).isEqualTo (1 );
324+ assertThat (
325+ cosmosDiagnostics
326+ .getContactedRegionNames ()
327+ .containsAll (Arrays .asList (this .readPreferredLocations .get (0 ).toLowerCase ())))
328+ .isTrue ();
329+
330+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getStatusCode ())
331+ .isEqualTo (HttpConstants .StatusCodes .REQUEST_TIMEOUT );
332+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getSubStatusCode ())
333+ .isEqualTo (HttpConstants .SubStatusCodes .GATEWAY_ENDPOINT_READ_TIMEOUT );
334+ }
335+
336+ validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshResponseDelay , 3 , operationType == OperationType .Query );
320337 } finally {
321338 addressRefreshResponseDelayRule .disable ();
322339 dataOperationGoneRule .disable ();
@@ -404,17 +421,25 @@ public void faultInjectionServerErrorRuleTests_AddressRefresh_byPartition(boolea
404421 Arrays .asList (addressRefreshResponseDelayRule , dataOperationGoneRule ))
405422 .block ();
406423
407- // validate for request on feed range 0, it will fail
424+ // validate for request on feed range 0, address refresh request failures will happen but request will succeed in second region as request is Document read
408425 try {
409- CosmosDiagnostics cosmosDiagnostics =
426+ CosmosItemResponse < JsonNode > itemResponse =
410427 container
411428 .readItem (itemOnFeedRange1 .getId (), new PartitionKey (itemOnFeedRange1 .getId ()), JsonNode .class )
412- .block ()
413- .getDiagnostics ();
429+ .block ();
414430
415- fail ("Item on feed range 1 should have failed. " + cosmosDiagnostics );
431+ assertThat (itemResponse ).isNotNull ();
432+
433+ CosmosDiagnostics cosmosDiagnostics = itemResponse .getDiagnostics ();
434+
435+ assertThat (addressRefreshResponseDelayRule .getHitCount ()).isGreaterThan (0 );
436+
437+ assertThat (cosmosDiagnostics ).isNotNull ();
438+ assertThat (cosmosDiagnostics .getDiagnosticsContext ()).isNotNull ();
439+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getContactedRegionNames ()).isNotNull ();
440+ assertThat (cosmosDiagnostics .getDiagnosticsContext ().getContactedRegionNames ().size ()).isEqualTo (2 );
416441 } catch (CosmosException e ) {
417- // no-op
442+ fail ( "Item on feed range 1 should have succeeded. " + e . getDiagnostics ());
418443 }
419444
420445 try {
@@ -497,7 +522,7 @@ public void faultInjectionServerErrorRuleTests_AddressRefresh_TooManyRequest(boo
497522
498523 assertThat (cosmosDiagnostics .getContactedRegionNames ().size ()).isEqualTo (1 );
499524 assertThat (cosmosDiagnostics .getContactedRegionNames ().containsAll (Arrays .asList (this .readPreferredLocations .get (0 ).toLowerCase ()))).isTrue ();
500- validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshTooManyRequest , 1 );
525+ validateFaultInjectionRuleAppliedForAddressResolution (cosmosDiagnostics , addressRefreshTooManyRequest , 1 , false );
501526 } finally {
502527 addressRefreshTooManyRequestRule .disable ();
503528 dataOperationGoneRule .disable ();
@@ -719,10 +744,24 @@ public void afterClass() {
719744 private void validateFaultInjectionRuleAppliedForAddressResolution (
720745 CosmosDiagnostics cosmosDiagnostics ,
721746 String ruleId ,
722- int failureInjectedExpectedCount ) throws JsonProcessingException {
747+ int failureInjectedExpectedCount ,
748+ boolean isQueryOperation ) throws JsonProcessingException {
723749
724750 ObjectNode diagnosticsNode = (ObjectNode ) Utils .getSimpleObjectMapper ().readTree (cosmosDiagnostics .toString ());
725- JsonNode addressResolutionStatistics = diagnosticsNode .get ("addressResolutionStatistics" );
751+ JsonNode addressResolutionStatistics ;
752+
753+ if (isQueryOperation ) {
754+
755+ ArrayNode arrayNode = (ArrayNode ) diagnosticsNode .get ("clientSideRequestStatistics" );
756+
757+ assertThat (arrayNode ).isNotNull ();
758+ assertThat (arrayNode .get (0 )).isNotNull ();
759+
760+ addressResolutionStatistics = arrayNode .get (0 ).get ("addressResolutionStatistics" );
761+ } else {
762+ addressResolutionStatistics = diagnosticsNode .get ("addressResolutionStatistics" );
763+ }
764+
726765 Iterator <Map .Entry <String , JsonNode >> addressResolutionIterator = addressResolutionStatistics .fields ();
727766 int failureInjectedCount = 0 ;
728767 while (addressResolutionIterator .hasNext ()) {
@@ -736,6 +775,12 @@ private void validateFaultInjectionRuleAppliedForAddressResolution(
736775 assertThat (failureInjectedCount ).isEqualTo (failureInjectedExpectedCount );
737776 }
738777
778+ private static boolean isNonWriteDocumentOperation (OperationType operationType ) {
779+ return operationType == OperationType .Read ||
780+ operationType == OperationType .Query ||
781+ operationType == OperationType .ReadFeed ;
782+ }
783+
739784 private static AccountLevelLocationContext getAccountLevelLocationContext (DatabaseAccount databaseAccount , boolean writeOnly ) {
740785 Iterator <DatabaseAccountLocation > locationIterator =
741786 writeOnly ? databaseAccount .getWritableLocations ().iterator () : databaseAccount .getReadableLocations ().iterator ();
0 commit comments