Skip to content

Commit 15c7f61

Browse files
committed
fix: add test coverage for single replica failure
1 parent 0788efc commit 15c7f61

1 file changed

Lines changed: 89 additions & 3 deletions

File tree

  • Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTests.cs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)