From 2de73b2c12d071a0ccdf33ba5f4200cbc165ba2c Mon Sep 17 00:00:00 2001 From: Tom Biddulph Date: Wed, 1 Nov 2023 19:20:52 +0000 Subject: [PATCH] [repo] Update dotnet format ci job (#4881) Co-authored-by: Reiley Yang Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/dotnet-format.yml | 5 +- ...njectionLoggerProviderBuilderExtensions.cs | 8 +- ...ctionLoggingServiceCollectionExtensions.cs | 4 +- ...InjectionMeterProviderBuilderExtensions.cs | 4 +- ...njectionTracerProviderBuilderExtensions.cs | 4 +- .../Implementation/ExportClient/OtlpRetry.cs | 4 +- .../LoggerProviderBuilderExtensions.cs | 4 +- .../Builder/MeterProviderBuilderExtensions.cs | 4 +- .../TracerProviderBuilderExtensions.cs | 8 +- src/Shared/PeerServiceResolver.cs | 133 ++++--- .../OtlpMetricsExporterTests.cs | 2 +- .../OtlpRetryTests.cs | 337 +++++++++--------- .../W3CTraceContextTests.cs | 2 +- 13 files changed, 257 insertions(+), 262 deletions(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 69d4b91343f..fb09d11d10f 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -23,8 +23,5 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Install format tool - run: dotnet tool install -g dotnet-format - - name: dotnet format - run: dotnet-format --folder --check + run: dotnet format OpenTelemetry.sln --verify-no-changes diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs index e113baa8cd4..98897f3a8ce 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions.cs @@ -27,11 +27,11 @@ namespace OpenTelemetry.Logs; /// Contains extension methods for the class. /// #if EXPOSE_EXPERIMENTAL_FEATURES - public +public #else internal #endif - static class OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions +static class OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions { #if EXPOSE_EXPERIMENTAL_FEATURES /// @@ -59,9 +59,9 @@ static class OpenTelemetryDependencyInjectionLoggerProviderBuilderExtensions #endif public static LoggerProviderBuilder AddInstrumentation< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this LoggerProviderBuilder loggerProviderBuilder) + T>(this LoggerProviderBuilder loggerProviderBuilder) where T : class { loggerProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs index 14102cf30da..6683cf4de9e 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Logs/OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions.cs @@ -23,11 +23,11 @@ namespace OpenTelemetry.Logs; /// Extension methods for setting up OpenTelemetry logging services in an . /// #if EXPOSE_EXPERIMENTAL_FEATURES - public +public #else internal #endif - static class OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions +static class OpenTelemetryDependencyInjectionLoggingServiceCollectionExtensions { #if EXPOSE_EXPERIMENTAL_FEATURES /// diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Metrics/OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Metrics/OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.cs index d2d32637eb4..81b0fd57bd3 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Metrics/OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Metrics/OpenTelemetryDependencyInjectionMeterProviderBuilderExtensions.cs @@ -40,9 +40,9 @@ public static class OpenTelemetryDependencyInjectionMeterProviderBuilderExtensio /// The supplied for chaining. public static MeterProviderBuilder AddInstrumentation< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this MeterProviderBuilder meterProviderBuilder) + T>(this MeterProviderBuilder meterProviderBuilder) where T : class { meterProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Trace/OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Trace/OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.cs index e3cdfd6bad3..0d6ec709f16 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/Trace/OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/Trace/OpenTelemetryDependencyInjectionTracerProviderBuilderExtensions.cs @@ -40,9 +40,9 @@ public static class OpenTelemetryDependencyInjectionTracerProviderBuilderExtensi /// The supplied for chaining. public static TracerProviderBuilder AddInstrumentation< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this TracerProviderBuilder tracerProviderBuilder) + T>(this TracerProviderBuilder tracerProviderBuilder) where T : class { tracerProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpRetry.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpRetry.cs index e65a1204925..b4d1f7232fb 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpRetry.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpRetry.cs @@ -67,12 +67,12 @@ internal static class OtlpRetry public static bool TryGetHttpRetryResult(HttpStatusCode statusCode, DateTime? deadline, HttpResponseHeaders responseHeaders, int retryDelayMilliseconds, out RetryResult retryResult) { - return OtlpRetry.TryGetRetryResult(statusCode, IsHttpStatusCodeRetryable, deadline, responseHeaders, TryGetHttpRetryDelay, retryDelayMilliseconds, out retryResult); + return TryGetRetryResult(statusCode, IsHttpStatusCodeRetryable, deadline, responseHeaders, TryGetHttpRetryDelay, retryDelayMilliseconds, out retryResult); } public static bool TryGetGrpcRetryResult(StatusCode statusCode, DateTime? deadline, Metadata trailers, int retryDelayMilliseconds, out RetryResult retryResult) { - return OtlpRetry.TryGetRetryResult(statusCode, IsGrpcStatusCodeRetryable, deadline, trailers, TryGetGrpcRetryDelay, retryDelayMilliseconds, out retryResult); + return TryGetRetryResult(statusCode, IsGrpcStatusCodeRetryable, deadline, trailers, TryGetGrpcRetryDelay, retryDelayMilliseconds, out retryResult); } private static bool TryGetRetryResult(TStatusCode statusCode, Func isRetryable, DateTime? deadline, TCarrier carrier, Func throttleGetter, int nextRetryDelayMilliseconds, out RetryResult retryResult) diff --git a/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs b/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs index bc4e122005c..ea28f79a6fb 100644 --- a/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Logs/Builder/LoggerProviderBuilderExtensions.cs @@ -165,9 +165,9 @@ public static LoggerProviderBuilder AddProcessor(this LoggerProviderBuilder logg #endif public static LoggerProviderBuilder AddProcessor< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this LoggerProviderBuilder loggerProviderBuilder) + T>(this LoggerProviderBuilder loggerProviderBuilder) where T : BaseProcessor { loggerProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 5e49ac68687..d5c979604bf 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -64,9 +64,9 @@ public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProv /// The supplied for chaining. public static MeterProviderBuilder AddReader< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this MeterProviderBuilder meterProviderBuilder) + T>(this MeterProviderBuilder meterProviderBuilder) where T : MetricReader { meterProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs index 01acef414c4..c071d9552cc 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs @@ -83,9 +83,9 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracer /// The supplied for chaining. public static TracerProviderBuilder SetSampler< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this TracerProviderBuilder tracerProviderBuilder) + T>(this TracerProviderBuilder tracerProviderBuilder) where T : Sampler { tracerProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); @@ -203,9 +203,9 @@ public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder trac /// The supplied for chaining. public static TracerProviderBuilder AddProcessor< #if NET6_0_OR_GREATER - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] #endif - T>(this TracerProviderBuilder tracerProviderBuilder) + T>(this TracerProviderBuilder tracerProviderBuilder) where T : BaseProcessor { tracerProviderBuilder.ConfigureServices(services => services.TryAddSingleton()); diff --git a/src/Shared/PeerServiceResolver.cs b/src/Shared/PeerServiceResolver.cs index 3227bb1e700..869554bb81e 100644 --- a/src/Shared/PeerServiceResolver.cs +++ b/src/Shared/PeerServiceResolver.cs @@ -19,90 +19,89 @@ using System.Runtime.CompilerServices; using OpenTelemetry.Trace; -namespace OpenTelemetry.Exporter +namespace OpenTelemetry.Exporter; + +internal static class PeerServiceResolver { - internal static class PeerServiceResolver + private static readonly Dictionary PeerServiceKeyResolutionDictionary = new(StringComparer.OrdinalIgnoreCase) { - private static readonly Dictionary PeerServiceKeyResolutionDictionary = new(StringComparer.OrdinalIgnoreCase) - { - [SemanticConventions.AttributePeerService] = 0, // priority 0 (highest). - ["peer.hostname"] = 1, - ["peer.address"] = 1, - [SemanticConventions.AttributeHttpHost] = 2, // peer.service for Http. - [SemanticConventions.AttributeDbInstance] = 2, // peer.service for Redis. - }; + [SemanticConventions.AttributePeerService] = 0, // priority 0 (highest). + ["peer.hostname"] = 1, + ["peer.address"] = 1, + [SemanticConventions.AttributeHttpHost] = 2, // peer.service for Http. + [SemanticConventions.AttributeDbInstance] = 2, // peer.service for Redis. + }; - public interface IPeerServiceState - { - string? PeerService { get; set; } + public interface IPeerServiceState + { + string? PeerService { get; set; } - int? PeerServicePriority { get; set; } + int? PeerServicePriority { get; set; } - string? HostName { get; set; } + string? HostName { get; set; } - string? IpAddress { get; set; } + string? IpAddress { get; set; } - long Port { get; set; } - } + long Port { get; set; } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void InspectTag(ref T state, string key, string? value) - where T : struct, IPeerServiceState + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InspectTag(ref T state, string key, string? value) + where T : struct, IPeerServiceState + { + if (PeerServiceKeyResolutionDictionary.TryGetValue(key, out int priority) + && (state.PeerService == null || priority < state.PeerServicePriority)) { - if (PeerServiceKeyResolutionDictionary.TryGetValue(key, out int priority) - && (state.PeerService == null || priority < state.PeerServicePriority)) - { - state.PeerService = value; - state.PeerServicePriority = priority; - } - else if (key == SemanticConventions.AttributeNetPeerName) - { - state.HostName = value; - } - else if (key == SemanticConventions.AttributeNetPeerIp) - { - state.IpAddress = value; - } - else if (key == SemanticConventions.AttributeNetPeerPort && long.TryParse(value, out var port)) - { - state.Port = port; - } + state.PeerService = value; + state.PeerServicePriority = priority; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void InspectTag(ref T state, string key, long value) - where T : struct, IPeerServiceState + else if (key == SemanticConventions.AttributeNetPeerName) { - if (key == SemanticConventions.AttributeNetPeerPort) - { - state.Port = value; - } + state.HostName = value; + } + else if (key == SemanticConventions.AttributeNetPeerIp) + { + state.IpAddress = value; + } + else if (key == SemanticConventions.AttributeNetPeerPort && long.TryParse(value, out var port)) + { + state.Port = port; } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Resolve(ref T state, out string? peerServiceName, out bool addAsTag) - where T : struct, IPeerServiceState + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InspectTag(ref T state, string key, long value) + where T : struct, IPeerServiceState + { + if (key == SemanticConventions.AttributeNetPeerPort) { - peerServiceName = state.PeerService; + state.Port = value; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Resolve(ref T state, out string? peerServiceName, out bool addAsTag) + where T : struct, IPeerServiceState + { + peerServiceName = state.PeerService; - // If priority = 0 that means peer.service was included in tags - addAsTag = state.PeerServicePriority != 0; + // If priority = 0 that means peer.service was included in tags + addAsTag = state.PeerServicePriority != 0; - if (addAsTag) - { - var hostNameOrIpAddress = state.HostName ?? state.IpAddress; + if (addAsTag) + { + var hostNameOrIpAddress = state.HostName ?? state.IpAddress; - // peer.service has not already been included, but net.peer.name/ip and optionally net.peer.port are present - if (hostNameOrIpAddress != null) - { - peerServiceName = state.Port == default - ? hostNameOrIpAddress - : $"{hostNameOrIpAddress}:{state.Port}"; - } - else if (state.PeerService != null) - { - peerServiceName = state.PeerService; - } + // peer.service has not already been included, but net.peer.name/ip and optionally net.peer.port are present + if (hostNameOrIpAddress != null) + { + peerServiceName = state.Port == default + ? hostNameOrIpAddress + : $"{hostNameOrIpAddress}:{state.Port}"; + } + else if (state.PeerService != null) + { + peerServiceName = state.PeerService; } } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index 5f77818c202..bdac11c2eb1 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -60,7 +60,7 @@ public void TestAddOtlpExporter_SetsCorrectMetricReaderDefaults() void CheckMetricReaderDefaults() { - var bindingFlags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance; + var bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; var metricReader = typeof(MetricReader) .Assembly diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs index a5909d763d9..3540bce76f5 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpRetryTests.cs @@ -19,198 +19,197 @@ using Grpc.Core; using Xunit; -namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient.Tests +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient.Tests; + +public class OtlpRetryTests { - public class OtlpRetryTests + public static IEnumerable GrpcRetryTestData => GrpcRetryTestCase.GetTestCases(); + + [Theory] + [MemberData(nameof(GrpcRetryTestData))] + public void TryGetGrpcRetryResultTest(GrpcRetryTestCase testCase) { - public static IEnumerable GrpcRetryTestData => GrpcRetryTestCase.GetTestCases(); + var attempts = 0; + var nextRetryDelayMilliseconds = OtlpRetry.InitialBackoffMilliseconds; - [Theory] - [MemberData(nameof(GrpcRetryTestData))] - public void TryGetGrpcRetryResultTest(GrpcRetryTestCase testCase) + foreach (var retryAttempt in testCase.RetryAttempts) { - var attempts = 0; - var nextRetryDelayMilliseconds = OtlpRetry.InitialBackoffMilliseconds; + ++attempts; + var statusCode = retryAttempt.RpcException.StatusCode; + var deadline = retryAttempt.CallOptions.Deadline; + var trailers = retryAttempt.RpcException.Trailers; + var success = OtlpRetry.TryGetGrpcRetryResult(statusCode, deadline, trailers, nextRetryDelayMilliseconds, out var retryResult); + + Assert.Equal(retryAttempt.ExpectedSuccess, success); + + if (!success) + { + Assert.Equal(testCase.ExpectedRetryAttempts, attempts); + break; + } - foreach (var retryAttempt in testCase.RetryAttempts) + if (retryResult.Throttled) + { + Assert.Equal(retryAttempt.ThrottleDelay, retryResult.RetryDelay); + } + else { - ++attempts; - var statusCode = retryAttempt.RpcException.StatusCode; - var deadline = retryAttempt.CallOptions.Deadline; - var trailers = retryAttempt.RpcException.Trailers; - var success = OtlpRetry.TryGetGrpcRetryResult(statusCode, deadline, trailers, nextRetryDelayMilliseconds, out var retryResult); - - Assert.Equal(retryAttempt.ExpectedSuccess, success); - - if (!success) - { - Assert.Equal(testCase.ExpectedRetryAttempts, attempts); - break; - } - - if (retryResult.Throttled) - { - Assert.Equal(retryAttempt.ThrottleDelay, retryResult.RetryDelay); - } - else - { - Assert.True(retryResult.RetryDelay >= TimeSpan.Zero); - Assert.True(retryResult.RetryDelay < TimeSpan.FromMilliseconds(nextRetryDelayMilliseconds)); - } - - Assert.Equal(retryAttempt.ExpectedNextRetryDelayMilliseconds, retryResult.NextRetryDelayMilliseconds); - - nextRetryDelayMilliseconds = retryResult.NextRetryDelayMilliseconds; + Assert.True(retryResult.RetryDelay >= TimeSpan.Zero); + Assert.True(retryResult.RetryDelay < TimeSpan.FromMilliseconds(nextRetryDelayMilliseconds)); } - Assert.Equal(testCase.ExpectedRetryAttempts, attempts); + Assert.Equal(retryAttempt.ExpectedNextRetryDelayMilliseconds, retryResult.NextRetryDelayMilliseconds); + + nextRetryDelayMilliseconds = retryResult.NextRetryDelayMilliseconds; } - public class GrpcRetryTestCase + Assert.Equal(testCase.ExpectedRetryAttempts, attempts); + } + + public class GrpcRetryTestCase + { + public int ExpectedRetryAttempts; + public GrpcRetryAttempt[] RetryAttempts; + + private string testRunnerName; + + private GrpcRetryTestCase(string testRunnerName, GrpcRetryAttempt[] retryAttempts, int expectedRetryAttempts = 1) { - public int ExpectedRetryAttempts; - public GrpcRetryAttempt[] RetryAttempts; + this.ExpectedRetryAttempts = expectedRetryAttempts; + this.RetryAttempts = retryAttempts; + this.testRunnerName = testRunnerName; + } - private string testRunnerName; + public static IEnumerable GetTestCases() + { + yield return new[] { new GrpcRetryTestCase("Cancelled", new GrpcRetryAttempt[] { new(StatusCode.Cancelled) }) }; + yield return new[] { new GrpcRetryTestCase("DeadlineExceeded", new GrpcRetryAttempt[] { new(StatusCode.DeadlineExceeded) }) }; + yield return new[] { new GrpcRetryTestCase("Aborted", new GrpcRetryAttempt[] { new(StatusCode.Aborted) }) }; + yield return new[] { new GrpcRetryTestCase("OutOfRange", new GrpcRetryAttempt[] { new(StatusCode.OutOfRange) }) }; + yield return new[] { new GrpcRetryTestCase("DataLoss", new GrpcRetryAttempt[] { new(StatusCode.DataLoss) }) }; + yield return new[] { new GrpcRetryTestCase("Unavailable", new GrpcRetryAttempt[] { new(StatusCode.Unavailable) }) }; - private GrpcRetryTestCase(string testRunnerName, GrpcRetryAttempt[] retryAttempts, int expectedRetryAttempts = 1) - { - this.ExpectedRetryAttempts = expectedRetryAttempts; - this.RetryAttempts = retryAttempts; - this.testRunnerName = testRunnerName; - } + yield return new[] { new GrpcRetryTestCase("OK", new GrpcRetryAttempt[] { new(StatusCode.OK, expectedSuccess: false) }) }; + yield return new[] { new GrpcRetryTestCase("PermissionDenied", new GrpcRetryAttempt[] { new(StatusCode.PermissionDenied, expectedSuccess: false) }) }; + yield return new[] { new GrpcRetryTestCase("Unknown", new GrpcRetryAttempt[] { new(StatusCode.Unknown, expectedSuccess: false) }) }; - public static IEnumerable GetTestCases() - { - yield return new[] { new GrpcRetryTestCase("Cancelled", new GrpcRetryAttempt[] { new(StatusCode.Cancelled) }) }; - yield return new[] { new GrpcRetryTestCase("DeadlineExceeded", new GrpcRetryAttempt[] { new(StatusCode.DeadlineExceeded) }) }; - yield return new[] { new GrpcRetryTestCase("Aborted", new GrpcRetryAttempt[] { new(StatusCode.Aborted) }) }; - yield return new[] { new GrpcRetryTestCase("OutOfRange", new GrpcRetryAttempt[] { new(StatusCode.OutOfRange) }) }; - yield return new[] { new GrpcRetryTestCase("DataLoss", new GrpcRetryAttempt[] { new(StatusCode.DataLoss) }) }; - yield return new[] { new GrpcRetryTestCase("Unavailable", new GrpcRetryAttempt[] { new(StatusCode.Unavailable) }) }; - - yield return new[] { new GrpcRetryTestCase("OK", new GrpcRetryAttempt[] { new(StatusCode.OK, expectedSuccess: false) }) }; - yield return new[] { new GrpcRetryTestCase("PermissionDenied", new GrpcRetryAttempt[] { new(StatusCode.PermissionDenied, expectedSuccess: false) }) }; - yield return new[] { new GrpcRetryTestCase("Unknown", new GrpcRetryAttempt[] { new(StatusCode.Unknown, expectedSuccess: false) }) }; - - yield return new[] { new GrpcRetryTestCase("ResourceExhausted w/o RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.ResourceExhausted, expectedSuccess: false) }) }; - yield return new[] { new GrpcRetryTestCase("ResourceExhausted w/ RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.ResourceExhausted, throttleDelay: new Duration { Seconds = 2 }, expectedNextRetryDelayMilliseconds: 3000) }) }; - - yield return new[] { new GrpcRetryTestCase("Unavailable w/ RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromMilliseconds(2000)), expectedNextRetryDelayMilliseconds: 3000) }) }; - - yield return new[] { new GrpcRetryTestCase("Expired deadline", new GrpcRetryAttempt[] { new(StatusCode.Unavailable, deadlineExceeded: true, expectedSuccess: false) }) }; - - yield return new[] - { - new GrpcRetryTestCase( - "Exponential backoff", - new GrpcRetryAttempt[] - { - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3375), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), - }, - expectedRetryAttempts: 5), - }; - - yield return new[] - { - new GrpcRetryTestCase( - "Retry until non-retryable status code encountered", - new GrpcRetryAttempt[] - { - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3375), - new(StatusCode.PermissionDenied, expectedSuccess: false), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), - }, - expectedRetryAttempts: 4), - }; - - // Test throttling affects exponential backoff. - yield return new[] - { - new GrpcRetryTestCase( - "Exponential backoff after throttling", - new GrpcRetryAttempt[] - { - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), - new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromMilliseconds(500)), expectedNextRetryDelayMilliseconds: 750), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1125), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1688), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2532), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3798), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), - new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), - }, - expectedRetryAttempts: 9), - }; - - yield return new[] - { - new GrpcRetryTestCase( - "Ridiculous throttling delay", - new GrpcRetryAttempt[] - { - new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromDays(3000000)), expectedNextRetryDelayMilliseconds: 5000), - }), - }; - } + yield return new[] { new GrpcRetryTestCase("ResourceExhausted w/o RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.ResourceExhausted, expectedSuccess: false) }) }; + yield return new[] { new GrpcRetryTestCase("ResourceExhausted w/ RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.ResourceExhausted, throttleDelay: new Duration { Seconds = 2 }, expectedNextRetryDelayMilliseconds: 3000) }) }; - public override string ToString() - { - return this.testRunnerName; - } + yield return new[] { new GrpcRetryTestCase("Unavailable w/ RetryInfo", new GrpcRetryAttempt[] { new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromMilliseconds(2000)), expectedNextRetryDelayMilliseconds: 3000) }) }; + + yield return new[] { new GrpcRetryTestCase("Expired deadline", new GrpcRetryAttempt[] { new(StatusCode.Unavailable, deadlineExceeded: true, expectedSuccess: false) }) }; - private static Metadata GenerateTrailers(Duration throttleDelay) + yield return new[] + { + new GrpcRetryTestCase( + "Exponential backoff", + new GrpcRetryAttempt[] + { + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3375), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), + }, + expectedRetryAttempts: 5), + }; + + yield return new[] + { + new GrpcRetryTestCase( + "Retry until non-retryable status code encountered", + new GrpcRetryAttempt[] + { + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3375), + new(StatusCode.PermissionDenied, expectedSuccess: false), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), + }, + expectedRetryAttempts: 4), + }; + + // Test throttling affects exponential backoff. + yield return new[] { - var metadata = new Metadata(); + new GrpcRetryTestCase( + "Exponential backoff after throttling", + new GrpcRetryAttempt[] + { + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1500), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2250), + new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromMilliseconds(500)), expectedNextRetryDelayMilliseconds: 750), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1125), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 1688), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 2532), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 3798), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), + new(StatusCode.Unavailable, expectedNextRetryDelayMilliseconds: 5000), + }, + expectedRetryAttempts: 9), + }; + + yield return new[] + { + new GrpcRetryTestCase( + "Ridiculous throttling delay", + new GrpcRetryAttempt[] + { + new(StatusCode.Unavailable, throttleDelay: Duration.FromTimeSpan(TimeSpan.FromDays(3000000)), expectedNextRetryDelayMilliseconds: 5000), + }), + }; + } - var retryInfo = new Google.Rpc.RetryInfo(); - retryInfo.RetryDelay = throttleDelay; + public override string ToString() + { + return this.testRunnerName; + } - var status = new Google.Rpc.Status(); - status.Details.Add(Any.Pack(retryInfo)); + private static Metadata GenerateTrailers(Duration throttleDelay) + { + var metadata = new Metadata(); - var stream = new MemoryStream(); - status.WriteTo(stream); + var retryInfo = new Google.Rpc.RetryInfo(); + retryInfo.RetryDelay = throttleDelay; - metadata.Add(OtlpRetry.GrpcStatusDetailsHeader, stream.ToArray()); - return metadata; - } + var status = new Google.Rpc.Status(); + status.Details.Add(Any.Pack(retryInfo)); + + var stream = new MemoryStream(); + status.WriteTo(stream); - public struct GrpcRetryAttempt + metadata.Add(OtlpRetry.GrpcStatusDetailsHeader, stream.ToArray()); + return metadata; + } + + public struct GrpcRetryAttempt + { + public RpcException RpcException; + public CallOptions CallOptions; + public TimeSpan? ThrottleDelay; + public int? ExpectedNextRetryDelayMilliseconds; + public bool ExpectedSuccess; + + public GrpcRetryAttempt( + StatusCode statusCode, + bool deadlineExceeded = false, + Duration throttleDelay = null, + int expectedNextRetryDelayMilliseconds = 1500, + bool expectedSuccess = true) { - public RpcException RpcException; - public CallOptions CallOptions; - public TimeSpan? ThrottleDelay; - public int? ExpectedNextRetryDelayMilliseconds; - public bool ExpectedSuccess; - - public GrpcRetryAttempt( - StatusCode statusCode, - bool deadlineExceeded = false, - Duration throttleDelay = null, - int expectedNextRetryDelayMilliseconds = 1500, - bool expectedSuccess = true) - { - var status = new Status(statusCode, "Error"); - this.RpcException = throttleDelay != null - ? new RpcException(status, GenerateTrailers(throttleDelay)) - : new RpcException(status); - - this.CallOptions = deadlineExceeded ? new CallOptions(deadline: DateTime.UtcNow.AddSeconds(-1)) : default; - - this.ThrottleDelay = throttleDelay != null ? throttleDelay.ToTimeSpan() : null; - - this.ExpectedNextRetryDelayMilliseconds = expectedNextRetryDelayMilliseconds; - - this.ExpectedSuccess = expectedSuccess; - } + var status = new Status(statusCode, "Error"); + this.RpcException = throttleDelay != null + ? new RpcException(status, GenerateTrailers(throttleDelay)) + : new RpcException(status); + + this.CallOptions = deadlineExceeded ? new CallOptions(deadline: DateTime.UtcNow.AddSeconds(-1)) : default; + + this.ThrottleDelay = throttleDelay != null ? throttleDelay.ToTimeSpan() : null; + + this.ExpectedNextRetryDelayMilliseconds = expectedNextRetryDelayMilliseconds; + + this.ExpectedSuccess = expectedSuccess; } } } diff --git a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs index aacc918f67a..4561168d74f 100644 --- a/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs +++ b/test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/W3CTraceContextTests.cs @@ -60,7 +60,7 @@ public void W3CTraceContextTestSuiteAsync(string value) // disabling due to failing dotnet-format // TODO: investigate why dotnet-format fails. #pragma warning disable SA1008 // Opening parenthesis should be spaced correctly - app.MapPost("/", async([FromBody] Data[] data) => + app.MapPost("/", async ([FromBody] Data[] data) => { var result = string.Empty; if (data != null)