From c2043ae85c2cb11c1c2c7a46f88c0473f73c43a2 Mon Sep 17 00:00:00 2001 From: Nalu Tripician <27316859+NaluTripician@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:45:54 -0400 Subject: [PATCH] [Internal] Request Hedging: Refactors HedgeRegion diagnostics field to only show successful region (#4625) * changed hedge region to only show sucessfull region * added and updated tests * discussion changes * suggestions and test improvements * test fix * updated hedge context * fix test * no string conversion * requested changes * suggested changes * remove and sort usings --- ...gionParallelHedgingAvailabilityStrategy.cs | 80 ++++++----- .../CosmosAvailabilityStrategyTests.cs | 130 ++++++++---------- .../AvailabilityStrategyUnitTests.cs | 62 +++++++++ .../Telemetry/OpenTelemetryRecorderTests.cs | 12 +- 4 files changed, 172 insertions(+), 112 deletions(-) create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/AvailabilityStrategyUnitTests.cs diff --git a/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionParallelHedgingAvailabilityStrategy.cs b/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionParallelHedgingAvailabilityStrategy.cs index 2821b9759c..418bbc36e8 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionParallelHedgingAvailabilityStrategy.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionParallelHedgingAvailabilityStrategy.cs @@ -23,10 +23,8 @@ namespace Microsoft.Azure.Cosmos /// internal class CrossRegionParallelHedgingAvailabilityStrategy : AvailabilityStrategy { - private const string HedgeRegions = "Hedge Regions"; private const string HedgeContext = "Hedge Context"; - private const string HedgeContextOriginalRequest = "Original Request"; - private const string HedgeContextHedgedRequest = "Hedged Request"; + private const string ResponseRegion = "Response Region"; /// /// Latency threshold which activates the first region hedging @@ -123,9 +121,8 @@ public override async Task ExecuteAvailabilityStrategyAsync( List requestTasks = new List(hedgeRegions.Count + 1); - Task<(bool, ResponseMessage)> primaryRequest = null; - - ResponseMessage responseMessage = null; + Task primaryRequest = null; + HedgingResponse hedgeResponse = null; //Send out hedged requests for (int requestNumber = 0; requestNumber < hedgeRegions.Count; requestNumber++) @@ -142,6 +139,7 @@ public override async Task ExecuteAvailabilityStrategyAsync( primaryRequest = this.RequestSenderAndResultCheckAsync( sender, request, + hedgeRegions.ElementAt(requestNumber), cancellationToken, cancellationTokenSource); @@ -149,7 +147,7 @@ public override async Task ExecuteAvailabilityStrategyAsync( } else { - Task<(bool, ResponseMessage)> requestTask = this.CloneAndSendAsync( + Task requestTask = this.CloneAndSendAsync( sender: sender, request: request, clonedBody: clonedBody, @@ -180,19 +178,18 @@ public override async Task ExecuteAvailabilityStrategyAsync( AggregateException innerExceptions = completedTask.Exception.Flatten(); } - (bool isNonTransient, responseMessage) = await (Task<(bool, ResponseMessage)>)completedTask; - if (isNonTransient) + hedgeResponse = await (Task)completedTask; + if (hedgeResponse.IsNonTransient) { cancellationTokenSource.Cancel(); - ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value.AddOrUpdateDatum( - HedgeRegions, - HedgeRegionsToString(responseMessage.Diagnostics.GetContactedRegions())); - ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value.AddOrUpdateDatum( + //Take is not inclusive, so we need to add 1 to the request number which starts at 0 + ((CosmosTraceDiagnostics)hedgeResponse.ResponseMessage.Diagnostics).Value.AddOrUpdateDatum( HedgeContext, - object.ReferenceEquals(primaryRequest, completedTask) - ? HedgeContextOriginalRequest - : HedgeContextHedgedRequest); - return responseMessage; + hedgeRegions.Take(requestNumber + 1)); + ((CosmosTraceDiagnostics)hedgeResponse.ResponseMessage.Diagnostics).Value.AddOrUpdateDatum( + ResponseRegion, + hedgeResponse.ResponseRegion); + return hedgeResponse.ResponseMessage; } } } @@ -210,19 +207,17 @@ public override async Task ExecuteAvailabilityStrategyAsync( lastException = innerExceptions.InnerExceptions.FirstOrDefault(); } - (bool isNonTransient, responseMessage) = await (Task<(bool, ResponseMessage)>)completedTask; - if (isNonTransient || requestTasks.Count == 0) + hedgeResponse = await (Task)completedTask; + if (hedgeResponse.IsNonTransient || requestTasks.Count == 0) { cancellationTokenSource.Cancel(); - ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value.AddOrUpdateDatum( - HedgeRegions, - HedgeRegionsToString(responseMessage.Diagnostics.GetContactedRegions())); - ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value.AddOrUpdateDatum( + ((CosmosTraceDiagnostics)hedgeResponse.ResponseMessage.Diagnostics).Value.AddOrUpdateDatum( HedgeContext, - object.ReferenceEquals(primaryRequest, completedTask) - ? HedgeContextOriginalRequest - : HedgeContextHedgedRequest); - return responseMessage; + hedgeRegions); + ((CosmosTraceDiagnostics)hedgeResponse.ResponseMessage.Diagnostics).Value.AddOrUpdateDatum( + ResponseRegion, + hedgeResponse.ResponseRegion); + return hedgeResponse.ResponseMessage; } } @@ -231,13 +226,13 @@ public override async Task ExecuteAvailabilityStrategyAsync( throw lastException; } - Debug.Assert(responseMessage != null); - return responseMessage; + Debug.Assert(hedgeResponse != null); + return hedgeResponse.ResponseMessage; } } } - private async Task<(bool, ResponseMessage)> CloneAndSendAsync( + private async Task CloneAndSendAsync( Func> sender, RequestMessage request, CloneableStream clonedBody, @@ -256,20 +251,23 @@ public override async Task ExecuteAvailabilityStrategyAsync( clonedRequest.RequestOptions ??= new RequestOptions(); List excludeRegions = new List(hedgeRegions); + string region = excludeRegions[requestNumber]; excludeRegions.RemoveAt(requestNumber); clonedRequest.RequestOptions.ExcludeRegions = excludeRegions; return await this.RequestSenderAndResultCheckAsync( sender, clonedRequest, + region, cancellationToken, cancellationTokenSource); } } - private async Task<(bool, ResponseMessage)> RequestSenderAndResultCheckAsync( + private async Task RequestSenderAndResultCheckAsync( Func> sender, RequestMessage request, + string hedgedRegion, CancellationToken cancellationToken, CancellationTokenSource cancellationTokenSource) { @@ -282,14 +280,15 @@ public override async Task ExecuteAvailabilityStrategyAsync( { cancellationTokenSource.Cancel(); } - return (true, response); + + return new HedgingResponse(true, response, hedgedRegion); } - return (false, response); + return new HedgingResponse(false, response, hedgedRegion); } catch (OperationCanceledException) when (cancellationTokenSource.IsCancellationRequested) { - return (false, null); + return new HedgingResponse(false, null, hedgedRegion); } catch (Exception ex) { @@ -323,9 +322,18 @@ private static bool IsFinalResult(int statusCode, int subStatusCode) return statusCode == (int)HttpStatusCode.NotFound && subStatusCode == (int)SubStatusCodes.Unknown; } - private static string HedgeRegionsToString(IReadOnlyList<(string, Uri)> hedgeRegions) + private sealed class HedgingResponse { - return string.Join(",", hedgeRegions); + public readonly bool IsNonTransient; + public readonly ResponseMessage ResponseMessage; + public readonly string ResponseRegion; + + public HedgingResponse(bool isNonTransient, ResponseMessage responseMessage, string responseRegion) + { + this.IsNonTransient = isNonTransient; + this.ResponseMessage = responseMessage; + this.ResponseRegion = responseRegion; + } } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs index 64ad968d86..7994a06507 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs @@ -5,7 +5,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Collections.Generic; using System.Data; using System.IO; - using System.Net.Http; + using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; @@ -14,7 +14,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Diagnostics; using Microsoft.Azure.Cosmos.FaultInjection; - using Microsoft.Azure.Documents; using Microsoft.VisualStudio.TestTools.UnitTesting; using Database = Database; using PartitionKey = PartitionKey; @@ -22,6 +21,9 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests [TestClass] public class CosmosAvailabilityStrategyTests { + private const string centralUS = "Central US"; + private const string northCentralUS = "North Central US"; + private const string eastUs = "East US"; private CosmosClient client; private Database database; @@ -184,7 +186,21 @@ public async Task AvailabilityStrategyNoTriggerTest() .WithDuration(TimeSpan.FromMinutes(90)) .Build(); - List rules = new List() { responseDelay }; + FaultInjectionRule responseDelay2 = new FaultInjectionRuleBuilder( + id: "responseDely", + condition: + new FaultInjectionConditionBuilder() + .WithRegion("North Central US") + .WithOperationType(FaultInjectionOperationType.ReadItem) + .Build(), + result: + FaultInjectionResultBuilder.GetResultBuilder(FaultInjectionServerErrorType.ResponseDelay) + .WithDelay(TimeSpan.FromMilliseconds(3000)) + .Build()) + .WithDuration(TimeSpan.FromMinutes(90)) + .Build(); + + List rules = new List() { responseDelay, responseDelay2 }; FaultInjector faultInjector = new FaultInjector(rules); responseDelay.Disable(); @@ -194,7 +210,7 @@ public async Task AvailabilityStrategyNoTriggerTest() ConnectionMode = ConnectionMode.Direct, ApplicationPreferredRegions = new List() { "Central US", "North Central US" }, AvailabilityStrategy = new CrossRegionParallelHedgingAvailabilityStrategy( - threshold: TimeSpan.FromMilliseconds(1500), + threshold: TimeSpan.FromMilliseconds(300), thresholdStep: TimeSpan.FromMilliseconds(50)), Serializer = this.cosmosSystemTextJsonSerializer }; @@ -211,10 +227,18 @@ public async Task AvailabilityStrategyNoTriggerTest() CosmosTraceDiagnostics traceDiagnostic = ir.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out object responseRegion); + Assert.IsNotNull(responseRegion); + Assert.AreEqual(centralUS, (string)responseRegion); + + //Should send out hedge request but original should be returned traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out object hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Original Request", (string)hedgeContext); - + IReadOnlyCollection hedgeContextList; + hedgeContextList = hedgeContext as IReadOnlyCollection; + Assert.AreEqual(2, hedgeContextList.Count); + Assert.IsTrue(hedgeContextList.Contains(centralUS)); + Assert.IsTrue(hedgeContextList.Contains(northCentralUS)); faultInjectionClient.Dispose(); } @@ -270,10 +294,9 @@ public async Task AvailabilityStrategyRequestOptionsTriggerTest() CosmosTraceDiagnostics traceDiagnostic = ir.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out object hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out object hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); - faultInjectionClient.Dispose(); + Assert.AreEqual(northCentralUS, (string)hedgeContext); } [TestMethod] @@ -331,6 +354,8 @@ public async Task AvailabilityStrategyDisableOverideTest() CosmosTraceDiagnostics traceDiagnostic = ir.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); + Assert.IsFalse(traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out _)); + faultInjectionClient.Dispose(); } @@ -430,9 +455,9 @@ public async Task AvailabilityStrategyAllFaultsTests(string operation, string co Assert.IsTrue(rule.GetHitCount() > 0); traceDiagnostic = ir.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(northCentralUS, (string)hedgeContext); break; @@ -457,9 +482,9 @@ public async Task AvailabilityStrategyAllFaultsTests(string operation, string co Assert.IsTrue(rule.GetHitCount() > 0); traceDiagnostic = feedResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(northCentralUS, (string)hedgeContext); } break; @@ -478,9 +503,9 @@ public async Task AvailabilityStrategyAllFaultsTests(string operation, string co Assert.IsTrue(rule.GetHitCount() > 0); traceDiagnostic = feedResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(northCentralUS, (string)hedgeContext); } break; @@ -500,9 +525,9 @@ public async Task AvailabilityStrategyAllFaultsTests(string operation, string co Assert.IsTrue(rule.GetHitCount() > 0); traceDiagnostic = readManyResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(northCentralUS, (string)hedgeContext); break; @@ -608,9 +633,9 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito traceDiagnostic = ir.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(eastUs, (string)hedgeContext); break; @@ -635,9 +660,9 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito traceDiagnostic = feedResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(eastUs, (string)hedgeContext); } break; @@ -656,9 +681,9 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito traceDiagnostic = feedResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(eastUs, (string)hedgeContext); } break; @@ -678,9 +703,9 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito traceDiagnostic = readManyResponse.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); + Assert.AreEqual(eastUs, (string)hedgeContext); break; @@ -720,50 +745,6 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito faultInjectionClient.Dispose(); } - [TestMethod] - [TestCategory("MultiRegion")] - public async Task RequestMessageCloneTests() - { - RequestMessage httpRequest = new RequestMessage( - HttpMethod.Get, - new Uri("/dbs/testdb/colls/testcontainer/docs/testId", UriKind.Relative)); - - string key = Guid.NewGuid().ToString(); - Dictionary properties = new Dictionary() - { - { key, Guid.NewGuid() } - }; - - RequestOptions requestOptions = new RequestOptions() - { - Properties = properties - }; - - httpRequest.RequestOptions = requestOptions; - httpRequest.ResourceType = ResourceType.Document; - httpRequest.OperationType = OperationType.Read; - httpRequest.Headers.CorrelatedActivityId = Guid.NewGuid().ToString(); - httpRequest.PartitionKeyRangeId = new PartitionKeyRangeIdentity("0", "1"); - httpRequest.UseGatewayMode = true; - httpRequest.ContainerId = "testcontainer"; - httpRequest.DatabaseId = "testdb"; - httpRequest.Content = Stream.Null; - - using (CloneableStream clonedBody = await StreamExtension.AsClonableStreamAsync(httpRequest.Content)) - { - RequestMessage clone = httpRequest.Clone(httpRequest.Trace, clonedBody); - - Assert.AreEqual(httpRequest.RequestOptions.Properties, clone.RequestOptions.Properties); - Assert.AreEqual(httpRequest.ResourceType, clone.ResourceType); - Assert.AreEqual(httpRequest.OperationType, clone.OperationType); - Assert.AreEqual(httpRequest.Headers.CorrelatedActivityId, clone.Headers.CorrelatedActivityId); - Assert.AreEqual(httpRequest.PartitionKeyRangeId, clone.PartitionKeyRangeId); - Assert.AreEqual(httpRequest.UseGatewayMode, clone.UseGatewayMode); - Assert.AreEqual(httpRequest.ContainerId, clone.ContainerId); - Assert.AreEqual(httpRequest.DatabaseId, clone.DatabaseId); - } - } - private static async Task HandleChangesAsync( ChangeFeedProcessorContext context, IReadOnlyCollection changes, @@ -776,10 +757,9 @@ private static async Task HandleChangesAsync( CosmosTraceDiagnostics traceDiagnostic = context.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out object hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out object hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); - + Assert.AreNotEqual(centralUS, (string)hedgeContext); await Task.Delay(1); } @@ -795,10 +775,10 @@ private static async Task HandleChangesStepAsync( CosmosTraceDiagnostics traceDiagnostic = context.Diagnostics as CosmosTraceDiagnostics; Assert.IsNotNull(traceDiagnostic); - traceDiagnostic.Value.Data.TryGetValue("Hedge Context", out object hedgeContext); + traceDiagnostic.Value.Data.TryGetValue("Response Region", out object hedgeContext); Assert.IsNotNull(hedgeContext); - Assert.AreEqual("Hedged Request", (string)hedgeContext); - + Assert.AreNotEqual(centralUS, (string)hedgeContext); + Assert.AreNotEqual(northCentralUS, (string)hedgeContext); await Task.Delay(1); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/AvailabilityStrategyUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/AvailabilityStrategyUnitTests.cs new file mode 100644 index 0000000000..8566fb6dd6 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/AvailabilityStrategyUnitTests.cs @@ -0,0 +1,62 @@ +namespace Microsoft.Azure.Cosmos.Tests +{ + using System; + using System.Collections.Concurrent; + using System.Collections.Generic; + using System.IO; + using System.Net.Http; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos; + using Microsoft.Azure.Documents; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// Tests for + /// + [TestClass] + public class AvailabilityStrategyUnitTests + { + [TestMethod] + public async Task RequestMessageCloneTests() + { + RequestMessage httpRequest = new RequestMessage( + HttpMethod.Get, + new Uri("/dbs/testdb/colls/testcontainer/docs/testId", UriKind.Relative)); + + string key = Guid.NewGuid().ToString(); + Dictionary properties = new Dictionary() + { + { key, Guid.NewGuid() } + }; + + RequestOptions requestOptions = new RequestOptions() + { + Properties = properties + }; + + httpRequest.RequestOptions = requestOptions; + httpRequest.ResourceType = ResourceType.Document; + httpRequest.OperationType = OperationType.Read; + httpRequest.Headers.CorrelatedActivityId = Guid.NewGuid().ToString(); + httpRequest.PartitionKeyRangeId = new PartitionKeyRangeIdentity("0", "1"); + httpRequest.UseGatewayMode = true; + httpRequest.ContainerId = "testcontainer"; + httpRequest.DatabaseId = "testdb"; + httpRequest.Content = Stream.Null; + + using (CloneableStream clonedBody = await StreamExtension.AsClonableStreamAsync(httpRequest.Content)) + { + RequestMessage clone = httpRequest.Clone(httpRequest.Trace, clonedBody); + + Assert.AreEqual(httpRequest.RequestOptions.Properties, clone.RequestOptions.Properties); + Assert.AreEqual(httpRequest.ResourceType, clone.ResourceType); + Assert.AreEqual(httpRequest.OperationType, clone.OperationType); + Assert.AreEqual(httpRequest.Headers.CorrelatedActivityId, clone.Headers.CorrelatedActivityId); + Assert.AreEqual(httpRequest.PartitionKeyRangeId, clone.PartitionKeyRangeId); + Assert.AreEqual(httpRequest.UseGatewayMode, clone.UseGatewayMode); + Assert.AreEqual(httpRequest.ContainerId, clone.ContainerId); + Assert.AreEqual(httpRequest.DatabaseId, clone.DatabaseId); + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs index 50c0e425a5..fa6dcf693d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Telemetry using System; using System.Collections.Generic; using System.Collections.ObjectModel; + using System.Diagnostics; using System.Linq; using System.Net; using System.Reflection; @@ -18,6 +19,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Telemetry using Microsoft.Azure.Cosmos.Tracing; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; + using static Microsoft.Azure.Cosmos.CrossRegionParallelHedgingAvailabilityStrategy; [TestClass] public class OpenTelemetryRecorderTests @@ -86,7 +88,8 @@ public async Task CheckResponseCompatibility() { "StoredProcedureExecuteResponse`1",new Mock>().Object }, { "StoredProcedureResponse", new Mock().Object }, { "TriggerResponse", new Mock().Object }, - { "UserDefinedFunctionResponse", new Mock().Object } + { "UserDefinedFunctionResponse", new Mock().Object }, + { "HedgingResponse", "HedgingResponse" }, }; Assembly asm = OpenTelemetryRecorderTests.GetAssemblyLocally(DllName); @@ -165,6 +168,13 @@ public async Task CheckResponseCompatibility() { _ = new OpenTelemetryResponse>(storedProcedureExecuteResponse); } + else if (instance is string hedgingResponse) + { + Assert.AreEqual( + "HedgingResponse", + hedgingResponse, + "HedgingResponse is only used internally in the CrossRegionParallelHedgingAvailabilityStrategy and is never returned. No support Needed."); + } else { Assert.Fail("Opentelemetry does not support this response type " + className.Name);