Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/8.0] Update to 8.0.4 of ASP.NET Core #3672

Merged
merged 1 commit into from
Apr 14, 2024
Merged
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
27 changes: 14 additions & 13 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>8.0.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>8.0.2</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>8.0.0</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftAspNetCoreAuthenticationCertificatePackageVersion>8.0.3</MicrosoftAspNetCoreAuthenticationCertificatePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>8.0.3</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreOpenApiPackageVersion>8.0.3</MicrosoftAspNetCoreOpenApiPackageVersion>
<MicrosoftAspNetCoreOutputCachingStackExchangeRedisPackageVersion>8.0.2</MicrosoftAspNetCoreOutputCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>8.0.2</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsDiagnosticsHealthChecksEntityFrameworkCorePackageVersion>8.0.2</MicrosoftExtensionsDiagnosticsHealthChecksEntityFrameworkCorePackageVersion>
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>8.0.2</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
<MicrosoftExtensionsFeaturesPackageVersion>8.0.3</MicrosoftExtensionsFeaturesPackageVersion>
<MicrosoftEntityFrameworkCoreCosmosPackageVersion>8.0.2</MicrosoftEntityFrameworkCoreCosmosPackageVersion>
<MicrosoftEntityFrameworkCoreDesignPackageVersion>8.0.3</MicrosoftEntityFrameworkCoreDesignPackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>8.0.3</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftEntityFrameworkCoreToolsPackageVersion>8.0.3</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftNETRuntimeWorkloadTestingInternalVersion>9.0.0-preview.3.24158.8</MicrosoftNETRuntimeWorkloadTestingInternalVersion>
<MicrosoftAspNetCoreAuthenticationCertificatePackageVersion>8.0.4</MicrosoftAspNetCoreAuthenticationCertificatePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>8.0.4</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreOpenApiPackageVersion>8.0.4</MicrosoftAspNetCoreOpenApiPackageVersion>
<MicrosoftAspNetCoreOutputCachingStackExchangeRedisPackageVersion>8.0.4</MicrosoftAspNetCoreOutputCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>8.0.4</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsDiagnosticsHealthChecksEntityFrameworkCorePackageVersion>8.0.4</MicrosoftExtensionsDiagnosticsHealthChecksEntityFrameworkCorePackageVersion>
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>8.0.4</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
<MicrosoftExtensionsFeaturesPackageVersion>8.0.4</MicrosoftExtensionsFeaturesPackageVersion>
<!-- EF -->
<MicrosoftEntityFrameworkCoreCosmosPackageVersion>8.0.4</MicrosoftEntityFrameworkCoreCosmosPackageVersion>
<MicrosoftEntityFrameworkCoreDesignPackageVersion>8.0.4</MicrosoftEntityFrameworkCoreDesignPackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>8.0.4</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftEntityFrameworkCoreToolsPackageVersion>8.0.4</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftNETRuntimeWorkloadTestingInternalVersion>9.0.0-preview.4.24208.7</MicrosoftNETRuntimeWorkloadTestingInternalVersion>
</PropertyGroup>
</Project>
45 changes: 36 additions & 9 deletions tests/Aspire.Components.Common.Tests/ActivityNotifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Channels;
using OpenTelemetry;

namespace Aspire.Components.Common.Tests;
Expand All @@ -11,19 +13,44 @@ namespace Aspire.Components.Common.Tests;
/// </summary>
public sealed class ActivityNotifier : BaseProcessor<Activity>
{
// RunContinuationsAsynchronously because OnEnd gets invoked on the thread creating the Activity.
// Running more test code on this thread can cause deadlocks in the case where the Activity is created on a "drain thread" (ex. Redis)
// and the test method disposes the Host on that same thread. Disposing the Host will dispose the Instrumentation, which tries joining
// with the "drain thread".
private readonly TaskCompletionSource _taskSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly Channel<Activity> _activityChannel = Channel.CreateUnbounded<Activity>();

public Task ActivityReceived => _taskSource.Task;
public async Task<List<Activity>> TakeAsync(int count, TimeSpan timeout)
{
var activityList = new List<Activity>();
using var cts = new CancellationTokenSource(timeout);
await foreach (var activity in WaitAsync(cts.Token))
{
activityList.Add(activity);
if (activityList.Count == count)
{
break;
}
}

public List<Activity> ExportedActivities { get; } = [];
return activityList;
}

public override void OnEnd(Activity data)
{
ExportedActivities.Add(data);
_taskSource.SetResult();
_activityChannel.Writer.TryWrite(data);
}

private async IAsyncEnumerable<Activity> WaitAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var activity in _activityChannel.Reader.ReadAllAsync(cancellationToken).ConfigureAwait(false))
{
yield return activity;
}
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
_activityChannel.Writer.TryComplete();
}

base.Dispose(disposing);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void NatsInstrumentationEndToEnd()

builder.AddNatsClient(DefaultConnectionName);

var notifier = new ActivityNotifier();
using var notifier = new ActivityNotifier();
builder.Services.AddOpenTelemetry().WithTracing(builder => builder.AddProcessor(notifier));

