Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions tests/Aspire.Cli.Tests/Telemetry/TelemetryConfigurationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ namespace Aspire.Cli.Tests.Telemetry;

public class TelemetryConfigurationTests
{
// The Aspire.Cli.Tests assembly opts out of Azure Monitor telemetry by default
// (see TestTelemetryDefaults). Tests that need the Azure Monitor branch override
// the env-var-derived opt-out by passing this in their in-memory configuration —
// AddInMemoryCollection is added AFTER AddEnvironmentVariables in
// Program.BuildApplicationAsync, so the in-memory value wins.
private static readonly KeyValuePair<string, string?> s_telemetryOptInOverride =
new(AspireCliTelemetry.TelemetryOptOutConfigKey, "false");

private static Dictionary<string, string?> WithTelemetryOptIn(Dictionary<string, string?>? config = null)
{
var result = config is null
? new Dictionary<string, string?>()
: new Dictionary<string, string?>(config);
result[s_telemetryOptInOverride.Key] = s_telemetryOptInOverride.Value;
return result;
}

private static async Task<IHost> BuildHostAsync(Dictionary<string, string?>? config = null)
{
var loggingOptions = Program.ParseLoggingOptions([]);
Expand All @@ -30,9 +47,11 @@ private static async Task<IHost> BuildHostAsync(Dictionary<string, string?>? con
[Fact]
public async Task AzureMonitor_Enabled_ByDefault()
{
// The Application Insights connection string is now hardcoded, so Azure Monitor
// should be enabled by default when telemetry is not opted out
using var host = await BuildHostAsync();
// The Application Insights connection string is hardcoded, so Azure Monitor
// should be enabled when telemetry is not opted out. The test process opts out
// by default (see TestTelemetryDefaults); we explicitly opt back in here to
// exercise the Azure Monitor branch.
using var host = await BuildHostAsync(WithTelemetryOptIn());

var telemetryManager = host.Services.GetService<TelemetryManager>();
Assert.NotNull(telemetryManager);
Expand All @@ -59,10 +78,10 @@ public async Task AzureMonitor_Disabled_WhenOptOutSetToTrueValues(string optOutV
[Fact]
public async Task OtlpExporter_WithoutProfiling_EnablesOnlyDebugDiagnostics_WhenEndpointProvided()
{
var config = new Dictionary<string, string?>
var config = WithTelemetryOptIn(new Dictionary<string, string?>
{
[AspireCliTelemetry.OtlpExporterEndpointConfigKey] = "http://localhost:4317"
};
});

using var host = await BuildHostAsync(config);

Expand Down Expand Up @@ -122,11 +141,11 @@ public async Task OtlpExporter_WithProfiling_EnablesProfilingProviderWhenTelemet
[Fact]
public async Task OtlpExporter_WithProfiling_KeepsReportedTelemetryAndProfilingSeparate()
{
var config = new Dictionary<string, string?>
var config = WithTelemetryOptIn(new Dictionary<string, string?>
{
[AspireCliTelemetry.OtlpExporterEndpointConfigKey] = "http://localhost:4317",
[Aspire.Hosting.KnownConfigNames.ProfilingEnabled] = "true"
};
});

using var host = await BuildHostAsync(config);

Expand Down
33 changes: 33 additions & 0 deletions tests/Aspire.Cli.Tests/TestTelemetryDefaults.cs
Comment thread
davidfowl marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using Aspire.Cli.Telemetry;

namespace Aspire.Cli.Tests;

/// <summary>
/// Opts the CLI out of Azure Monitor telemetry for the entire <c>Aspire.Cli.Tests</c>
/// process. Tests that need to exercise the Azure Monitor branch override this via the
/// in-memory configuration passed to <see cref="Aspire.Cli.Program.BuildApplicationAsync"/>,
/// which is layered on top of <c>AddEnvironmentVariables()</c> and therefore wins.
///
/// Why opt out by default in tests: see https://github.com/microsoft/aspire/issues/17450.
/// Azure Monitor's default <c>RateLimitedSampler</c> emits a <c>microsoft.sample_rate</c>
/// attribute via <c>ActivityCreationOptions.SamplingTags.Add</c> (no <c>TryAdd</c>). When
/// xUnit v3 runs test classes in parallel and more than one <c>TelemetryManager</c>
/// builds a TracerProvider in the same process, two listeners are registered on the
/// <c>Aspire.Cli.Reported</c> ActivitySource and both samplers fire on the same shared
/// <c>ActivityCreationOptions</c>, so the second <c>Add</c> throws
/// <c>InvalidOperationException("The collection already contains item with same key 'microsoft.sample_rate'")</c>.
/// Defaulting the test process to opted-out keeps Azure Monitor out of the pipeline
/// except in the focused tests that explicitly need it.
/// </summary>
internal static class TestTelemetryDefaults
{
[ModuleInitializer]
internal static void OptOutByDefault()
{
Environment.SetEnvironmentVariable(AspireCliTelemetry.TelemetryOptOutConfigKey, "true");
}
}
Loading