Skip to content

Commit 63a9cee

Browse files
Tests: Adds ValidateFallbackToDefaultEndpointWhenAllRegionsExcluded to LocationCacheTests
Agent-Logs-Url: https://github.com/Azure/azure-cosmos-dotnet-v3/sessions/023374cd-c809-410b-85ae-d6fdaf547fa5 Co-authored-by: kirankumarkolli <6880899+kirankumarkolli@users.noreply.github.com>
1 parent d4c91a0 commit 63a9cee

1 file changed

Lines changed: 99 additions & 1 deletion

File tree

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/LocationCacheTests.cs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,105 @@ public void VerifyRegionExcludedTest(
14331433

14341434
}
14351435

1436-
[TestMethod]
1436+
/// <summary>
1437+
/// Validates that when all preferred regions are included in ExcludeRegions, read requests fall
1438+
/// back to the configured default (Hub) endpoint unconditionally — even when that endpoint has
1439+
/// been marked as unavailable. The unavailability tracking used by the normal ReadEndpoints
1440+
/// ordering does NOT intercept the ExcludeRegions fallback path inside GetApplicableEndpoints.
1441+
/// </summary>
1442+
[TestMethod]
1443+
[DataRow(false, false, DisplayName = "All regions excluded - global default endpoint - default endpoint is available")]
1444+
[DataRow(false, true, DisplayName = "All regions excluded - global default endpoint - default endpoint is also marked unavailable")]
1445+
[DataRow(true, false, DisplayName = "All regions excluded - regional default endpoint - default endpoint is available")]
1446+
[DataRow(true, true, DisplayName = "All regions excluded - regional default endpoint - default endpoint is also marked unavailable")]
1447+
public void ValidateFallbackToDefaultEndpointWhenAllRegionsExcluded(
1448+
bool isDefaultEndpointARegionalEndpoint,
1449+
bool markDefaultEndpointUnavailable)
1450+
{
1451+
// The hub/configured endpoint — a global URI when not regional, a regional URI otherwise.
1452+
Uri defaultEndpoint = isDefaultEndpointARegionalEndpoint
1453+
? new Uri("https://location1.documents.azure.com")
1454+
: new Uri("https://testaccount.documents.azure.com");
1455+
1456+
Collection<AccountRegion> readLocations = new Collection<AccountRegion>()
1457+
{
1458+
new AccountRegion { Name = "location1", Endpoint = "https://location1.documents.azure.com" },
1459+
new AccountRegion { Name = "location2", Endpoint = "https://location2.documents.azure.com" },
1460+
new AccountRegion { Name = "location3", Endpoint = "https://location3.documents.azure.com" },
1461+
};
1462+
1463+
Collection<AccountRegion> writeLocations = new Collection<AccountRegion>()
1464+
{
1465+
new AccountRegion { Name = "location1", Endpoint = "https://location1.documents.azure.com" },
1466+
};
1467+
1468+
AccountProperties accountProps = new AccountProperties
1469+
{
1470+
ReadLocationsInternal = readLocations,
1471+
WriteLocationsInternal = writeLocations,
1472+
EnableMultipleWriteLocations = false,
1473+
};
1474+
1475+
ReadOnlyCollection<string> preferredLocations = new List<string>
1476+
{
1477+
"location1",
1478+
"location2",
1479+
"location3",
1480+
}.AsReadOnly();
1481+
1482+
LocationCache cache = new LocationCache(
1483+
preferredLocations: preferredLocations,
1484+
defaultEndpoint: defaultEndpoint,
1485+
enableEndpointDiscovery: true,
1486+
connectionLimit: 10,
1487+
useMultipleWriteLocations: false);
1488+
1489+
cache.OnDatabaseAccountRead(accountProps);
1490+
1491+
// Sanity check: before excluding any region the preferred read endpoints are the named regions.
1492+
Assert.IsTrue(cache.ReadEndpoints.Count > 0, "There should be read endpoints before any exclusion.");
1493+
if (!isDefaultEndpointARegionalEndpoint)
1494+
{
1495+
// When defaultEndpoint is a global (non-regional) URI it should not appear in the
1496+
// named-region read-endpoint list.
1497+
Assert.IsFalse(cache.ReadEndpoints.Contains(defaultEndpoint),
1498+
"The global default endpoint should not appear in the ordered read-endpoint list when named regions are available.");
1499+
}
1500+
1501+
if (markDefaultEndpointUnavailable)
1502+
{
1503+
// Mark the hub/default endpoint unavailable for reads to confirm the ExcludeRegions
1504+
// fallback is unconditional and does not consult the unavailability registry.
1505+
cache.MarkEndpointUnavailableForRead(defaultEndpoint);
1506+
}
1507+
1508+
// Exclude every named region so that no applicable endpoint survives filtering.
1509+
List<string> allRegions = new List<string> { "location1", "location2", "location3" };
1510+
1511+
using (DocumentServiceRequest request = DocumentServiceRequest.Create(
1512+
OperationType.Read,
1513+
ResourceType.Document,
1514+
AuthorizationTokenType.PrimaryMasterKey))
1515+
{
1516+
request.RequestContext.ExcludeRegions = allRegions;
1517+
1518+
// GetApplicableEndpoints must fall back to the configured default endpoint when every
1519+
// preferred region is excluded, regardless of the endpoint's own availability status.
1520+
ReadOnlyCollection<Uri> applicableEndpoints = cache.GetApplicableEndpoints(request, isReadRequest: true);
1521+
1522+
Assert.AreEqual(1, applicableEndpoints.Count,
1523+
"Exactly one fallback endpoint should be returned when all regions are excluded.");
1524+
Assert.AreEqual(defaultEndpoint, applicableEndpoints[0],
1525+
"The fallback endpoint must be the configured default/Hub endpoint, even if it is marked unavailable.");
1526+
1527+
// ResolveServiceEndpoint must also route the request to that same default endpoint.
1528+
Uri resolvedEndpoint = cache.ResolveServiceEndpoint(request);
1529+
Assert.AreEqual(defaultEndpoint, resolvedEndpoint,
1530+
"ResolveServiceEndpoint must route to the default/Hub endpoint when all regions are excluded.");
1531+
}
1532+
}
1533+
1534+
[TestMethod]
14371535
public void ValidateThinClientReadFallbackToWriteEndpointTest()
14381536
{
14391537
// Arrange:

0 commit comments

Comments
 (0)