@@ -1075,12 +1075,14 @@ public async Task AssertBarrierCallsForStrongConsistencyWrite()
10751075 Assert . IsTrue ( barrier429Count > 0 , "No retries were made for 429 error code." ) ;
10761076 }
10771077
1078+
10781079 [ TestMethod ]
1079- public async Task AssertBarrierCallsWhenQuorumStateIsQuorumSelected ( )
1080+ public async Task AssertOneBarrierCallShouldResultInASuccess ( )
10801081 {
10811082 int barrier429Count = 0 ;
10821083 string databaseName = "newdatabase" ;
10831084 bool isReadOperation = false ;
1085+ bool hasFailedOnce = false ;
10841086
10851087 CosmosClientOptions clientOptions = new CosmosClientOptions ( )
10861088 {
@@ -1098,14 +1100,98 @@ public async Task AssertBarrierCallsWhenQuorumStateIsQuorumSelected()
10981100 storeResponse . Headers . Set ( Documents . WFConstants . BackendHeaders . GlobalCommittedLSN , lsn . ToString ( ) ) ;
10991101 }
11001102 // only simulate 429 errors for read operations not write
1101- if ( request . OperationType == Documents . OperationType . Head && isReadOperation )
1103+ if ( request . OperationType == Documents . OperationType . Head && isReadOperation && ! hasFailedOnce )
11021104 {
1103-
1105+
11041106 request . UseStatusCodeFor429 = false ;
11051107 // Simulate a 429 for barrier requests
11061108 storeResponse . Status = ( int ) HttpStatusCode . TooManyRequests ; // Simulate 429 error
11071109 storeResponse . Headers . Set ( Documents . WFConstants . BackendHeaders . GlobalCommittedLSN , lsn . ToString ( ) ) ;
11081110 barrier429Count ++ ;
1111+ hasFailedOnce = true ; // Ensure only one failure
1112+ }
1113+
1114+ return storeResponse ;
1115+ } )
1116+ } ;
1117+
1118+ CosmosClient cosmosClient = new CosmosClientBuilder (
1119+ connectionString : "points to test environment with one read and one write region" )
1120+ . WithTransportClientHandlerFactory ( clientOptions . TransportClientHandlerFactory )
1121+ . WithThrottlingRetryOptions (
1122+ maxRetryWaitTimeOnThrottledRequests : TimeSpan . FromSeconds ( 5 ) , // Maximum wait time for retries
1123+ maxRetryAttemptsOnThrottledRequests : 2 ) // Maximum retry attempts
1124+ . WithConnectionModeDirect ( )
1125+ . WithConsistencyLevel ( Cosmos . ConsistencyLevel . Strong )
1126+ . Build ( ) ;
1127+
1128+ Container container = cosmosClient . GetDatabase ( databaseName ) . GetContainer ( "test" ) ;
1129+
1130+ dynamic testObject = new
1131+ {
1132+ id = Guid . NewGuid ( ) . ToString ( ) ,
1133+ Company = "Microsoft" ,
1134+ State = "WA"
1135+ } ;
1136+ await container . CreateItemAsync < dynamic > ( testObject ) ;
1137+
1138+ try
1139+ {
1140+ isReadOperation = true ;
1141+ // Perform a read operation to trigger barrier calls
1142+ ItemResponse < dynamic > response = await container . ReadItemAsync < dynamic > (
1143+ testObject . id ,
1144+ new Cosmos . PartitionKey ( testObject . id ) ) ;
1145+
1146+
1147+ Console . WriteLine ( "Diagnostics:" ) ;
1148+ Console . WriteLine ( response . Diagnostics . ToString ( ) ) ;
1149+ }
1150+ catch ( CosmosException ex )
1151+ {
1152+ // Handle other Cosmos exceptions
1153+ Console . WriteLine ( $ "CosmosException: { ex . StatusCode } - { ex . Message } ") ;
1154+ Console . WriteLine ( "Diagnostics:" ) ;
1155+ Console . WriteLine ( ex . Diagnostics . ToString ( ) ) ;
1156+ }
1157+
1158+ Console . WriteLine ( $ "Total 429 responses on barrier calls: { barrier429Count } ") ;
1159+ // Assert that retries occurred
1160+ Assert . IsTrue ( barrier429Count > 0 , "No retries were made for 429 error code." ) ;
1161+
1162+ }
1163+
1164+ //StorePhysicalAddress
1165+ [ TestMethod ]
1166+ public async Task AssertBarrierCallsWhenQuorumStateIsQuorumSelected ( )
1167+ {
1168+ int barrier429Count = 0 ;
1169+ string databaseName = "newdatabase" ;
1170+ bool isReadOperation = false ;
1171+
1172+
1173+ CosmosClientOptions clientOptions = new CosmosClientOptions ( )
1174+ {
1175+ ConnectionMode = ConnectionMode . Direct ,
1176+ ConnectionProtocol = Protocol . Tcp ,
1177+ TransportClientHandlerFactory = ( transport ) => new TransportClientWrapper ( transport ,
1178+ interceptorAfterResult : ( request , storeResponse ) =>
1179+ {
1180+ // Force a barrier request on read item in strong consistency.
1181+ // There needs to be 2 regions and the GlobalCommittedLSN must be behind the LSN.
1182+ long lsn = storeResponse . LSN - 2 ;
1183+ if ( request . OperationType == Documents . OperationType . Read )
1184+ {
1185+ // Simulate a barrier request by setting GLSN < LSN
1186+ storeResponse . Headers . Set ( Documents . WFConstants . BackendHeaders . GlobalCommittedLSN , lsn . ToString ( ) ) ;
1187+ }
1188+ // only simulate 429 errors for read operations not write
1189+ if ( request . OperationType == Documents . OperationType . Head && isReadOperation )
1190+ {
1191+ // Simulate a 429 for barrier requests
1192+ storeResponse . Status = ( int ) HttpStatusCode . TooManyRequests ; // Simulate 429 error
1193+ storeResponse . Headers . Set ( Documents . WFConstants . BackendHeaders . GlobalCommittedLSN , lsn . ToString ( ) ) ;
1194+ barrier429Count ++ ;
11091195 }
11101196
11111197 return storeResponse ;
0 commit comments