From 766af536e098fa8dfdc9419b3fcdd19d18b4b256 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Thu, 16 May 2024 21:12:37 -0700 Subject: [PATCH 1/6] Fixes `dotnet test` below issues [D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA007: Method ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations defined in class Microsoft.Azure.Cosmos.Client.Tests.ClientRetryPolicyTests does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be Task. Example: public async Task Test.Class1.Test2() There are still some more query test issues that needs attention (next follow-UpsertUser) [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA001: TestClass attribute defined on non-public class Microsoft.Azure.Cosmos.Tests.Query.OrderByQueryPartitionRangePageAsyncEnumeratorTests+Implementation [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA001: TestClass attribute defined on non-public class Microsoft.Azure.Cosmos.Tests.Query.QueryPartitionRangePageAsyncEnumeratorTests+Implementation [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA001: TestClass attribute defined on non-public class Microsoft.Azure.Cosmos.Tests.Pagination.BufferedPartitionPartitionRangeEnumeratorTests+Implementation [MSTest][Discovery][D:\a\1\s\Microsoft.Azure.Cosmos\tests\Microsoft.Azure.Cosmos.Tests\bin\Debug\net6.0\Microsoft.Azure.Cosmos.Tests.dll] UTA001: TestClass attribute defined on non-public class Microsoft.Azure.Cosmos.Tests.Pagination.SinglePartitionPartitionRangeEnumeratorTests+Implementation --- .../ClientRetryPolicyTests.cs | 34 +++++++++---------- .../CosmosClientOptionsUnitTests.cs | 3 +- .../Pipeline/NonStreamingOrderByQueryTests.cs | 12 ++++++- .../Query/SubpartitionTests.cs | 14 ++++---- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index cf1c739388..a982439e42 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -21,7 +21,7 @@ /// [TestClass] public sealed class ClientRetryPolicyTests - { + { private static Uri Location1Endpoint = new Uri("https://location1.documents.azure.com"); private static Uri Location2Endpoint = new Uri("https://location2.documents.azure.com"); @@ -125,51 +125,51 @@ public void Http503SubStatusHandelingTests(int testCode) } [TestMethod] - public Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } private async Task ValidateConnectTimeoutTriggersClientRetryPolicy( diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs index 293c3b14ab..f32bc532db 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs @@ -1003,8 +1003,7 @@ public void TestServerCertificatesValidationWithDisableSSLFlagTrue(string connSt CosmosHttpClient httpClient = cosmosClient.DocumentClient.httpClient; SocketsHttpHandler socketsHttpHandler = (SocketsHttpHandler)httpClient.HttpMessageHandler; - RemoteCertificateValidationCallback? httpClientRemoreCertValidationCallback = socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback; - Assert.IsNotNull(httpClientRemoreCertValidationCallback); + Assert.IsNotNull(socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback); } private class TestWebProxy : IWebProxy diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs index 6d41312496..ed2cf06a35 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs @@ -726,7 +726,17 @@ private async Task SplitMergeAsync() private static class DebugTraceHelpers { - private const bool Enabled = false; + private static readonly bool Enabled; + + static DebugTraceHelpers() + { + DebugTraceHelpers.Enabled = false; + if (Debugger.IsAttached) + { + // Hack to workaround the non-reachable warning + DebugTraceHelpers.Enabled = true; + } + } #pragma warning disable CS0162 // Unreachable code detected [Conditional("DEBUG")] diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs index 2cdaedfc37..b306281ae0 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs @@ -22,9 +22,9 @@ using Microsoft.Azure.Cosmos.Tests.Pagination; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; - using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; - + [TestClass] public class SubpartitionTests : BaselineTests { @@ -136,7 +136,7 @@ private static IQueryPipelineStage CreateQueryPipelineStage( partitionedQueryExecutionInfo: null, returnResultsInDeterministicOrder: null, enableOptimisticDirectExecution: queryRequestOptions.EnableOptimisticDirectExecution, - isNonStreamingOrderByQueryFeatureDisabled: queryRequestOptions.IsNonStreamingOrderByQueryFeatureDisabled, + isNonStreamingOrderByQueryFeatureDisabled: queryRequestOptions.IsNonStreamingOrderByQueryFeatureDisabled, enableDistributedQueryGatewayMode: queryRequestOptions.EnableDistributedQueryGatewayMode, testInjections: queryRequestOptions.TestSettings); @@ -161,8 +161,8 @@ private static IQueryPipelineStage CreateQueryPipelineStage( isContinuationExpected: true, allowNonValueAggregateQuery: true, useSystemPrefix: false, - correlatedActivityId: Guid.NewGuid()); - + correlatedActivityId: Guid.NewGuid()); + IQueryPipelineStage queryPipelineStage = CosmosQueryExecutionContextFactory.Create( documentContainer, cosmosQueryContextCore, @@ -177,7 +177,7 @@ internal static Tuple Get QueryPartitionProvider queryPartitionProvider = CreateCustomQueryPartitionProvider(); TryCatch tryGetQueryPlan = queryPartitionProvider.TryGetPartitionedQueryExecutionInfo( querySpecJsonString: querySpecJsonString, - partitionKeyDefinition: pkDefinition, + partitionKeyDefinition: pkDefinition, vectorEmbeddingPolicy: null, requireFormattableOrderByQuery: true, isContinuationExpected: true, @@ -332,7 +332,7 @@ public override Task GetCachedContainerQueryProperties true, true) }, - SubpartitionTests.CreatePartitionKeyDefinition(), + SubpartitionTests.CreatePartitionKeyDefinition(), vectorEmbeddingPolicy: null, Cosmos.GeospatialType.Geometry)); } From ff16ab635865f6209b96cd6516e098dd66c72c5b Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Wed, 2 Oct 2024 14:46:38 -0700 Subject: [PATCH 2/6] refreshing file --- .../ClientRetryPolicyTests.cs | 1416 ++++++++--------- 1 file changed, 708 insertions(+), 708 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index 6203f9418b..e2591eeac4 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -1,143 +1,143 @@ -namespace Microsoft.Azure.Cosmos.Client.Tests -{ - using System; - using Microsoft.Azure.Cosmos.Routing; - using Microsoft.Azure.Documents; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Globalization; - using System.Linq; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Azure.Documents.Collections; - using Microsoft.Azure.Documents.Client; +namespace Microsoft.Azure.Cosmos.Client.Tests +{ + using System; + using Microsoft.Azure.Cosmos.Routing; + using Microsoft.Azure.Documents; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Globalization; + using System.Linq; + using System.Net; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Azure.Documents.Collections; + using Microsoft.Azure.Documents.Client; using Microsoft.Azure.Cosmos.Common; using System.Net.Http; using System.Reflection; using System.Collections.Concurrent; - /// - /// Tests for - /// - [TestClass] - public sealed class ClientRetryPolicyTests - { - private static Uri Location1Endpoint = new Uri("https://location1.documents.azure.com"); - private static Uri Location2Endpoint = new Uri("https://location2.documents.azure.com"); - - private ReadOnlyCollection preferredLocations; - private AccountProperties databaseAccount; - private GlobalPartitionEndpointManager partitionKeyRangeLocationCache; - private Mock mockedClient; - - /// - /// Tests behavior of Multimaster Accounts on metadata writes where the default location is not the hub region - /// - [TestMethod] - public void MultimasterMetadataWriteRetryTest() - { - const bool enableEndpointDiscovery = false; - - //Creates GlobalEndpointManager where enableEndpointDiscovery is False and - //Default location is false - using GlobalEndpointManager endpointManager = this.Initialize( - useMultipleWriteLocations: true, - enableEndpointDiscovery: enableEndpointDiscovery, - isPreferredLocationsListEmpty: true, - multimasterMetadataWriteRetryTest: true); - - - ClientRetryPolicy retryPolicy = new ClientRetryPolicy(endpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery, false); - - //Creates a metadata write request - DocumentServiceRequest request = this.CreateRequest(false, true); - - Assert.IsTrue(endpointManager.IsMultimasterMetadataWriteRequest(request)); - - //On first attempt should get incorrect (default/non hub) location - retryPolicy.OnBeforeSendRequest(request); - Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location2Endpoint); - - //Creation of 403.3 Error - HttpStatusCode forbidden = HttpStatusCode.Forbidden; - SubStatusCodes writeForbidden = SubStatusCodes.WriteForbidden; - Exception forbiddenWriteFail = new Exception(); - Mock nameValueCollection = new Mock(); - - DocumentClientException documentClientException = new DocumentClientException( - message: "Multimaster Metadata Write Fail", - innerException: forbiddenWriteFail, - statusCode: forbidden, - substatusCode: writeForbidden, - requestUri: request.RequestContext.LocationEndpointToRoute, - responseHeaders: nameValueCollection.Object); - - CancellationToken cancellationToken = new CancellationToken(); - - //Tests behavior of should retry - Task shouldRetry = retryPolicy.ShouldRetryAsync(documentClientException, cancellationToken); - - Assert.IsTrue(shouldRetry.Result.ShouldRetry); - - //Now since the retry context is not null, should route to the hub region - retryPolicy.OnBeforeSendRequest(request); - Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location1Endpoint); - } - - /// + /// + /// Tests for + /// + [TestClass] + public sealed class ClientRetryPolicyTests + { + private static Uri Location1Endpoint = new Uri("https://location1.documents.azure.com"); + private static Uri Location2Endpoint = new Uri("https://location2.documents.azure.com"); + + private ReadOnlyCollection preferredLocations; + private AccountProperties databaseAccount; + private GlobalPartitionEndpointManager partitionKeyRangeLocationCache; + private Mock mockedClient; + + /// + /// Tests behavior of Multimaster Accounts on metadata writes where the default location is not the hub region + /// + [TestMethod] + public void MultimasterMetadataWriteRetryTest() + { + const bool enableEndpointDiscovery = false; + + //Creates GlobalEndpointManager where enableEndpointDiscovery is False and + //Default location is false + using GlobalEndpointManager endpointManager = this.Initialize( + useMultipleWriteLocations: true, + enableEndpointDiscovery: enableEndpointDiscovery, + isPreferredLocationsListEmpty: true, + multimasterMetadataWriteRetryTest: true); + + + ClientRetryPolicy retryPolicy = new ClientRetryPolicy(endpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery, false); + + //Creates a metadata write request + DocumentServiceRequest request = this.CreateRequest(false, true); + + Assert.IsTrue(endpointManager.IsMultimasterMetadataWriteRequest(request)); + + //On first attempt should get incorrect (default/non hub) location + retryPolicy.OnBeforeSendRequest(request); + Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location2Endpoint); + + //Creation of 403.3 Error + HttpStatusCode forbidden = HttpStatusCode.Forbidden; + SubStatusCodes writeForbidden = SubStatusCodes.WriteForbidden; + Exception forbiddenWriteFail = new Exception(); + Mock nameValueCollection = new Mock(); + + DocumentClientException documentClientException = new DocumentClientException( + message: "Multimaster Metadata Write Fail", + innerException: forbiddenWriteFail, + statusCode: forbidden, + substatusCode: writeForbidden, + requestUri: request.RequestContext.LocationEndpointToRoute, + responseHeaders: nameValueCollection.Object); + + CancellationToken cancellationToken = new CancellationToken(); + + //Tests behavior of should retry + Task shouldRetry = retryPolicy.ShouldRetryAsync(documentClientException, cancellationToken); + + Assert.IsTrue(shouldRetry.Result.ShouldRetry); + + //Now since the retry context is not null, should route to the hub region + retryPolicy.OnBeforeSendRequest(request); + Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location1Endpoint); + } + + /// /// Test to validate that when 429.3092 is thrown from the service, write requests on - /// a multi master account should be converted to 503 and retried to the next region. - /// + /// a multi master account should be converted to 503 and retried to the next region. + /// [TestMethod] [DataRow(true, DisplayName = "Validate retry policy with multi master write account.")] - [DataRow(false, DisplayName = "Validate retry policy with single master write account.")] + [DataRow(false, DisplayName = "Validate retry policy with single master write account.")] public async Task ShouldRetryAsync_WhenRequestThrottledWithResourceNotAvailable_ShouldThrow503OnMultiMasterWriteAndRetryOnNextRegion( - bool isMultiMasterAccount) + bool isMultiMasterAccount) { // Arrange. - const bool enableEndpointDiscovery = true; - using GlobalEndpointManager endpointManager = this.Initialize( - useMultipleWriteLocations: isMultiMasterAccount, - enableEndpointDiscovery: enableEndpointDiscovery, - isPreferredLocationsListEmpty: false, + const bool enableEndpointDiscovery = true; + using GlobalEndpointManager endpointManager = this.Initialize( + useMultipleWriteLocations: isMultiMasterAccount, + enableEndpointDiscovery: enableEndpointDiscovery, + isPreferredLocationsListEmpty: false, multimasterMetadataWriteRetryTest: true); - await endpointManager.RefreshLocationAsync(); - + await endpointManager.RefreshLocationAsync(); + ClientRetryPolicy retryPolicy = new ( endpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery, - false); - - // Creates a sample write request. + false); + + // Creates a sample write request. DocumentServiceRequest request = this.CreateRequest( isReadRequest: false, - isMasterResourceType: false); - - // On first attempt should get (default/non hub) location. - retryPolicy.OnBeforeSendRequest(request); - Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location1Endpoint); - - // Creation of 429.3092 Error. - HttpStatusCode throttleException = HttpStatusCode.TooManyRequests; + isMasterResourceType: false); + + // On first attempt should get (default/non hub) location. + retryPolicy.OnBeforeSendRequest(request); + Assert.AreEqual(request.RequestContext.LocationEndpointToRoute, ClientRetryPolicyTests.Location1Endpoint); + + // Creation of 429.3092 Error. + HttpStatusCode throttleException = HttpStatusCode.TooManyRequests; SubStatusCodes resourceNotAvailable = SubStatusCodes.SystemResourceUnavailable; - - Exception innerException = new (); - Mock nameValueCollection = new (); - DocumentClientException documentClientException = new ( - message: "SystemResourceUnavailable: 429 with 3092 occurred.", - innerException: innerException, - statusCode: throttleException, - substatusCode: resourceNotAvailable, - requestUri: request.RequestContext.LocationEndpointToRoute, - responseHeaders: nameValueCollection.Object); - - // Act. + + Exception innerException = new (); + Mock nameValueCollection = new (); + DocumentClientException documentClientException = new ( + message: "SystemResourceUnavailable: 429 with 3092 occurred.", + innerException: innerException, + statusCode: throttleException, + substatusCode: resourceNotAvailable, + requestUri: request.RequestContext.LocationEndpointToRoute, + responseHeaders: nameValueCollection.Object); + + // Act. Task shouldRetry = retryPolicy.ShouldRetryAsync( documentClientException, new CancellationToken()); @@ -153,85 +153,85 @@ public async Task ShouldRetryAsync_WhenRequestThrottledWithResourceNotAvailable_ actual: request.RequestContext.LocationEndpointToRoute, message: "The request should be routed to the next region, since the accound is a multi master write account and the request" + "failed with 429.309 which got converted into 503 internally. This should trigger another retry attempt to the next region."); - } + } else { Assert.AreEqual( expected: ClientRetryPolicyTests.Location1Endpoint, actual: request.RequestContext.LocationEndpointToRoute, message: "Since this is asingle master account, the write request should not be retried on the next region."); - } + } } - - /// - /// Tests to see if different 503 substatus codes are handeled correctly - /// - /// The substatus code being Tested. - [DataRow((int)SubStatusCodes.Unknown)] - [DataRow((int)SubStatusCodes.TransportGenerated503)] - [DataTestMethod] - public void Http503SubStatusHandelingTests(int testCode) - { - - const bool enableEndpointDiscovery = true; - //Create GlobalEndpointManager - using GlobalEndpointManager endpointManager = this.Initialize( - useMultipleWriteLocations: false, - enableEndpointDiscovery: enableEndpointDiscovery, - isPreferredLocationsListEmpty: true); - - //Create Retry Policy + + /// + /// Tests to see if different 503 substatus codes are handeled correctly + /// + /// The substatus code being Tested. + [DataRow((int)SubStatusCodes.Unknown)] + [DataRow((int)SubStatusCodes.TransportGenerated503)] + [DataTestMethod] + public void Http503SubStatusHandelingTests(int testCode) + { + + const bool enableEndpointDiscovery = true; + //Create GlobalEndpointManager + using GlobalEndpointManager endpointManager = this.Initialize( + useMultipleWriteLocations: false, + enableEndpointDiscovery: enableEndpointDiscovery, + isPreferredLocationsListEmpty: true); + + //Create Retry Policy ClientRetryPolicy retryPolicy = new ClientRetryPolicy(endpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery, false); - CancellationToken cancellationToken = new CancellationToken(); - Exception serviceUnavailableException = new Exception(); - Mock nameValueCollection = new Mock(); - - HttpStatusCode serviceUnavailable = HttpStatusCode.ServiceUnavailable; - - DocumentClientException documentClientException = new DocumentClientException( - message: "Service Unavailable", - innerException: serviceUnavailableException, - responseHeaders: nameValueCollection.Object, - statusCode: serviceUnavailable, - substatusCode: (SubStatusCodes)testCode, - requestUri: null - ); - - Task retryStatus = retryPolicy.ShouldRetryAsync(documentClientException, cancellationToken); - - Assert.IsFalse(retryStatus.Result.ShouldRetry); + CancellationToken cancellationToken = new CancellationToken(); + Exception serviceUnavailableException = new Exception(); + Mock nameValueCollection = new Mock(); + + HttpStatusCode serviceUnavailable = HttpStatusCode.ServiceUnavailable; + + DocumentClientException documentClientException = new DocumentClientException( + message: "Service Unavailable", + innerException: serviceUnavailableException, + responseHeaders: nameValueCollection.Object, + statusCode: serviceUnavailable, + substatusCode: (SubStatusCodes)testCode, + requestUri: null + ); + + Task retryStatus = retryPolicy.ShouldRetryAsync(documentClientException, cancellationToken); + + Assert.IsFalse(retryStatus.Result.ShouldRetry); } - /// + /// /// Tests to validate that when HttpRequestException is thrown while connecting to a gateway endpoint for a single master write account with PPAF enabled, - /// a partition level failover is added and the request is retried to the next region. - /// + /// a partition level failover is added and the request is retried to the next region. + /// [TestMethod] - [DataRow(true, DisplayName = "Case when partition level failover is enabled.")] - [DataRow(false, DisplayName = "Case when partition level failover is disabled.")] - + [DataRow(true, DisplayName = "Case when partition level failover is enabled.")] + [DataRow(false, DisplayName = "Case when partition level failover is disabled.")] + public void HttpRequestExceptionHandelingTests( - bool enablePartitionLevelFailover) + bool enablePartitionLevelFailover) { const bool enableEndpointDiscovery = true; const string suffix = "-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF"; //Creates a sample write request DocumentServiceRequest request = this.CreateRequest(false, false); - request.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange() { Id = "0" , MinInclusive = "3F" + suffix, MaxExclusive = "5F" + suffix }; - - //Create GlobalEndpointManager - using GlobalEndpointManager endpointManager = this.Initialize( - useMultipleWriteLocations: false, - enableEndpointDiscovery: enableEndpointDiscovery, + request.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange() { Id = "0" , MinInclusive = "3F" + suffix, MaxExclusive = "5F" + suffix }; + + //Create GlobalEndpointManager + using GlobalEndpointManager endpointManager = this.Initialize( + useMultipleWriteLocations: false, + enableEndpointDiscovery: enableEndpointDiscovery, isPreferredLocationsListEmpty: false, - enablePartitionLevelFailover: enablePartitionLevelFailover); + enablePartitionLevelFailover: enablePartitionLevelFailover); // Capture the read locations. ReadOnlyCollection readLocations = endpointManager.ReadEndpoints; - - //Create Retry Policy + + //Create Retry Policy ClientRetryPolicy retryPolicy = new ( globalEndpointManager: endpointManager, partitionKeyRangeLocationCache: this.partitionKeyRangeLocationCache, @@ -239,7 +239,7 @@ public void HttpRequestExceptionHandelingTests( enableEndpointDiscovery: enableEndpointDiscovery, isPertitionLevelFailoverEnabled: enablePartitionLevelFailover); - CancellationToken cancellationToken = new (); + CancellationToken cancellationToken = new (); HttpRequestException httpRequestException = new (message: "Connecting to endpoint has failed."); GlobalPartitionEndpointManagerCore.PartitionKeyRangeFailoverInfo partitionKeyRangeFailoverInfo = ClientRetryPolicyTests.GetPartitionKeyRangeFailoverInfoUsingReflection( @@ -249,7 +249,7 @@ public void HttpRequestExceptionHandelingTests( // Validate that the partition key range failover info is not present before the http request exception was captured in the retry policy. Assert.IsNull(partitionKeyRangeFailoverInfo); - retryPolicy.OnBeforeSendRequest(request); + retryPolicy.OnBeforeSendRequest(request); Task retryStatus = retryPolicy.ShouldRetryAsync(httpRequestException, cancellationToken); Assert.IsTrue(retryStatus.Result.ShouldRetry); @@ -267,168 +267,168 @@ public void HttpRequestExceptionHandelingTests( { Assert.IsNull(partitionKeyRangeFailoverInfo); } + } + + [TestMethod] + public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); + } + + [TestMethod] + public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + } + + [TestMethod] + public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + } + + [TestMethod] + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); + } + + [TestMethod] + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + } + + [TestMethod] + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + } + + [TestMethod] + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + } + + [TestMethod] + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() + { + await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } - - [TestMethod] - public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); - } - - [TestMethod] - public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); - } - - [TestMethod] - public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); - } - - [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); - } - - [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); - } - - [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); - } - - [TestMethod] - public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); - } - - [TestMethod] - public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() - { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); - } - - private async Task ValidateConnectTimeoutTriggersClientRetryPolicy( - bool isReadRequest, - bool useMultipleWriteLocations, - bool usesPreferredLocations, - bool shouldHaveRetried) - { - List newPhysicalUris = new List(); - newPhysicalUris.Add("https://default.documents.azure.com"); - newPhysicalUris.Add("https://location1.documents.azure.com"); - newPhysicalUris.Add("https://location2.documents.azure.com"); - newPhysicalUris.Add("https://location3.documents.azure.com"); - - Dictionary uriToException = new Dictionary(); - uriToException.Add(new Uri("https://default.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://default.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); - uriToException.Add(new Uri("https://location1.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location1.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); - uriToException.Add(new Uri("https://location2.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location2.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); - uriToException.Add(new Uri("https://location3.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location3.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); - - using MockDocumentClientContext mockDocumentClientContext = this.InitializeMockedDocumentClient(useMultipleWriteLocations, !usesPreferredLocations); - mockDocumentClientContext.GlobalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(mockDocumentClientContext.DatabaseAccount); - - MockAddressResolver mockAddressResolver = new MockAddressResolver(newPhysicalUris, newPhysicalUris); - SessionContainer sessionContainer = new SessionContainer("localhost"); - MockTransportClient mockTransportClient = new MockTransportClient(null, uriToException); - MockServiceConfigurationReader mockServiceConfigurationReader = new MockServiceConfigurationReader(); - MockAuthorizationTokenProvider mockAuthorizationTokenProvider = new MockAuthorizationTokenProvider(); - - ReplicatedResourceClient replicatedResourceClient = new ReplicatedResourceClient( - addressResolver: mockAddressResolver, - sessionContainer: sessionContainer, - protocol: Protocol.Tcp, - transportClient: mockTransportClient, - serviceConfigReader: mockServiceConfigurationReader, - authorizationTokenProvider: mockAuthorizationTokenProvider, - enableReadRequestsFallback: false, - useMultipleWriteLocations: useMultipleWriteLocations, - detectClientConnectivityIssues: true, - disableRetryWithRetryPolicy: false, - enableReplicaValidation: false); - - // Reducing retry timeout to avoid long-running tests - replicatedResourceClient.GoneAndRetryWithRetryTimeoutInSecondsOverride = 1; - - this.partitionKeyRangeLocationCache = GlobalPartitionEndpointManagerNoOp.Instance; - - ClientRetryPolicy retryPolicy = new ClientRetryPolicy(mockDocumentClientContext.GlobalEndpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery: true, isPertitionLevelFailoverEnabled: false); - - INameValueCollection headers = new DictionaryNameValueCollection(); - headers.Set(HttpConstants.HttpHeaders.ConsistencyLevel, ConsistencyLevel.BoundedStaleness.ToString()); - - using (DocumentServiceRequest request = DocumentServiceRequest.Create( - isReadRequest ? OperationType.Read : OperationType.Create, - ResourceType.Document, - "dbs/OVJwAA==/colls/OVJwAOcMtA0=/docs/OVJwAOcMtA0BAAAAAAAAAA==/", - AuthorizationTokenType.PrimaryMasterKey, - headers)) - { - int retryCount = 0; - - try - { - await BackoffRetryUtility.ExecuteAsync( - () => - { - retryPolicy.OnBeforeSendRequest(request); - - if (retryCount == 1) - { - Uri expectedEndpoint = null; - if (usesPreferredLocations) - { - expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.ReadLocationsInternal.First(l => l.Name == mockDocumentClientContext.PreferredLocations[1]).Endpoint); - } - else - { - if (isReadRequest) - { - expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.ReadLocationsInternal[1].Endpoint); - } - else - { - expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.WriteLocationsInternal[1].Endpoint); - } - } - - Assert.AreEqual(expectedEndpoint, request.RequestContext.LocationEndpointToRoute); - } - else if (retryCount > 1) - { - Assert.Fail("Should retry once"); - } - - retryCount++; - - return replicatedResourceClient.InvokeAsync(request); - }, - retryPolicy); - - Assert.Fail(); - } - catch (ServiceUnavailableException) - { - if (shouldHaveRetried) - { - Assert.AreEqual(2, retryCount, $"Retry count {retryCount}, shouldHaveRetried {shouldHaveRetried} isReadRequest {isReadRequest} useMultipleWriteLocations {useMultipleWriteLocations} usesPreferredLocations {usesPreferredLocations}"); - } - else - { - Assert.AreEqual(1, retryCount, $"Retry count {retryCount}, shouldHaveRetried {shouldHaveRetried} isReadRequest {isReadRequest} useMultipleWriteLocations {useMultipleWriteLocations} usesPreferredLocations {usesPreferredLocations}"); - } - } - } + + private async Task ValidateConnectTimeoutTriggersClientRetryPolicy( + bool isReadRequest, + bool useMultipleWriteLocations, + bool usesPreferredLocations, + bool shouldHaveRetried) + { + List newPhysicalUris = new List(); + newPhysicalUris.Add("https://default.documents.azure.com"); + newPhysicalUris.Add("https://location1.documents.azure.com"); + newPhysicalUris.Add("https://location2.documents.azure.com"); + newPhysicalUris.Add("https://location3.documents.azure.com"); + + Dictionary uriToException = new Dictionary(); + uriToException.Add(new Uri("https://default.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://default.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); + uriToException.Add(new Uri("https://location1.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location1.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); + uriToException.Add(new Uri("https://location2.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location2.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); + uriToException.Add(new Uri("https://location3.documents.azure.com"), new GoneException(new TransportException(TransportErrorCode.ConnectTimeout, innerException: null, activityId: Guid.NewGuid(), requestUri: new Uri("https://location3.documents.azure.com"), sourceDescription: "description", userPayload: true, payloadSent: true), SubStatusCodes.TransportGenerated410)); + + using MockDocumentClientContext mockDocumentClientContext = this.InitializeMockedDocumentClient(useMultipleWriteLocations, !usesPreferredLocations); + mockDocumentClientContext.GlobalEndpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(mockDocumentClientContext.DatabaseAccount); + + MockAddressResolver mockAddressResolver = new MockAddressResolver(newPhysicalUris, newPhysicalUris); + SessionContainer sessionContainer = new SessionContainer("localhost"); + MockTransportClient mockTransportClient = new MockTransportClient(null, uriToException); + MockServiceConfigurationReader mockServiceConfigurationReader = new MockServiceConfigurationReader(); + MockAuthorizationTokenProvider mockAuthorizationTokenProvider = new MockAuthorizationTokenProvider(); + + ReplicatedResourceClient replicatedResourceClient = new ReplicatedResourceClient( + addressResolver: mockAddressResolver, + sessionContainer: sessionContainer, + protocol: Protocol.Tcp, + transportClient: mockTransportClient, + serviceConfigReader: mockServiceConfigurationReader, + authorizationTokenProvider: mockAuthorizationTokenProvider, + enableReadRequestsFallback: false, + useMultipleWriteLocations: useMultipleWriteLocations, + detectClientConnectivityIssues: true, + disableRetryWithRetryPolicy: false, + enableReplicaValidation: false); + + // Reducing retry timeout to avoid long-running tests + replicatedResourceClient.GoneAndRetryWithRetryTimeoutInSecondsOverride = 1; + + this.partitionKeyRangeLocationCache = GlobalPartitionEndpointManagerNoOp.Instance; + + ClientRetryPolicy retryPolicy = new ClientRetryPolicy(mockDocumentClientContext.GlobalEndpointManager, this.partitionKeyRangeLocationCache, new RetryOptions(), enableEndpointDiscovery: true, isPertitionLevelFailoverEnabled: false); + + INameValueCollection headers = new DictionaryNameValueCollection(); + headers.Set(HttpConstants.HttpHeaders.ConsistencyLevel, ConsistencyLevel.BoundedStaleness.ToString()); + + using (DocumentServiceRequest request = DocumentServiceRequest.Create( + isReadRequest ? OperationType.Read : OperationType.Create, + ResourceType.Document, + "dbs/OVJwAA==/colls/OVJwAOcMtA0=/docs/OVJwAOcMtA0BAAAAAAAAAA==/", + AuthorizationTokenType.PrimaryMasterKey, + headers)) + { + int retryCount = 0; + + try + { + await BackoffRetryUtility.ExecuteAsync( + () => + { + retryPolicy.OnBeforeSendRequest(request); + + if (retryCount == 1) + { + Uri expectedEndpoint = null; + if (usesPreferredLocations) + { + expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.ReadLocationsInternal.First(l => l.Name == mockDocumentClientContext.PreferredLocations[1]).Endpoint); + } + else + { + if (isReadRequest) + { + expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.ReadLocationsInternal[1].Endpoint); + } + else + { + expectedEndpoint = new Uri(mockDocumentClientContext.DatabaseAccount.WriteLocationsInternal[1].Endpoint); + } + } + + Assert.AreEqual(expectedEndpoint, request.RequestContext.LocationEndpointToRoute); + } + else if (retryCount > 1) + { + Assert.Fail("Should retry once"); + } + + retryCount++; + + return replicatedResourceClient.InvokeAsync(request); + }, + retryPolicy); + + Assert.Fail(); + } + catch (ServiceUnavailableException) + { + if (shouldHaveRetried) + { + Assert.AreEqual(2, retryCount, $"Retry count {retryCount}, shouldHaveRetried {shouldHaveRetried} isReadRequest {isReadRequest} useMultipleWriteLocations {useMultipleWriteLocations} usesPreferredLocations {usesPreferredLocations}"); + } + else + { + Assert.AreEqual(1, retryCount, $"Retry count {retryCount}, shouldHaveRetried {shouldHaveRetried} isReadRequest {isReadRequest} useMultipleWriteLocations {useMultipleWriteLocations} usesPreferredLocations {usesPreferredLocations}"); + } + } + } } private static GlobalPartitionEndpointManagerCore.PartitionKeyRangeFailoverInfo GetPartitionKeyRangeFailoverInfoUsingReflection( @@ -451,374 +451,374 @@ private static GlobalPartitionEndpointManagerCore.PartitionKeyRangeFailoverInfo return null; } - - private static AccountProperties CreateDatabaseAccount( - bool useMultipleWriteLocations, - bool enforceSingleMasterSingleWriteLocation) - { - Collection writeLocations = new Collection() - { - { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } }, - { new AccountRegion() { Name = "location2", Endpoint = ClientRetryPolicyTests.Location2Endpoint.ToString() } }, - }; - - if (!useMultipleWriteLocations - && enforceSingleMasterSingleWriteLocation) - { - // Some pre-existing tests depend on the account having multiple write locations even on single master setup - // Newer tests can correctly define a single master account (single write region) without breaking existing tests - writeLocations = new Collection() - { - { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } } - }; - } - - AccountProperties databaseAccount = new AccountProperties() - { - EnableMultipleWriteLocations = useMultipleWriteLocations, - ReadLocationsInternal = new Collection() - { - { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } }, - { new AccountRegion() { Name = "location2", Endpoint = ClientRetryPolicyTests.Location2Endpoint.ToString() } }, - }, - WriteLocationsInternal = writeLocations - }; - - return databaseAccount; - } - - private GlobalEndpointManager Initialize( - bool useMultipleWriteLocations, - bool enableEndpointDiscovery, - bool isPreferredLocationsListEmpty, - bool enforceSingleMasterSingleWriteLocation = false, // Some tests depend on the Initialize to create an account with multiple write locations, even when not multi master - ReadOnlyCollection preferedRegionListOverride = null, - bool enablePartitionLevelFailover = false, - bool multimasterMetadataWriteRetryTest = false) - { - this.databaseAccount = ClientRetryPolicyTests.CreateDatabaseAccount( - useMultipleWriteLocations, - enforceSingleMasterSingleWriteLocation); - - if (isPreferredLocationsListEmpty) - { - this.preferredLocations = new List().AsReadOnly(); - } - else - { - // Allow for override at the test method level if needed - this.preferredLocations = preferedRegionListOverride != null ? preferedRegionListOverride : new List() - { - "location1", - "location2" - }.AsReadOnly(); - } - - if (!multimasterMetadataWriteRetryTest) - { - this.mockedClient = new Mock(); - mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(ClientRetryPolicyTests.Location1Endpoint); - mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(this.databaseAccount); - } - else - { - this.mockedClient = new Mock(); - mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(ClientRetryPolicyTests.Location2Endpoint); - mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(this.databaseAccount); - } - - ConnectionPolicy connectionPolicy = new ConnectionPolicy() - { - EnableEndpointDiscovery = enableEndpointDiscovery, - UseMultipleWriteLocations = useMultipleWriteLocations, - }; - - foreach (string preferredLocation in this.preferredLocations) - { - connectionPolicy.PreferredLocations.Add(preferredLocation); - } - - GlobalEndpointManager endpointManager = new GlobalEndpointManager(this.mockedClient.Object, connectionPolicy); - endpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(this.databaseAccount); - - if (enablePartitionLevelFailover) - { - this.partitionKeyRangeLocationCache = new GlobalPartitionEndpointManagerCore(endpointManager); - } - else - { - this.partitionKeyRangeLocationCache = GlobalPartitionEndpointManagerNoOp.Instance; - } - - return endpointManager; - } - - private DocumentServiceRequest CreateRequest(bool isReadRequest, bool isMasterResourceType) - { - if (isReadRequest) - { - return DocumentServiceRequest.Create(OperationType.Read, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); - } - else - { - return DocumentServiceRequest.Create(OperationType.Create, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); - } - } - - private MockDocumentClientContext InitializeMockedDocumentClient( - bool useMultipleWriteLocations, - bool isPreferredLocationsListEmpty) - { - AccountProperties databaseAccount = new AccountProperties() - { - EnableMultipleWriteLocations = useMultipleWriteLocations, - ReadLocationsInternal = new Collection() - { - { new AccountRegion() { Name = "location1", Endpoint = new Uri("https://location1.documents.azure.com").ToString() } }, - { new AccountRegion() { Name = "location2", Endpoint = new Uri("https://location2.documents.azure.com").ToString() } }, - { new AccountRegion() { Name = "location3", Endpoint = new Uri("https://location3.documents.azure.com").ToString() } }, - }, - WriteLocationsInternal = new Collection() - { - { new AccountRegion() { Name = "location1", Endpoint = new Uri("https://location1.documents.azure.com").ToString() } }, - { new AccountRegion() { Name = "location2", Endpoint = new Uri("https://location2.documents.azure.com").ToString() } }, - { new AccountRegion() { Name = "location3", Endpoint = new Uri("https://location3.documents.azure.com").ToString() } }, - } - }; - - MockDocumentClientContext mockDocumentClientContext = new MockDocumentClientContext(); - mockDocumentClientContext.DatabaseAccount = databaseAccount; - - mockDocumentClientContext.PreferredLocations = isPreferredLocationsListEmpty ? new List().AsReadOnly() : new List() - { - "location1", - "location3" - }.AsReadOnly(); - - mockDocumentClientContext.LocationCache = new LocationCache( - mockDocumentClientContext.PreferredLocations, - new Uri("https://default.documents.azure.com"), - true, - 10, - useMultipleWriteLocations); - - mockDocumentClientContext.LocationCache.OnDatabaseAccountRead(mockDocumentClientContext.DatabaseAccount); - - Mock mockedClient = new Mock(); - mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://default.documents.azure.com")); - mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(mockDocumentClientContext.DatabaseAccount); - - ConnectionPolicy connectionPolicy = new ConnectionPolicy() - { - UseMultipleWriteLocations = useMultipleWriteLocations, - }; - - foreach (string preferredLocation in mockDocumentClientContext.PreferredLocations) - { - connectionPolicy.PreferredLocations.Add(preferredLocation); - } - - mockDocumentClientContext.DocumentClientInternal = mockedClient.Object; - mockDocumentClientContext.GlobalEndpointManager = new GlobalEndpointManager(mockDocumentClientContext.DocumentClientInternal, connectionPolicy); - return mockDocumentClientContext; - } - private class MockDocumentClientContext : IDisposable - { - public IDocumentClientInternal DocumentClientInternal { get; set; } - public GlobalEndpointManager GlobalEndpointManager { get; set; } - public LocationCache LocationCache { get; set; } - public ReadOnlyCollection PreferredLocations { get; set; } - public AccountProperties DatabaseAccount { get; set; } - - public void Dispose() - { - this.GlobalEndpointManager.Dispose(); - } - } - - private class MockAddressResolver : IAddressResolverExtension - { - private List oldAddressInformations; - private List newAddressInformations; - - public int NumberOfRefreshes { get; set; } - - public MockAddressResolver(List oldPhysicalUris, List newPhysicalUris) - { - this.NumberOfRefreshes = 0; - this.oldAddressInformations = new List(); - - for (int i = 0; i < oldPhysicalUris.Count; i++) - { - this.oldAddressInformations.Add(new AddressInformation( - isPrimary: i == 0, - isPublic: true, - physicalUri: oldPhysicalUris[i], - protocol: Protocol.Tcp)); - } - - this.newAddressInformations = new List(); - for (int i = 0; i < newPhysicalUris.Count; i++) - { - this.newAddressInformations.Add(new AddressInformation( - isPrimary: i == 0, - isPublic: true, - physicalUri: newPhysicalUris[i], - protocol: Protocol.Tcp)); - } - } - - public Task ResolveAsync(DocumentServiceRequest request, bool forceRefreshPartitionAddresses, CancellationToken cancellationToken) - { - List addressInformations = new List(); - request.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange() { Id = "0" }; - if (forceRefreshPartitionAddresses) - { - this.NumberOfRefreshes++; - return Task.FromResult(new PartitionAddressInformation(this.newAddressInformations.ToArray())); - } - - return Task.FromResult(new PartitionAddressInformation(this.oldAddressInformations.ToArray())); - } - - public Task UpdateAsync(IReadOnlyList addressCacheTokens, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public Task OpenConnectionsToAllReplicasAsync( - string databaseName, - string containerLinkUri, - CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public Task UpdateAsync(Documents.Rntbd.ServerKey serverKey, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public void SetOpenConnectionsHandler( - IOpenConnectionsHandler openConnectionHandler) - { - throw new NotImplementedException(); - } - } - - private class MockTransportClient : TransportClient - { - private Dictionary uriToStoreResponseMap; - private Dictionary uriToExceptionMap; - - public MockTransportClient( - Dictionary uriToStoreResponseMap, - Dictionary uriToExceptionMap) - { - this.uriToStoreResponseMap = uriToStoreResponseMap; - this.uriToExceptionMap = uriToExceptionMap; - } - - internal override Task InvokeStoreAsync(Uri physicalAddress, ResourceOperation resourceOperation, DocumentServiceRequest request) - { - if (this.uriToStoreResponseMap != null && this.uriToStoreResponseMap.ContainsKey(physicalAddress)) - { - return Task.FromResult(this.uriToStoreResponseMap[physicalAddress]); - } - - if (this.uriToExceptionMap != null && this.uriToExceptionMap.ContainsKey(physicalAddress)) - { - throw this.uriToExceptionMap[physicalAddress]; - } - - throw new InvalidOperationException(); - } - } - - private class MockServiceConfigurationReader : IServiceConfigurationReader - { - - public string DatabaseAccountId - { - get { return "localhost"; } - } - - public Uri DatabaseAccountApiEndpoint { get; private set; } - - public ReplicationPolicy UserReplicationPolicy - { - get { return new ReplicationPolicy(); } - } - - public ReplicationPolicy SystemReplicationPolicy - { - get { return new ReplicationPolicy(); } - } - - public ConsistencyLevel DefaultConsistencyLevel - { - get { return ConsistencyLevel.BoundedStaleness; } - } - - public ReadPolicy ReadPolicy - { - get { return new ReadPolicy(); } - } - - public string PrimaryMasterKey - { - get { return "key"; } - } - - public string SecondaryMasterKey - { - get { return "key"; } - } - - public string PrimaryReadonlyMasterKey - { - get { return "key"; } - } - - public string SecondaryReadonlyMasterKey - { - get { return "key"; } - } - - public string ResourceSeedKey - { - get { return "seed"; } - } - - public string SubscriptionId - { - get { return Guid.Empty.ToString(); } - } - - public Task InitializeAsync() - { - return Task.FromResult(true); - } - } - private class MockAuthorizationTokenProvider : IAuthorizationTokenProvider - { - public ValueTask<(string token, string payload)> GetUserAuthorizationAsync( - string resourceAddress, - string resourceType, - string requestVerb, - INameValueCollection headers, - AuthorizationTokenType tokenType) - { - return new ValueTask<(string token, string payload)>(("authtoken!", null)); - } - - public Task AddSystemAuthorizationHeaderAsync(DocumentServiceRequest request, string federationId, string verb, string resourceId) - { - request.Headers[HttpConstants.HttpHeaders.XDate] = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture); - request.Headers[HttpConstants.HttpHeaders.Authorization] = "authtoken!"; - return Task.FromResult(0); - } - } - - } -} + + private static AccountProperties CreateDatabaseAccount( + bool useMultipleWriteLocations, + bool enforceSingleMasterSingleWriteLocation) + { + Collection writeLocations = new Collection() + { + { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } }, + { new AccountRegion() { Name = "location2", Endpoint = ClientRetryPolicyTests.Location2Endpoint.ToString() } }, + }; + + if (!useMultipleWriteLocations + && enforceSingleMasterSingleWriteLocation) + { + // Some pre-existing tests depend on the account having multiple write locations even on single master setup + // Newer tests can correctly define a single master account (single write region) without breaking existing tests + writeLocations = new Collection() + { + { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } } + }; + } + + AccountProperties databaseAccount = new AccountProperties() + { + EnableMultipleWriteLocations = useMultipleWriteLocations, + ReadLocationsInternal = new Collection() + { + { new AccountRegion() { Name = "location1", Endpoint = ClientRetryPolicyTests.Location1Endpoint.ToString() } }, + { new AccountRegion() { Name = "location2", Endpoint = ClientRetryPolicyTests.Location2Endpoint.ToString() } }, + }, + WriteLocationsInternal = writeLocations + }; + + return databaseAccount; + } + + private GlobalEndpointManager Initialize( + bool useMultipleWriteLocations, + bool enableEndpointDiscovery, + bool isPreferredLocationsListEmpty, + bool enforceSingleMasterSingleWriteLocation = false, // Some tests depend on the Initialize to create an account with multiple write locations, even when not multi master + ReadOnlyCollection preferedRegionListOverride = null, + bool enablePartitionLevelFailover = false, + bool multimasterMetadataWriteRetryTest = false) + { + this.databaseAccount = ClientRetryPolicyTests.CreateDatabaseAccount( + useMultipleWriteLocations, + enforceSingleMasterSingleWriteLocation); + + if (isPreferredLocationsListEmpty) + { + this.preferredLocations = new List().AsReadOnly(); + } + else + { + // Allow for override at the test method level if needed + this.preferredLocations = preferedRegionListOverride != null ? preferedRegionListOverride : new List() + { + "location1", + "location2" + }.AsReadOnly(); + } + + if (!multimasterMetadataWriteRetryTest) + { + this.mockedClient = new Mock(); + mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(ClientRetryPolicyTests.Location1Endpoint); + mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(this.databaseAccount); + } + else + { + this.mockedClient = new Mock(); + mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(ClientRetryPolicyTests.Location2Endpoint); + mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(this.databaseAccount); + } + + ConnectionPolicy connectionPolicy = new ConnectionPolicy() + { + EnableEndpointDiscovery = enableEndpointDiscovery, + UseMultipleWriteLocations = useMultipleWriteLocations, + }; + + foreach (string preferredLocation in this.preferredLocations) + { + connectionPolicy.PreferredLocations.Add(preferredLocation); + } + + GlobalEndpointManager endpointManager = new GlobalEndpointManager(this.mockedClient.Object, connectionPolicy); + endpointManager.InitializeAccountPropertiesAndStartBackgroundRefresh(this.databaseAccount); + + if (enablePartitionLevelFailover) + { + this.partitionKeyRangeLocationCache = new GlobalPartitionEndpointManagerCore(endpointManager); + } + else + { + this.partitionKeyRangeLocationCache = GlobalPartitionEndpointManagerNoOp.Instance; + } + + return endpointManager; + } + + private DocumentServiceRequest CreateRequest(bool isReadRequest, bool isMasterResourceType) + { + if (isReadRequest) + { + return DocumentServiceRequest.Create(OperationType.Read, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); + } + else + { + return DocumentServiceRequest.Create(OperationType.Create, isMasterResourceType ? ResourceType.Database : ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); + } + } + + private MockDocumentClientContext InitializeMockedDocumentClient( + bool useMultipleWriteLocations, + bool isPreferredLocationsListEmpty) + { + AccountProperties databaseAccount = new AccountProperties() + { + EnableMultipleWriteLocations = useMultipleWriteLocations, + ReadLocationsInternal = new Collection() + { + { new AccountRegion() { Name = "location1", Endpoint = new Uri("https://location1.documents.azure.com").ToString() } }, + { new AccountRegion() { Name = "location2", Endpoint = new Uri("https://location2.documents.azure.com").ToString() } }, + { new AccountRegion() { Name = "location3", Endpoint = new Uri("https://location3.documents.azure.com").ToString() } }, + }, + WriteLocationsInternal = new Collection() + { + { new AccountRegion() { Name = "location1", Endpoint = new Uri("https://location1.documents.azure.com").ToString() } }, + { new AccountRegion() { Name = "location2", Endpoint = new Uri("https://location2.documents.azure.com").ToString() } }, + { new AccountRegion() { Name = "location3", Endpoint = new Uri("https://location3.documents.azure.com").ToString() } }, + } + }; + + MockDocumentClientContext mockDocumentClientContext = new MockDocumentClientContext(); + mockDocumentClientContext.DatabaseAccount = databaseAccount; + + mockDocumentClientContext.PreferredLocations = isPreferredLocationsListEmpty ? new List().AsReadOnly() : new List() + { + "location1", + "location3" + }.AsReadOnly(); + + mockDocumentClientContext.LocationCache = new LocationCache( + mockDocumentClientContext.PreferredLocations, + new Uri("https://default.documents.azure.com"), + true, + 10, + useMultipleWriteLocations); + + mockDocumentClientContext.LocationCache.OnDatabaseAccountRead(mockDocumentClientContext.DatabaseAccount); + + Mock mockedClient = new Mock(); + mockedClient.Setup(owner => owner.ServiceEndpoint).Returns(new Uri("https://default.documents.azure.com")); + mockedClient.Setup(owner => owner.GetDatabaseAccountInternalAsync(It.IsAny(), It.IsAny())).ReturnsAsync(mockDocumentClientContext.DatabaseAccount); + + ConnectionPolicy connectionPolicy = new ConnectionPolicy() + { + UseMultipleWriteLocations = useMultipleWriteLocations, + }; + + foreach (string preferredLocation in mockDocumentClientContext.PreferredLocations) + { + connectionPolicy.PreferredLocations.Add(preferredLocation); + } + + mockDocumentClientContext.DocumentClientInternal = mockedClient.Object; + mockDocumentClientContext.GlobalEndpointManager = new GlobalEndpointManager(mockDocumentClientContext.DocumentClientInternal, connectionPolicy); + return mockDocumentClientContext; + } + private class MockDocumentClientContext : IDisposable + { + public IDocumentClientInternal DocumentClientInternal { get; set; } + public GlobalEndpointManager GlobalEndpointManager { get; set; } + public LocationCache LocationCache { get; set; } + public ReadOnlyCollection PreferredLocations { get; set; } + public AccountProperties DatabaseAccount { get; set; } + + public void Dispose() + { + this.GlobalEndpointManager.Dispose(); + } + } + + private class MockAddressResolver : IAddressResolverExtension + { + private List oldAddressInformations; + private List newAddressInformations; + + public int NumberOfRefreshes { get; set; } + + public MockAddressResolver(List oldPhysicalUris, List newPhysicalUris) + { + this.NumberOfRefreshes = 0; + this.oldAddressInformations = new List(); + + for (int i = 0; i < oldPhysicalUris.Count; i++) + { + this.oldAddressInformations.Add(new AddressInformation( + isPrimary: i == 0, + isPublic: true, + physicalUri: oldPhysicalUris[i], + protocol: Protocol.Tcp)); + } + + this.newAddressInformations = new List(); + for (int i = 0; i < newPhysicalUris.Count; i++) + { + this.newAddressInformations.Add(new AddressInformation( + isPrimary: i == 0, + isPublic: true, + physicalUri: newPhysicalUris[i], + protocol: Protocol.Tcp)); + } + } + + public Task ResolveAsync(DocumentServiceRequest request, bool forceRefreshPartitionAddresses, CancellationToken cancellationToken) + { + List addressInformations = new List(); + request.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange() { Id = "0" }; + if (forceRefreshPartitionAddresses) + { + this.NumberOfRefreshes++; + return Task.FromResult(new PartitionAddressInformation(this.newAddressInformations.ToArray())); + } + + return Task.FromResult(new PartitionAddressInformation(this.oldAddressInformations.ToArray())); + } + + public Task UpdateAsync(IReadOnlyList addressCacheTokens, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task OpenConnectionsToAllReplicasAsync( + string databaseName, + string containerLinkUri, + CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(Documents.Rntbd.ServerKey serverKey, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public void SetOpenConnectionsHandler( + IOpenConnectionsHandler openConnectionHandler) + { + throw new NotImplementedException(); + } + } + + private class MockTransportClient : TransportClient + { + private Dictionary uriToStoreResponseMap; + private Dictionary uriToExceptionMap; + + public MockTransportClient( + Dictionary uriToStoreResponseMap, + Dictionary uriToExceptionMap) + { + this.uriToStoreResponseMap = uriToStoreResponseMap; + this.uriToExceptionMap = uriToExceptionMap; + } + + internal override Task InvokeStoreAsync(Uri physicalAddress, ResourceOperation resourceOperation, DocumentServiceRequest request) + { + if (this.uriToStoreResponseMap != null && this.uriToStoreResponseMap.ContainsKey(physicalAddress)) + { + return Task.FromResult(this.uriToStoreResponseMap[physicalAddress]); + } + + if (this.uriToExceptionMap != null && this.uriToExceptionMap.ContainsKey(physicalAddress)) + { + throw this.uriToExceptionMap[physicalAddress]; + } + + throw new InvalidOperationException(); + } + } + + private class MockServiceConfigurationReader : IServiceConfigurationReader + { + + public string DatabaseAccountId + { + get { return "localhost"; } + } + + public Uri DatabaseAccountApiEndpoint { get; private set; } + + public ReplicationPolicy UserReplicationPolicy + { + get { return new ReplicationPolicy(); } + } + + public ReplicationPolicy SystemReplicationPolicy + { + get { return new ReplicationPolicy(); } + } + + public ConsistencyLevel DefaultConsistencyLevel + { + get { return ConsistencyLevel.BoundedStaleness; } + } + + public ReadPolicy ReadPolicy + { + get { return new ReadPolicy(); } + } + + public string PrimaryMasterKey + { + get { return "key"; } + } + + public string SecondaryMasterKey + { + get { return "key"; } + } + + public string PrimaryReadonlyMasterKey + { + get { return "key"; } + } + + public string SecondaryReadonlyMasterKey + { + get { return "key"; } + } + + public string ResourceSeedKey + { + get { return "seed"; } + } + + public string SubscriptionId + { + get { return Guid.Empty.ToString(); } + } + + public Task InitializeAsync() + { + return Task.FromResult(true); + } + } + private class MockAuthorizationTokenProvider : IAuthorizationTokenProvider + { + public ValueTask<(string token, string payload)> GetUserAuthorizationAsync( + string resourceAddress, + string resourceType, + string requestVerb, + INameValueCollection headers, + AuthorizationTokenType tokenType) + { + return new ValueTask<(string token, string payload)>(("authtoken!", null)); + } + + public Task AddSystemAuthorizationHeaderAsync(DocumentServiceRequest request, string federationId, string verb, string resourceId) + { + request.Headers[HttpConstants.HttpHeaders.XDate] = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture); + request.Headers[HttpConstants.HttpHeaders.Authorization] = "authtoken!"; + return Task.FromResult(0); + } + } + + } +} From 8b0f3683f5fe0ff1e76ff6cbe2d4933538b53217 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Wed, 2 Oct 2024 15:00:46 -0700 Subject: [PATCH 3/6] Addressing new warnings --- .../Query/NonStreamingOrderByQueryTests.cs | 2 +- ...angeFeedPartitionKeyResultSetIteratorCoreTests.cs | 6 ++++++ .../Query/Pipeline/NonStreamingOrderByQueryTests.cs | 12 +----------- .../Routing/PartitionKeyHash.cs | 2 ++ 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs index c21f76d610..abf9261351 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs @@ -324,9 +324,9 @@ private sealed class Document private static class DebugTraceHelpers { +#pragma warning disable CS0162, CS0649 // Unreachable code detected private const bool Enabled = false; -#pragma warning disable CS0162 // Unreachable code detected public static void TraceSupportedFeaturesString(string supportedQueryFeatures) { if (Enabled) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs index 5f8a9903bf..8de33c9c0a 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs @@ -40,6 +40,7 @@ public async Task EtagPassesContinuation() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -59,6 +60,7 @@ public async Task EtagPassesContinuation() return func(trace); } }); +#pragma warning restore CA1416 mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), @@ -121,6 +123,7 @@ public async Task NextReadHasUpdatedContinuation() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -140,6 +143,7 @@ public async Task NextReadHasUpdatedContinuation() return func(trace); } }); +#pragma warning restore CA1416 mockContext.SetupSequence(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), @@ -192,6 +196,7 @@ public async Task ShouldSetFeedRangePartitionKeyRange() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -211,6 +216,7 @@ public async Task ShouldSetFeedRangePartitionKeyRange() return func(trace); } }); +#pragma warning restore CA1416 mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs index 2799fd60f5..46753d3a49 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs @@ -727,19 +727,9 @@ private async Task SplitMergeAsync() private static class DebugTraceHelpers { +#pragma warning disable CS0162, CS0649 // Unreachable code detected private static readonly bool Enabled; - static DebugTraceHelpers() - { - DebugTraceHelpers.Enabled = false; - if (Debugger.IsAttached) - { - // Hack to workaround the non-reachable warning - DebugTraceHelpers.Enabled = true; - } - } -#pragma warning disable CS0162 // Unreachable code detected - [Conditional("DEBUG")] public static void TraceSplit(FeedRangeInternal feedRange) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs index 0d7189abb2..6b098d5440 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs @@ -76,10 +76,12 @@ public override bool Equals(object obj) return false; } +#pragma warning disable CA2013 // value boxing, also this check seems redundant (future todo) if (object.ReferenceEquals(this, obj)) { return true; } +#pragma warning restore CA2013 return this.Equals(effectivePartitionKey); } From 336a9d569068c6b4ab8c85b57af9d670e04a08ac Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Wed, 2 Oct 2024 15:09:25 -0700 Subject: [PATCH 4/6] Addressing some more issues --- .../CosmosClientOptionsUnitTests.cs | 5 ++++- .../Microsoft.Azure.Cosmos.Tests.csproj | 1 + .../Query/SubpartitionTests.cs | 14 +++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs index 34a8445cfb..2434eccb70 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs @@ -1074,7 +1074,10 @@ public void TestServerCertificatesValidationWithDisableSSLFlagTrue(string connSt CosmosHttpClient httpClient = cosmosClient.DocumentClient.httpClient; SocketsHttpHandler socketsHttpHandler = (SocketsHttpHandler)httpClient.HttpMessageHandler; - Assert.IsNotNull(socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback); +#nullable enable + RemoteCertificateValidationCallback? httpClientRemoreCertValidationCallback = socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback; + Assert.IsNotNull(httpClientRemoreCertValidationCallback); +#nullable disable } private class TestWebProxy : IWebProxy diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj index 5a5cfa28d2..12773b7493 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj @@ -10,6 +10,7 @@ false Microsoft.Azure.Cosmos.Tests $(LangVersion) + true diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs index b306281ae0..2cdaedfc37 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SubpartitionTests.cs @@ -22,9 +22,9 @@ using Microsoft.Azure.Cosmos.Tests.Pagination; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; - using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; - + [TestClass] public class SubpartitionTests : BaselineTests { @@ -136,7 +136,7 @@ private static IQueryPipelineStage CreateQueryPipelineStage( partitionedQueryExecutionInfo: null, returnResultsInDeterministicOrder: null, enableOptimisticDirectExecution: queryRequestOptions.EnableOptimisticDirectExecution, - isNonStreamingOrderByQueryFeatureDisabled: queryRequestOptions.IsNonStreamingOrderByQueryFeatureDisabled, + isNonStreamingOrderByQueryFeatureDisabled: queryRequestOptions.IsNonStreamingOrderByQueryFeatureDisabled, enableDistributedQueryGatewayMode: queryRequestOptions.EnableDistributedQueryGatewayMode, testInjections: queryRequestOptions.TestSettings); @@ -161,8 +161,8 @@ private static IQueryPipelineStage CreateQueryPipelineStage( isContinuationExpected: true, allowNonValueAggregateQuery: true, useSystemPrefix: false, - correlatedActivityId: Guid.NewGuid()); - + correlatedActivityId: Guid.NewGuid()); + IQueryPipelineStage queryPipelineStage = CosmosQueryExecutionContextFactory.Create( documentContainer, cosmosQueryContextCore, @@ -177,7 +177,7 @@ internal static Tuple Get QueryPartitionProvider queryPartitionProvider = CreateCustomQueryPartitionProvider(); TryCatch tryGetQueryPlan = queryPartitionProvider.TryGetPartitionedQueryExecutionInfo( querySpecJsonString: querySpecJsonString, - partitionKeyDefinition: pkDefinition, + partitionKeyDefinition: pkDefinition, vectorEmbeddingPolicy: null, requireFormattableOrderByQuery: true, isContinuationExpected: true, @@ -332,7 +332,7 @@ public override Task GetCachedContainerQueryProperties true, true) }, - SubpartitionTests.CreatePartitionKeyDefinition(), + SubpartitionTests.CreatePartitionKeyDefinition(), vectorEmbeddingPolicy: null, Cosmos.GeospatialType.Geometry)); } From a805c358b2a4789a002253cbcd1f85a0ca5c73d9 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Wed, 2 Oct 2024 16:21:56 -0700 Subject: [PATCH 5/6] Renmaing method with Async suffix --- .../ClientRetryPolicyTests.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index e2591eeac4..0b2e625972 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -270,49 +270,49 @@ public void HttpRequestExceptionHandelingTests( } [TestMethod] - public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); } [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } [TestMethod] - public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocationsAsync() { await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } From 03ab87f8f5138f62c7775e97abbb48a7dea97975 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kolli Date: Wed, 2 Oct 2024 16:45:44 -0700 Subject: [PATCH 6/6] Adding Async suffix to the helper method as well --- .../ClientRetryPolicyTests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index 0b2e625972..0c7c332854 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -272,52 +272,52 @@ public void HttpRequestExceptionHandelingTests( [TestMethod] public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); } [TestMethod] public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } [TestMethod] public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocationsAsync() { - await this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } - private async Task ValidateConnectTimeoutTriggersClientRetryPolicy( + private async Task ValidateConnectTimeoutTriggersClientRetryPolicyAsync( bool isReadRequest, bool useMultipleWriteLocations, bool usesPreferredLocations,