using var host = builder.Build();
Expand All @@ -193,10 +193,10 @@ public void NatsInstrumentationEndToEnd()
var nats = host.Services.GetRequiredService<INatsConnection>();
await nats.PublishAsync("test");

await notifier.ActivityReceived.WaitAsync(TimeSpan.FromSeconds(10));
Assert.Single(notifier.ExportedActivities);
var activityList = await notifier.TakeAsync(1, TimeSpan.FromSeconds(10));
Assert.Single(activityList);

var activity = notifier.ExportedActivities[0];
var activity = activityList[0];
Assert.Equal("test publish", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "messaging.system" && kvp.Value == "nats");
}, _connectionString).Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void WorksWithOpenTelemetryTracing()

builder.AddRedisDistributedCache("redis");

var notifier = new ActivityNotifier();
using var notifier = new ActivityNotifier();
builder.Services.AddOpenTelemetry().WithTracing(builder => builder.AddProcessor(notifier));
// set the FlushInterval to to zero so the Activity gets created immediately
builder.Services.Configure<StackExchangeRedisInstrumentationOptions>(options => options.FlushInterval = TimeSpan.Zero);
Expand All @@ -61,14 +61,26 @@ public void WorksWithOpenTelemetryTracing()
var cache = host.Services.GetRequiredService<IDistributedCache>();
await cache.GetAsync("myFakeKey", CancellationToken.None);

// wait for the Activity to be processed
await notifier.ActivityReceived.WaitAsync(TimeSpan.FromSeconds(10));

Assert.Single(notifier.ExportedActivities);

var activity = notifier.ExportedActivities[0];
Assert.Equal("HMGET", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
// read the first 3 activities
var activityList = await notifier.TakeAsync(3, TimeSpan.FromSeconds(10));
Assert.Equal(3, activityList.Count);
Assert.Collection(activityList,
// https://github.com/dotnet/aspnetcore/pull/54239 added 2 CLIENT activities on the first call
activity =>
{
Assert.Equal("CLIENT", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
},
activity =>
{
Assert.Equal("CLIENT", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
},
activity =>
{
Assert.Equal("HMGET", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
});
}, ConnectionString).Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void WorksWithOpenTelemetryTracing()

builder.AddRedisOutputCache("redis");

var notifier = new ActivityNotifier();
using var notifier = new ActivityNotifier();
builder.Services.AddOpenTelemetry().WithTracing(builder => builder.AddProcessor(notifier));
// set the FlushInterval to to zero so the Activity gets created immediately
builder.Services.Configure<StackExchangeRedisInstrumentationOptions>(options => options.FlushInterval = TimeSpan.Zero);
Expand All @@ -61,14 +61,26 @@ public void WorksWithOpenTelemetryTracing()
var cacheStore = host.Services.GetRequiredService<IOutputCacheStore>();
await cacheStore.GetAsync("myFakeKey", CancellationToken.None);

// wait for the Activity to be processed
await notifier.ActivityReceived.WaitAsync(TimeSpan.FromSeconds(10));

Assert.Single(notifier.ExportedActivities);

var activity = notifier.ExportedActivities[0];
Assert.Equal("GET", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
// read the first 3 activities
var activityList = await notifier.TakeAsync(3, TimeSpan.FromSeconds(10));
Assert.Equal(3, activityList.Count);
Assert.Collection(activityList,
// https://github.com/dotnet/aspnetcore/pull/54239 added 2 CLIENT activities on the first call
activity =>
{
Assert.Equal("CLIENT", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
},
activity =>
{
Assert.Equal("CLIENT", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
},
activity =>
{
Assert.Equal("GET", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
});
}, ConnectionString).Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public void KeyedServiceRedisInstrumentationEndToEnd()
new KeyValuePair<string, string?>("ConnectionStrings:redis", connectionString)
]);

var notifier = new ActivityNotifier();
using var notifier = new ActivityNotifier();
builder.Services.AddOpenTelemetry().WithTracing(builder => builder.AddProcessor(notifier));
// set the FlushInterval to to zero so the Activity gets created immediately
builder.Services.Configure<StackExchangeRedisInstrumentationOptions>(options => options.FlushInterval = TimeSpan.Zero);
Expand All @@ -281,11 +281,11 @@ public void KeyedServiceRedisInstrumentationEndToEnd()
var database = connectionMultiplexer.GetDatabase();
database.StringGet("key");

await notifier.ActivityReceived.WaitAsync(TimeSpan.FromSeconds(10));
// read the first activity
var activityList = await notifier.TakeAsync(1, TimeSpan.FromSeconds(10));
Assert.Single(activityList);

Assert.Single(notifier.ExportedActivities);

var activity = notifier.ExportedActivities[0];
var activity = activityList[0];
Assert.Equal("GET", activity.OperationName);
Assert.Contains(activity.Tags, kvp => kvp.Key == "db.system" && kvp.Value == "redis");
}, ConnectionString).Dispose();
Expand Down