Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/Components/Aspire.RabbitMQ.Client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dotnet add package Aspire.RabbitMQ.Client

## Usage example

In the _AppHost.cs_ file of your project, call the `AddRabbitMQClient` extension method to register an `IConnection` for use via the dependency injection container. The method takes a connection name parameter.
In the _Program.cs_ file of your project, call the `AddRabbitMQClient` extension method to register an `IConnection` for use via the dependency injection container. The method takes a connection name parameter.

```csharp
builder.AddRabbitMQClient("messaging");
Expand Down
4 changes: 3 additions & 1 deletion src/Components/Telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,9 @@ Aspire.RabbitMQ.Client:
- Log categories:
- "RabbitMQ.Client"
- Activity source names:
- "Aspire.RabbitMQ.Client"
- "Aspire.RabbitMQ.Client" (connection establishment and retry attempts)
- "RabbitMQ.Client.Publisher" (message publishing operations; RabbitMQ.Client v7+ only)
- "RabbitMQ.Client.Subscriber" (message consumption operations; RabbitMQ.Client v7+ only)
- Metric names:
- none (currently not supported by RabbitMQ.Client library)

Expand Down
71 changes: 60 additions & 11 deletions tests/Aspire.RabbitMQ.Client.Tests/ConformanceTests.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using Aspire.TestUtilities;
using Aspire.Components.ConformanceTests;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Trace;
using RabbitMQ.Client;
using Xunit;

namespace Aspire.RabbitMQ.Client.Tests;

public class ConformanceTests : ConformanceTests<IConnection, RabbitMQClientSettings>, IClassFixture<RabbitMQContainerFixture>
{
private readonly RabbitMQContainerFixture _containerFixture;
private readonly RabbitMQContainerFixture? _containerFixture;
private string ConnectionString { get; set; }

public ConformanceTests(RabbitMQContainerFixture containerFixture, ITestOutputHelper? output = null) : base(output)
public ConformanceTests(RabbitMQContainerFixture? containerFixture, ITestOutputHelper? output = null) : base(output)
{
_containerFixture = containerFixture;
ConnectionString = (_containerFixture is not null && RequiresFeatureAttribute.IsFeatureSupported(TestFeature.Docker))
? _containerFixture.GetConnectionString()
: "amqp://localhost:5672";
}

protected override ServiceLifetime ServiceLifetime => ServiceLifetime.Singleton;
Expand All @@ -31,7 +38,11 @@ public ConformanceTests(RabbitMQContainerFixture containerFixture, ITestOutputHe

protected override string[] RequiredLogCategories => Array.Empty<string>();

protected override string ActivitySourceName => "";
#if RABBITMQ_V6
protected override string ActivitySourceName => "Aspire.RabbitMQ.Client";
Comment thread
eerhardt marked this conversation as resolved.
#else
protected override string ActivitySourceName => "RabbitMQ.Client.Publisher";
#endif

protected override string? ConfigurationSectionName => "Aspire:RabbitMQ:Client";

Expand Down Expand Up @@ -69,15 +80,9 @@ protected override (string json, string error)[] InvalidJsonToErrorMessage => ne
};

protected override void PopulateConfiguration(ConfigurationManager configuration, string? key = null)
{
var connectionString = RequiresFeatureAttribute.IsFeatureSupported(TestFeature.Docker) ?
Comment thread
eerhardt marked this conversation as resolved.
_containerFixture.GetConnectionString() :
"amqp://localhost:5672";

configuration.AddInMemoryCollection([
new(CreateConfigKey("Aspire:RabbitMQ:Client", key, "ConnectionString"), connectionString)
=> configuration.AddInMemoryCollection([
new(CreateConfigKey("Aspire:RabbitMQ:Client", key, "ConnectionString"), ConnectionString)
]);
}

protected override void RegisterComponent(HostApplicationBuilder builder, Action<RabbitMQClientSettings>? configure = null, string? key = null)
{
Expand Down Expand Up @@ -132,4 +137,48 @@ protected override void SetupConnectionInformationIsDelayValidated()
{
Assert.Skip("RabbitMQ connects to localhost by default if the connection information isn't available.");
}

#if !RABBITMQ_V6
[Fact]
[RequiresFeature(TestFeature.Docker)]
public void TracingEnablesTheRightActivitySource()
=> RemoteInvokeWithLogging(static connectionStringToUse =>
RunWithConnectionString(connectionStringToUse, static obj => obj.RunActivitySourceTest(key: null)),
ConnectionString, Output);

[Fact]
[RequiresFeature(TestFeature.Docker)]
public void TracingEnablesTheRightActivitySource_Keyed()
=> RemoteInvokeWithLogging(static connectionStringToUse =>
RunWithConnectionString(connectionStringToUse, static obj => obj.RunActivitySourceTest(key: "key")),
ConnectionString, Output);

private void RunActivitySourceTest(string? key)
Comment thread
eerhardt marked this conversation as resolved.
{
HostApplicationBuilder builder = CreateHostBuilder(key: key);
builder.Logging.AddConsole();
RegisterComponent(builder, options => SetTracing(options, true), key);

List<Activity> exportedActivities = [];
builder.Services.AddOpenTelemetry().WithTracing(traceBuilder => traceBuilder.AddInMemoryExporter(exportedActivities));

using IHost host = builder.Build();
host.Start();

IConnection service = key is null
? host.Services.GetRequiredService<IConnection>()
: host.Services.GetRequiredKeyedService<IConnection>(key);

// Clear activities generated during connection establishment (from "Aspire.RabbitMQ.Client" source)
exportedActivities.Clear();

TriggerActivity(service);

Assert.NotEmpty(exportedActivities);
Assert.Contains(exportedActivities, activity => activity.Source.Name == ActivitySourceName);
}

private static void RunWithConnectionString(string connectionString, Action<ConformanceTests> test)
=> test(new ConformanceTests(null) { ConnectionString = connectionString });
#endif
}
Loading