Skip to content

Commit

Permalink
feat(ServiceBus): Add support to use existing MSSQL container instanc…
Browse files Browse the repository at this point in the history
…es (#1335)

Co-authored-by: Andre Hofmeister <[email protected]>
  • Loading branch information
lgcmotta and HofmeisterAn authored Feb 3, 2025
1 parent 8ac4b0d commit ae50c59
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 27 deletions.
67 changes: 46 additions & 21 deletions src/Testcontainers.ServiceBus/ServiceBusBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,55 @@ public ServiceBusBuilder WithAcceptLicenseAgreement(bool acceptLicenseAgreement)
return WithEnvironment(AcceptLicenseAgreementEnvVar, licenseAgreement);
}

/// <summary>
/// Sets the dependent MSSQL container for the Azure Service Bus Emulator.
/// </summary>
/// <remarks>
/// This method allows an existing MSSQL container to be attached to the Azure Service
/// Bus Emulator. The containers must be on the same network to enable communication
/// between them.
/// </remarks>
/// <param name="network">The network to connect the container to.</param>
/// <param name="container">The MSSQL container.</param>
/// <param name="networkAlias">The MSSQL container network alias.</param>
/// <param name="password">The MSSQL container password.</param>
/// <returns>A configured instance of <see cref="ServiceBusBuilder" />.</returns>
public ServiceBusBuilder WithMsSqlContainer(
INetwork network,
MsSqlContainer container,
string networkAlias,
string password = MsSqlBuilder.DefaultPassword)
{
return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(databaseContainer: container))
.DependsOn(container)
.WithNetwork(network)
.WithNetworkAliases(ServiceBusNetworkAlias)
.WithEnvironment("SQL_SERVER", networkAlias)
.WithEnvironment("MSSQL_SA_PASSWORD", password);
}

/// <inheritdoc />
public override ServiceBusContainer Build()
{
Validate();
return new ServiceBusContainer(DockerResourceConfiguration);

if (DockerResourceConfiguration.DatabaseContainer != null)
{
return new ServiceBusContainer(DockerResourceConfiguration);
}

// If the user has not provided an existing MSSQL container instance,
// we configure one.
var network = new NetworkBuilder()
.Build();

var container = new MsSqlBuilder()
.WithNetwork(network)
.WithNetworkAliases(DatabaseNetworkAlias)
.Build();

var serviceBusContainer = WithMsSqlContainer(network, container, DatabaseNetworkAlias);
return new ServiceBusContainer(serviceBusContainer.DockerResourceConfiguration);
}

/// <inheritdoc />
Expand All @@ -80,10 +124,7 @@ protected override ServiceBusBuilder Init()
{
return base.Init()
.WithImage(ServiceBusImage)
.WithNetwork(new NetworkBuilder().Build())
.WithNetworkAliases(ServiceBusNetworkAlias)
.WithPortBinding(ServiceBusPort, true)
.WithMsSqlContainer()
.WithWaitStrategy(Wait.ForUnixContainer()
.UntilMessageIsLogged("Emulator Service is Successfully Up!")
.AddCustomWaitStrategy(new WaitTwoSeconds()));
Expand All @@ -107,25 +148,9 @@ protected override ServiceBusBuilder Merge(ServiceBusConfiguration oldValue, Ser
return new ServiceBusBuilder(new ServiceBusConfiguration(oldValue, newValue));
}

/// <summary>
/// Configures the dependent MSSQL container.
/// </summary>
/// <returns>A configured instance of <see cref="ServiceBusBuilder" />.</returns>
private ServiceBusBuilder WithMsSqlContainer()
{
var msSqlContainer = new MsSqlBuilder()
.WithNetwork(DockerResourceConfiguration.Networks.Single())
.WithNetworkAliases(DatabaseNetworkAlias)
.Build();

return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(databaseContainer: msSqlContainer))
.WithEnvironment("MSSQL_SA_PASSWORD", MsSqlBuilder.DefaultPassword)
.WithEnvironment("SQL_SERVER", DatabaseNetworkAlias);
}

