diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 186e917ddb..d1328cde1b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -57,9 +57,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.props = build\Common.props build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk + build\docker-compose.net10.0.yml = build\docker-compose.net10.0.yml build\docker-compose.net8.0.yml = build\docker-compose.net8.0.yml build\docker-compose.net9.0.yml = build\docker-compose.net9.0.yml - build\docker-compose.net10.0.yml = build\docker-compose.net10.0.yml build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset @@ -367,6 +367,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{70CA77 test\Shared\ConsoleCommand.cs = test\Shared\ConsoleCommand.cs test\Shared\CustomTextMapPropagator.cs = test\Shared\CustomTextMapPropagator.cs test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs = test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs + test\Shared\EnvironmentVariableScope.cs = test\Shared\EnvironmentVariableScope.cs test\Shared\EventSourceTestHelper.cs = test\Shared\EventSourceTestHelper.cs test\Shared\InMemoryEventListener.cs = test\Shared\InMemoryEventListener.cs test\Shared\PerfTracepointListener.cs = test\Shared\PerfTracepointListener.cs diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs index 7b812b7f5d..564fff393d 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs @@ -52,10 +52,8 @@ public void VerifyFlags() [MemberData(nameof(TestCases))] public void VerifyGetSemanticConventionOptIn_UsingEnvironmentVariable(string input, string expectedValue) { - try + using (EnvironmentVariableScope.Create(SemanticConventionOptInKeyName, input)) { - Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, input); - #if NET var expected = Enum.Parse(expectedValue); #else @@ -63,10 +61,6 @@ public void VerifyGetSemanticConventionOptIn_UsingEnvironmentVariable(string inp #endif Assert.Equal(expected, GetSemanticConventionOptIn(new ConfigurationBuilder().AddEnvironmentVariables().Build())); } - finally - { - Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, null); - } } [Theory] diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj index d632a5f92d..741b484015 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs index 3795504a75..c7e3e2f01a 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Internal.Tests; -public class RequestDataHelperTests : IDisposable +public class RequestDataHelperTests { public static IEnumerable MappingVersionProtocolToVersionData => [ @@ -50,19 +50,23 @@ public void MethodMappingWorksForKnownMethods(string method, string expected) [InlineData("invalid", "_OTHER")] public void MethodMappingWorksForEnvironmentVariables(string method, string expected) { - Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST"); - var requestHelper = new RequestDataHelper(configureByHttpKnownMethodsEnvironmentalVariable: true); - var actual = requestHelper.GetNormalizedHttpMethod(method); - Assert.Equal(expected, actual); + using (EnvironmentVariableScope.Create("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST")) + { + var requestHelper = new RequestDataHelper(configureByHttpKnownMethodsEnvironmentalVariable: true); + var actual = requestHelper.GetNormalizedHttpMethod(method); + Assert.Equal(expected, actual); + } } [Fact] public void MethodMappingWorksIfEnvironmentalVariableConfigurationIsDisabled() { - Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST"); - var requestHelper = new RequestDataHelper(configureByHttpKnownMethodsEnvironmentalVariable: false); - var actual = requestHelper.GetNormalizedHttpMethod("CONNECT"); - Assert.Equal("CONNECT", actual); + using (EnvironmentVariableScope.Create("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST")) + { + var requestHelper = new RequestDataHelper(configureByHttpKnownMethodsEnvironmentalVariable: false); + var actual = requestHelper.GetNormalizedHttpMethod("CONNECT"); + Assert.Equal("CONNECT", actual); + } } [Theory] @@ -83,10 +87,4 @@ public void MappingVersionProtocolToVersion(Version protocolVersion, string expe var actual = RequestDataHelper.GetHttpProtocolVersion(protocolVersion); Assert.Equal(expected, actual); } - - public void Dispose() - { - // Clean up after tests that set environment variables. - Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", null); - } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 8035d66523..98ab05e304 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -17,21 +17,25 @@ public class AWSLambdaWrapperTests : IDisposable private readonly SampleHandlers sampleHandlers; private readonly SampleLambdaContext sampleLambdaContext; + private readonly IDisposable environmentScope; public AWSLambdaWrapperTests() { this.sampleHandlers = new SampleHandlers(); this.sampleLambdaContext = new SampleLambdaContext(); - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=1"); - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "128"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_LOG_STREAM_NAME", "2025/07/21/[$LATEST]7b176c212e954e62adfb9b5451cb5374"); + this.environmentScope = EnvironmentVariableScope.Create( + ("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=1"), + ("AWS_REGION", "us-east-1"), + ("AWS_LAMBDA_FUNCTION_NAME", "testfunction"), + ("AWS_LAMBDA_FUNCTION_VERSION", "latest"), + ("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "128"), + ("AWS_LAMBDA_LOG_STREAM_NAME", "2025/07/21/[$LATEST]7b176c212e954e62adfb9b5451cb5374")); } public void Dispose() { + this.environmentScope.Dispose(); + // reset Semantic Convention to default Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations(); @@ -187,59 +191,63 @@ public void TestLambdaHandlerException(bool setCustomParent) [Fact] public void TestLambdaHandlerNotSampled() { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); + using (EnvironmentVariableScope.Create("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0")) + { + var exportedItems = new List(); - var exportedItems = new List(); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(opt => + { + opt.SemanticConventionVersion = SemanticConventionVersion.Latest; + }) + .AddInMemoryExporter(exportedItems) + .Build()!) + { + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); + } - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations(opt => - { - opt.SemanticConventionVersion = SemanticConventionVersion.Latest; - }) - .AddInMemoryExporter(exportedItems) - .Build()!) - { - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); + Assert.Empty(exportedItems); } - - Assert.Empty(exportedItems); } [Fact] public void OnFunctionStart_NoParent_ActivityCreated() { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", null); - - Activity? activity = null; - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations(opt => - { - opt.SemanticConventionVersion = SemanticConventionVersion.Latest; - }) - .Build()) + using (EnvironmentVariableScope.Create("_X_AMZN_TRACE_ID", null)) { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); - } + Activity? activity = null; + using (Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(opt => + { + opt.SemanticConventionVersion = SemanticConventionVersion.Latest; + }) + .Build()) + { + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); + } - Assert.NotNull(activity); + Assert.NotNull(activity); + } } [Fact] public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_ActivityCreated() { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0"); - Activity? activity = null; - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) - .Build()) + using (EnvironmentVariableScope.Create("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0")) { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); - } + Activity? activity = null; - Assert.NotNull(activity); + using (Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) + .Build()) + { + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); + } + + Assert.NotNull(activity); + } } [Theory] @@ -250,9 +258,9 @@ public void OnFunctionStart_ColdStart_ColdStartTagHasCorrectValue(int invocation AWSLambdaWrapper.ResetColdStart(); Activity? activity = null; - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) - .Build()) + using (Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) + .Build()) { for (var i = 1; i <= invocationsCount; i++) { diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 3949f9b0c1..95781d340c 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -15,6 +15,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index e8b760be98..ff03fc4d1d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -67,13 +67,8 @@ public void AspNetRequestsAreCollectedSuccessfully( bool recordException = false, string? expectedErrorType = null) { - try + using (EnvironmentVariableScope.Create("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", disableQueryRedaction == QueryRedactionDisableBehavior.DisableViaEnvVar ? "true" : null)) { - if (disableQueryRedaction == QueryRedactionDisableBehavior.DisableViaEnvVar) - { - Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", "true"); - } - HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate, requestMethod); typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); @@ -228,10 +223,6 @@ public void AspNetRequestsAreCollectedSuccessfully( Assert.True(string.IsNullOrEmpty(span.StatusDescription)); } } - finally - { - Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", null); - } } [Theory] diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 31c795fcf2..8e15686936 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -20,6 +20,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkIntegrationTests.cs index 1bb0bf7448..b0c8774089 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkIntegrationTests.cs @@ -159,28 +159,30 @@ bool ActivityFilter(string? providerName, IDbCommand command) return true; } - using var scope = SemanticConventionScope.Get(useNewConventions); - var activities = new List(); - using (Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(activities) - .AddSqlClientInstrumentation() - .AddEntityFrameworkCoreInstrumentation(options => options.Filter = ActivityFilter) - .Build()) + + using (SemanticConventionScope.Get(useNewConventions)) { - var optionsBuilder = new DbContextOptionsBuilder(); + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .AddSqlClientInstrumentation() + .AddEntityFrameworkCoreInstrumentation(options => options.Filter = ActivityFilter) + .Build()) + { + var optionsBuilder = new DbContextOptionsBuilder(); - this.ConfigureProvider(provider, optionsBuilder); + this.ConfigureProvider(provider, optionsBuilder); - await using var context = new ItemsContext(optionsBuilder.Options); + await using var context = new ItemsContext(optionsBuilder.Options); - try - { - await context.Database.ExecuteSqlRawAsync(commandText); - } - catch - { - // Ignore + try + { + await context.Database.ExecuteSqlRawAsync(commandText); + } + catch + { + // Ignore + } } } @@ -256,36 +258,38 @@ bool ActivityFilter(string? providerName, IDbCommand command) return true; } - using var scope = SemanticConventionScope.Get(useNewConventions); - var activities = new List(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(activities) - .AddSqlClientInstrumentation() - .AddEntityFrameworkCoreInstrumentation(options => - { - options.Filter = ActivityFilter; - if (shouldEnrich) + + using (SemanticConventionScope.Get(useNewConventions)) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .AddSqlClientInstrumentation() + .AddEntityFrameworkCoreInstrumentation(options => { - options.EnrichWithIDbCommand = ActivityEnrichment; - } - }) - .Build(); + options.Filter = ActivityFilter; + if (shouldEnrich) + { + options.EnrichWithIDbCommand = ActivityEnrichment; + } + }) + .Build(); - var optionsBuilder = new DbContextOptionsBuilder(); + var optionsBuilder = new DbContextOptionsBuilder(); - this.ConfigureProvider(provider, optionsBuilder); + this.ConfigureProvider(provider, optionsBuilder); - await using var context = new ItemsContext(optionsBuilder.Options); - await context.Database.EnsureCreatedAsync(); + await using var context = new ItemsContext(optionsBuilder.Options); + await context.Database.EnsureCreatedAsync(); - // Clear activities from creating the database - activities.Clear(); + // Clear activities from creating the database + activities.Clear(); - var result = await context.Items.ToListAsync(); + var result = await context.Items.ToListAsync(); - Assert.NotNull(result); - Assert.Empty(result); + Assert.NotNull(result); + Assert.Empty(result); + } // All activities should either be the root EFCore activity or a child of it. Assert.All(activities, activity => Assert.Equal(ActivitySourceName, (activity.Parent?.Source ?? activity.Source).Name)); @@ -310,29 +314,31 @@ bool ActivityFilter(string? providerName, IDbCommand command) public async Task SuccessfulParameterizedQueryTest(string provider) { // Arrange - using var scope = SemanticConventionScope.Get(useNewConventions: true); - var activities = new List(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(activities) - .AddEntityFrameworkCoreInstrumentation(options => options.SetDbQueryParameters = true) - .Build(); - var optionsBuilder = new DbContextOptionsBuilder(); + using (SemanticConventionScope.Get(useNewConventions: true)) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .AddEntityFrameworkCoreInstrumentation(options => options.SetDbQueryParameters = true) + .Build(); - this.ConfigureProvider(provider, optionsBuilder); + var optionsBuilder = new DbContextOptionsBuilder(); - await using var context = new ItemsContext(optionsBuilder.Options); - await context.Database.EnsureCreatedAsync(); + this.ConfigureProvider(provider, optionsBuilder); - // Clear activities from creating the database - activities.Clear(); + await using var context = new ItemsContext(optionsBuilder.Options); + await context.Database.EnsureCreatedAsync(); - // Act - await context.Database.ExecuteSqlRawAsync( - "SELECT @x + @y", - CreateParameter(provider, "@x", 42), - CreateParameter(provider, "@y", 37)); + // Clear activities from creating the database + activities.Clear(); + + // Act + await context.Database.ExecuteSqlRawAsync( + "SELECT @x + @y", + CreateParameter(provider, "@x", 42), + CreateParameter(provider, "@y", 37)); + } // Assert var activity = Assert.Single(activities); @@ -352,27 +358,29 @@ public async Task SqlQueriesAreSanitized( string? expectedCommandText, string? expectedQuerySummary) { - var conventions = useNewConventions ? SemanticConvention.New : SemanticConvention.Old; - using var scope = SemanticConventionScope.Get(useNewConventions); - var activities = new List(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(activities) - .AddEntityFrameworkCoreInstrumentation() - .Build(); - var optionsBuilder = new DbContextOptionsBuilder(); + var conventions = useNewConventions ? SemanticConvention.New : SemanticConvention.Old; + using (SemanticConventionScope.Get(useNewConventions)) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .AddEntityFrameworkCoreInstrumentation() + .Build(); + + var optionsBuilder = new DbContextOptionsBuilder(); - this.ConfigureProvider(provider, optionsBuilder); + this.ConfigureProvider(provider, optionsBuilder); - await using var context = new ItemsContext(optionsBuilder.Options); - await context.Database.EnsureCreatedAsync(); + await using var context = new ItemsContext(optionsBuilder.Options); + await context.Database.EnsureCreatedAsync(); - // Clear activities from creating the database - activities.Clear(); + // Clear activities from creating the database + activities.Clear(); - // Act - await context.Database.ExecuteSqlRawAsync(commandText); + // Act + await context.Database.ExecuteSqlRawAsync(commandText); + } // Assert var activity = Assert.Single(activities); @@ -506,21 +514,9 @@ private sealed class SemanticConvention public required string System { get; init; } } - private sealed class SemanticConventionScope(string? previous) : IDisposable + private sealed class SemanticConventionScope { - private const string ConventionsOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN"; - - public static SemanticConventionScope Get(bool useNewConventions) - { - var previous = Environment.GetEnvironmentVariable(ConventionsOptIn); - - Environment.SetEnvironmentVariable( - ConventionsOptIn, - useNewConventions ? "database" : string.Empty); - - return new SemanticConventionScope(previous); - } - - public void Dispose() => Environment.SetEnvironmentVariable(ConventionsOptIn, previous); + public static IDisposable Get(bool useNewConventions) + => EnvironmentVariableScope.Create("OTEL_SEMCONV_STABILITY_OPT_IN", useNewConventions ? "database" : string.Empty); } } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index b5f79a647b..9d4786ffa5 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 96db456378..501385a072 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -287,13 +287,8 @@ public async Task QueryParametersAreRedacted( bool disableQueryRedactionUsingEnvVar, bool disableQueryRedactionUsingConfiguration) { - try + using (EnvironmentVariableScope.Create("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", disableQueryRedactionUsingEnvVar ? "true" : null)) { - if (disableQueryRedactionUsingEnvVar) - { - Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", "true"); - } - List stoppedActivities = []; var builder = Sdk.CreateTracerProviderBuilder() @@ -348,10 +343,6 @@ Owin has finished to inspect the activity status. */ Assert.Equal(expectedRequestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlPath).Value); Assert.Equal(expectedRequestUri.Query.TrimStart('?'), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlQuery).Value); } - finally - { - Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", null); - } } private List GetMetricPoints(Metric metric) diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index b272d87d6d..ea887458cd 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -14,4 +14,8 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 344a903a0c..fedf737b1c 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -12,8 +12,9 @@ - + + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index 340842a3ff..3f4de843a1 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -42,10 +42,9 @@ public void SuccessfulCommandTest( bool recordException = false, bool enableTransaction = false) { - if (commandText == GetContextInfoQuery) - { - Environment.SetEnvironmentVariable(SqlClientTraceInstrumentationOptions.ContextPropagationLevelEnvVar, "true"); - } + using var scope = EnvironmentVariableScope.Create( + SqlClientTraceInstrumentationOptions.ContextPropagationLevelEnvVar, + commandText == GetContextInfoQuery ? "true" : null); #if NETFRAMEWORK // Disable things not available on netfx @@ -323,21 +322,9 @@ private static void VerifySamplingParameters(SamplingParameters samplingParamete private string GetConnectionString() => this.fixture.DatabaseContainer.GetConnectionString(); - private sealed class SemanticConventionScope(string? previous) : IDisposable + private static class SemanticConventionScope { - private const string ConventionsOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN"; - - public static SemanticConventionScope Get(bool useNewConventions) - { - var previous = Environment.GetEnvironmentVariable(ConventionsOptIn); - - Environment.SetEnvironmentVariable( - ConventionsOptIn, - useNewConventions ? "database" : string.Empty); - - return new SemanticConventionScope(previous); - } - - public void Dispose() => Environment.SetEnvironmentVariable(ConventionsOptIn, previous); + public static IDisposable Get(bool useNewConventions) + => EnvironmentVariableScope.Create("OTEL_SEMCONV_STABILITY_OPT_IN", useNewConventions ? "database" : string.Empty); } } diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 7a4d861afa..2f527131b7 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 94e51bd9f5..303b60d2ab 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -549,13 +549,10 @@ private static void VerifySamplingParameters(SamplingParameters samplingParamete && (string?)kvp.Value == "redis"); } - private sealed class SemanticConventionScope(string? previous) : IDisposable + private static class SemanticConventionScope { - private const string ConventionsOptIn = DatabaseSemanticConventionHelper.SemanticConventionOptInKeyName; - - public static SemanticConventionScope Get(DatabaseSemanticConventionHelper.DatabaseSemanticConvention convention) + public static IDisposable Get(DatabaseSemanticConventionHelper.DatabaseSemanticConvention convention) { - var previous = Environment.GetEnvironmentVariable(ConventionsOptIn); var value = convention switch { DatabaseSemanticConventionHelper.DatabaseSemanticConvention.Dupe => "database/dup", @@ -563,13 +560,7 @@ public static SemanticConventionScope Get(DatabaseSemanticConventionHelper.Datab _ => string.Empty, }; - Environment.SetEnvironmentVariable( - ConventionsOptIn, - value); - - return new SemanticConventionScope(previous); + return EnvironmentVariableScope.Create("OTEL_SEMCONV_STABILITY_OPT_IN", value); } - - public void Dispose() => Environment.SetEnvironmentVariable(ConventionsOptIn, previous); } } diff --git a/test/OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs index 40980ec2f0..cf895b7e7e 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs @@ -15,22 +15,12 @@ namespace OpenTelemetry.Resources.AWS.Tests; -public class AWSECSDetectorTests : IDisposable +public class AWSECSDetectorTests { private const string AWSECSMetadataFilePath = "SampleMetadataFiles/testcgroup"; private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; - public AWSECSDetectorTests() - { - this.ResetEnvironment(); - } - - public void Dispose() - { - this.ResetEnvironment(); - } - [Fact] public void TestNotOnEcs() { @@ -53,16 +43,17 @@ public void TestGetECSContainerId() [Fact] public void TestEcsMetadataV3() { - Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, "TestECSURIKey"); - - var ecsResourceDetector = new AWSECSDetector( - new OpenTelemetry.AWS.AWSSemanticConventions( - SemanticConventionVersion.Latest)); + using (EnvironmentVariableScope.Create(AWSECSMetadataURLKey, "TestECSURIKey")) + { + var ecsResourceDetector = new AWSECSDetector( + new OpenTelemetry.AWS.AWSSemanticConventions( + SemanticConventionVersion.Latest)); - var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + } } [Fact] @@ -73,31 +64,32 @@ public async Task TestEcsMetadataV4Ec2() await using (var metadataEndpoint = new MockEcsMetadataEndpoint("ecs_metadata/metadatav4-response-container-ec2.json", "ecs_metadata/metadatav4-response-task-ec2.json")) { - Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString()); - - var ecsResourceDetector = new AWSECSDetector( - new OpenTelemetry.AWS.AWSSemanticConventions( - SemanticConventionVersion.Latest)); - - var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAccountID], "111122223333"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2d"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudRegion], "us-west-2"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsLaunchtype], "ec2"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskFamily], "curltest"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskRevision], "26"); + using (EnvironmentVariableScope.Create(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString())) + { + var ecsResourceDetector = new AWSECSDetector( + new OpenTelemetry.AWS.AWSSemanticConventions( + SemanticConventionVersion.Latest)); + + var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); + + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAccountID], "111122223333"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2d"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudRegion], "us-west-2"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsLaunchtype], "ec2"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskFamily], "curltest"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskRevision], "26"); #pragma warning disable CA1861 // Avoid constant arrays as arguments - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/metadata" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/8f03e41243824aea923aca126495f665" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/metadata" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/8f03e41243824aea923aca126495f665" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665" }); #pragma warning restore CA1861 // Avoid constant arrays as arguments + } } } @@ -109,40 +101,35 @@ public async Task TestEcsMetadataV4Fargate() await using (var metadataEndpoint = new MockEcsMetadataEndpoint("ecs_metadata/metadatav4-response-container-fargate.json", "ecs_metadata/metadatav4-response-task-fargate.json")) { - Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString()); - - var ecsResourceDetector = new AWSECSDetector( - new OpenTelemetry.AWS.AWSSemanticConventions( - SemanticConventionVersion.Latest)); - - var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAccountID], "111122223333"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2a"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudRegion], "us-west-2"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsLaunchtype], "fargate"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskFamily], "curltest"); - Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskRevision], "3"); + using (EnvironmentVariableScope.Create(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString())) + { + var ecsResourceDetector = new AWSECSDetector( + new OpenTelemetry.AWS.AWSSemanticConventions( + SemanticConventionVersion.Latest)); + + var resourceAttributes = ecsResourceDetector.Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); + + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAccountID], "111122223333"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2a"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudRegion], "us-west-2"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsLaunchtype], "fargate"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskFamily], "curltest"); + Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeEcsTaskRevision], "3"); #pragma warning disable CA1861 // Avoid constant arrays as arguments - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/containerlogs" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/cd189a933e5849daa93386466019ab50" }); - Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs:log-stream:ecs/curl/cd189a933e5849daa93386466019ab50" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/containerlogs" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/cd189a933e5849daa93386466019ab50" }); + Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs:log-stream:ecs/curl/cd189a933e5849daa93386466019ab50" }); #pragma warning restore CA1861 // Avoid constant arrays as arguments + } } } - internal void ResetEnvironment() - { - Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, null); - Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, null); - } - internal class MockEcsMetadataEndpoint : IAsyncDisposable { public readonly Uri Address; diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index 0655b3ccde..c3d62a7266 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs index 5d037e012c..2a9afd57d5 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs @@ -6,42 +6,41 @@ namespace OpenTelemetry.Resources.Azure.Tests; -public class AzureResourceDetectorTests : IDisposable +public class AzureResourceDetectorTests { [Fact] public void AppServiceResourceDetectorReturnsResourceWithAttributes() { - try + var environment = new Dictionary(); + + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) { - foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + if (kvp.Value == ResourceAttributeConstants.AppServiceSiteNameEnvVar) { - if (kvp.Value == ResourceAttributeConstants.AppServiceSiteNameEnvVar) - { - continue; - } - - Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); + continue; } - // Special case for service.name and resource uri attribute - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar, "sitename"); - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar, "testResourceGroup"); - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar, "testtestSubscriptionId+testResourceGroup-websiteOwnerName"); + environment[kvp.Value] = kvp.Key; } - catch - { - } - - var resource = ResourceBuilder.CreateEmpty().AddAzureAppServiceDetector().Build(); - Assert.NotNull(resource); - var expectedResourceUri = "/subscriptions/testtestSubscriptionId/resourceGroups/testResourceGroup/providers/Microsoft.Web/sites/sitename"; - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeCloudResourceId, expectedResourceUri), resource.Attributes); - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "sitename"), resource.Attributes); + // Special case for service.name and resource uri attribute + environment[ResourceAttributeConstants.AppServiceSiteNameEnvVar] = "sitename"; + environment[ResourceAttributeConstants.AppServiceResourceGroupEnvVar] = "testResourceGroup"; + environment[ResourceAttributeConstants.AppServiceOwnerNameEnvVar] = "testtestSubscriptionId+testResourceGroup-websiteOwnerName"; - foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + using (EnvironmentVariableScope.Create(environment)) { - Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + var resource = ResourceBuilder.CreateEmpty().AddAzureAppServiceDetector().Build(); + Assert.NotNull(resource); + + var expectedResourceUri = "/subscriptions/testtestSubscriptionId/resourceGroups/testResourceGroup/providers/Microsoft.Web/sites/sitename"; + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeCloudResourceId, expectedResourceUri), resource.Attributes); + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "sitename"), resource.Attributes); + + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } } } @@ -94,75 +93,52 @@ public void TestAzureVmResourceDetector() [Fact] public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes() { - try - { - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) - { - Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); - } + var environment = new Dictionary(); - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar, "containerAppName"); - } - catch + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) { + environment[kvp.Value] = kvp.Key; } - var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); - Assert.NotNull(resource); + environment[ResourceAttributeConstants.AzureContainerAppsNameEnvVar] = "containerAppName"; - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes); - - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) + using (EnvironmentVariableScope.Create(environment)) { - Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); + Assert.NotNull(resource); + + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes); + + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } } } [Fact] public void AzureContainerAppsJobResourceDetectorReturnsResourceWithAttributes() { - try - { - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) - { - Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); - } - - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar, "containerAppJobName"); - } - catch - { - } - - var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); - Assert.NotNull(resource); - - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppJobName"), resource.Attributes); + var environment = new Dictionary(); foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) { - Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + environment[kvp.Value] = kvp.Key; } - } - public void Dispose() - { - foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) - { - Environment.SetEnvironmentVariable(kvp.Value, null); - } + environment[ResourceAttributeConstants.AzureContainerAppJobNameEnvVar] = "containerAppJobName"; - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) + using (EnvironmentVariableScope.Create(environment)) { - Environment.SetEnvironmentVariable(kvp.Value, null); - } + var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); + Assert.NotNull(resource); - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) - { - Environment.SetEnvironmentVariable(kvp.Value, null); - } + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppJobName"), resource.Attributes); - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar, null); - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar, null); + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } + } } } diff --git a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj index 2faced9fd9..10717e22a2 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj +++ b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/test/Shared/EnvironmentVariableScope.cs b/test/Shared/EnvironmentVariableScope.cs new file mode 100644 index 0000000000..21b64cd389 --- /dev/null +++ b/test/Shared/EnvironmentVariableScope.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry; + +internal sealed class EnvironmentVariableScope : IDisposable +{ + private readonly Dictionary originalEnvironment = []; + private bool disposed; + + private EnvironmentVariableScope(params ReadOnlySpan<(string Name, string? Value)> environment) + { + foreach (var (name, value) in environment) + { + this.originalEnvironment[name] = Environment.GetEnvironmentVariable(name); + Environment.SetEnvironmentVariable(name, value); + } + } + + public static IDisposable Create(string name, string? value) + => Create((name, value)); + + public static IDisposable Create(params ReadOnlySpan<(string Name, string? Value)> environment) + => new EnvironmentVariableScope(environment); + + public static IDisposable Create(IDictionary environment) + => new EnvironmentVariableScope([.. environment.Select((p) => (p.Key, p.Value))]); + + public void Dispose() + { + if (!this.disposed) + { + foreach (var pair in this.originalEnvironment) + { + Environment.SetEnvironmentVariable(pair.Key, pair.Value); + } + + this.disposed = true; + } + } +}