/// <inheritdoc cref="IWaitUntil" />
/// <remarks>
/// This is a workaround to ensure that the wait strategy does not indicate
/// This is a workaround to ensure that the wait strategy does not indicate
/// readiness too early:
/// https://github.com/Azure/azure-service-bus-emulator-installer/issues/35#issuecomment-2497164533.
/// </remarks>
Expand Down
3 changes: 1 addition & 2 deletions src/Testcontainers.ServiceBus/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Text.RegularExpressions;
global using System.Threading;
global using System.Threading.Tasks;
global using Docker.DotNet.Models;
global using DotNet.Testcontainers;
global using DotNet.Testcontainers.Builders;
global using DotNet.Testcontainers.Configurations;
global using DotNet.Testcontainers.Containers;
global using DotNet.Testcontainers.Images;
global using DotNet.Testcontainers.Networks;
global using JetBrains.Annotations;
global using Testcontainers.MsSql;
2 changes: 1 addition & 1 deletion src/Testcontainers/Builders/IContainerBuilder`2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ public interface IContainerBuilder<out TBuilderEntity, out TContainerEntity> : I
/// <summary>
/// Assigns the specified network to the container.
/// </summary>
/// <param name="network">The network to connect container to.</param>
/// <param name="network">The network to connect the container to.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity WithNetwork(INetwork network);
Expand Down
48 changes: 46 additions & 2 deletions tests/Testcontainers.ServiceBus.Tests/ServiceBusContainerTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
namespace Testcontainers.ServiceBus;

public sealed class ServiceBusContainerTest : IAsyncLifetime
public abstract class ServiceBusContainerTest : IAsyncLifetime
{
private readonly ServiceBusContainer _serviceBusContainer = new ServiceBusBuilder().WithAcceptLicenseAgreement(true).Build();
private readonly ServiceBusContainer _serviceBusContainer;

private ServiceBusContainerTest(ServiceBusContainer serviceBusContainer)
{
_serviceBusContainer = serviceBusContainer;
}

public Task InitializeAsync()
{
Expand Down Expand Up @@ -47,4 +52,43 @@ await sender.SendMessageAsync(message)
// Then
Assert.Equal(helloServiceBus, receivedMessage.Body.ToString());
}

[UsedImplicitly]
public sealed class ServiceBusDefaultMsSqlConfiguration : ServiceBusContainerTest
{
public ServiceBusDefaultMsSqlConfiguration()
: base(new ServiceBusBuilder().WithAcceptLicenseAgreement(true).Build())
{
}
}

[UsedImplicitly]
public sealed class ServiceBusCustomMsSqlConfiguration : ServiceBusContainerTest, IClassFixture<DatabaseFixture>
{
public ServiceBusCustomMsSqlConfiguration(DatabaseFixture fixture)
: base(new ServiceBusBuilder().WithAcceptLicenseAgreement(true).WithMsSqlContainer(fixture.Network, fixture.Container, fixture.DatabaseNetworkAlias).Build())
{
}
}

[UsedImplicitly]
public sealed class DatabaseFixture
{
public DatabaseFixture()
{
Network = new NetworkBuilder()
.Build();

Container = new MsSqlBuilder()
.WithNetwork(Network)
.WithNetworkAliases(DatabaseNetworkAlias)
.Build();
}

public string DatabaseNetworkAlias => ServiceBusBuilder.DatabaseNetworkAlias;

public INetwork Network { get; }

public MsSqlContainer Container { get; }
}
}
5 changes: 4 additions & 1 deletion tests/Testcontainers.ServiceBus.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
global using System;
global using System.Threading.Tasks;
global using Azure.Messaging.ServiceBus;
global using DotNet.Testcontainers.Builders;
global using DotNet.Testcontainers.Commons;
global using DotNet.Testcontainers.Networks;
global using JetBrains.Annotations;
global using Testcontainers.MsSql;
global using Xunit;

0 comments on commit ae50c59

Please sign in to comment.