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

Feature/455 Added WithNetworkAliases functionality #480

Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ To configure a container, use the `TestcontainersBuilder<TestcontainersContainer
- `WithBindMount` binds a path of a file or directory into the container e.g. `-v, --volume .:/tmp`.
- `WithVolumeMount` mounts a managed volume into the container e.g. `--mount type=volume,source=.,destination=/tmp`.
- `WithNetwork` assigns a network to the container e.g. `--network="bridge"`.
- `WithNetworkAliases` assigns a network scoped aliases to the container e.g. `--network-alias alias`
- `WithDockerEndpoint` sets the Docker API endpoint e.g. `-H tcp://0.0.0.0:2376`.
- `WithRegistryAuthentication` basic authentication against a private Docker registry.
- `WithOutputConsumer` redirects `stdout` and `stderr` to capture the container output.
Expand Down
16 changes: 16 additions & 0 deletions src/Testcontainers/Builders/ITestcontainersBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,22 @@ public interface ITestcontainersBuilder<out TDockerContainer> : IAbstractBuilder
[PublicAPI]
ITestcontainersBuilder<TDockerContainer> WithNetwork(IDockerNetwork dockerNetwork);

/// <summary>
/// Assign specified network aliases to container.
/// </summary>
/// <param name="networkAliases">Set of network aliases.</param>
/// <returns>A configured instance of <see cref="ITestcontainersBuilder{TDockerContainer}" />.</returns>
[PublicAPI]
ITestcontainersBuilder<TDockerContainer> WithNetworkAliases(params string[] networkAliases);

/// <summary>
/// Assign specified network aliases to container.
/// </summary>
/// <param name="networkAliases">Set of network aliases.</param>
/// <returns>A configured instance of <see cref="ITestcontainersBuilder{TDockerContainer}" />.</returns>
[PublicAPI]
ITestcontainersBuilder<TDockerContainer> WithNetworkAliases(IEnumerable<string> networkAliases);

/// <summary>
/// If true, the Docker daemon will remove the stopped Testcontainer automatically. Otherwise, the Testcontainer will be kept.
/// </summary>
Expand Down
16 changes: 15 additions & 1 deletion src/Testcontainers/Builders/TestcontainersBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace DotNet.Testcontainers.Builders
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -235,6 +236,18 @@ public ITestcontainersBuilder<TDockerContainer> WithNetwork(IDockerNetwork docke
return this.MergeNewConfiguration(new TestcontainersConfiguration(networks: networks));
}

/// <inheritdoc cref="ITestcontainersBuilder{TDockerContainer}" />
public ITestcontainersBuilder<TDockerContainer> WithNetworkAliases(params string[] networkAliases)
{
return this.WithNetworkAliases(networkAliases.AsEnumerable());
}

/// <inheritdoc cref="ITestcontainersBuilder{TDockerContainer}" />
public ITestcontainersBuilder<TDockerContainer> WithNetworkAliases(IEnumerable<string> networkAliases)
{
return this.MergeNewConfiguration(new TestcontainersConfiguration(networkAliases: networkAliases));
}

/// <inheritdoc cref="ITestcontainersBuilder{TDockerContainer}" />
public ITestcontainersBuilder<TDockerContainer> WithAutoRemove(bool autoRemove)
{
Expand Down Expand Up @@ -321,14 +334,15 @@ protected virtual ITestcontainersBuilder<TDockerContainer> MergeNewConfiguration
var portBindings = BuildConfiguration.Combine(dockerResourceConfiguration.PortBindings, this.DockerResourceConfiguration.PortBindings);
var mounts = BuildConfiguration.Combine(dockerResourceConfiguration.Mounts, this.DockerResourceConfiguration.Mounts);
var networks = BuildConfiguration.Combine(dockerResourceConfiguration.Networks, this.DockerResourceConfiguration.Networks);
var networkAliases = BuildConfiguration.Combine(dockerResourceConfiguration.NetworkAliases, this.DockerResourceConfiguration.NetworkAliases);

var dockerEndpointAuthConfig = BuildConfiguration.Combine(dockerResourceConfiguration.DockerEndpointAuthConfig, this.DockerResourceConfiguration.DockerEndpointAuthConfig);
var dockerRegistryAuthConfig = BuildConfiguration.Combine(dockerResourceConfiguration.DockerRegistryAuthConfig, this.DockerResourceConfiguration.DockerRegistryAuthConfig);
var outputConsumer = BuildConfiguration.Combine(dockerResourceConfiguration.OutputConsumer, this.DockerResourceConfiguration.OutputConsumer);
var waitStrategies = BuildConfiguration.Combine<IEnumerable<IWaitUntil>>(dockerResourceConfiguration.WaitStrategies, this.DockerResourceConfiguration.WaitStrategies);
var startupCallback = BuildConfiguration.Combine(dockerResourceConfiguration.StartupCallback, this.DockerResourceConfiguration.StartupCallback);

var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, outputConsumer, waitStrategies, startupCallback, autoRemove, privileged);
var updatedDockerResourceConfiguration = new TestcontainersConfiguration(dockerEndpointAuthConfig, dockerRegistryAuthConfig, image, name, hostname, workingDirectory, entrypoint, command, environments, labels, exposedPorts, portBindings, mounts, networks, networkAliases, outputConsumer, waitStrategies, startupCallback, autoRemove, privileged);
return new TestcontainersBuilder<TDockerContainer>(updatedDockerResourceConfiguration, moduleConfiguration ?? this.mergeModuleConfiguration);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ public TestcontainersConfigurationConverter(ITestcontainersConfiguration configu
this.ExposedPorts = new ToExposedPorts().Convert(configuration.ExposedPorts)?.ToDictionary(item => item.Key, item => item.Value);
this.PortBindings = new ToPortBindings().Convert(configuration.PortBindings)?.ToDictionary(item => item.Key, item => item.Value);
this.Mounts = new ToMounts().Convert(configuration.Mounts)?.ToList();
this.Networks = new ToNetworks().Convert(configuration.Networks)?.ToDictionary(item => item.Key, item => item.Value);
this.Networks = new ToNetworks().Convert(configuration.Networks)?.ToDictionary(
network => network.Key,
network =>
{
network.Value.Aliases = configuration.NetworkAliases?.ToArray();
return network.Value;
});
}

public IList<string> Entrypoint { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public interface ITestcontainersConfiguration : IDockerResourceConfiguration
/// </summary>
IEnumerable<IDockerNetwork> Networks { get; }

/// <summary>
/// Gets a list of container network aliases.
/// </summary>
IEnumerable<string> NetworkAliases { get; }

/// <summary>
/// Gets the output consumer.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public TestcontainersConfiguration(IDockerResourceConfiguration dockerResourceCo
/// <param name="portBindings">The port bindings.</param>
/// <param name="mounts">The volumes.</param>
/// <param name="networks">The networks.</param>
/// <param name="networkAliases">The container network aliases.</param>
/// <param name="outputConsumer">The output consumer.</param>
/// <param name="waitStrategies">The wait strategies.</param>
/// <param name="startupCallback">The startup callback.</param>
Expand All @@ -59,6 +60,7 @@ public TestcontainersConfiguration(
IReadOnlyDictionary<string, string> portBindings = null,
IEnumerable<IMount> mounts = null,
IEnumerable<IDockerNetwork> networks = null,
IEnumerable<string> networkAliases = null,
IOutputConsumer outputConsumer = null,
IEnumerable<IWaitUntil> waitStrategies = null,
Func<ITestcontainersContainer, CancellationToken, Task> startupCallback = null,
Expand All @@ -80,6 +82,7 @@ public TestcontainersConfiguration(
this.PortBindings = portBindings;
this.Mounts = mounts;
this.Networks = networks;
this.NetworkAliases = networkAliases;
this.OutputConsumer = outputConsumer;
this.WaitStrategies = waitStrategies;
this.StartupCallback = startupCallback;
Expand Down Expand Up @@ -129,6 +132,9 @@ public TestcontainersConfiguration(
/// <inheritdoc />>
public IEnumerable<IDockerNetwork> Networks { get; }

/// <inheritdoc />>
public IEnumerable<string> NetworkAliases { get; }

/// <inheritdoc />
public IOutputConsumer OutputConsumer { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace DotNet.Testcontainers.Tests.Unit
[Collection(nameof(Testcontainers))]
public sealed class TestcontainersNetworkTest : IClassFixture<NetworkFixture>, IAsyncLifetime
{
private const string AliasSuffix = "-alias";

private readonly ITestcontainersContainer testcontainer1;

private readonly ITestcontainersContainer testcontainer2;
Expand All @@ -22,10 +24,12 @@ public TestcontainersNetworkTest(NetworkFixture networkFixture)

this.testcontainer1 = testcontainersBuilder
.WithHostname(nameof(this.testcontainer1))
.WithNetworkAliases(nameof(this.testcontainer1) + AliasSuffix)
.Build();

this.testcontainer2 = testcontainersBuilder
.WithHostname(nameof(this.testcontainer2))
.WithNetworkAliases(nameof(this.testcontainer2) + AliasSuffix)
.Build();
}

Expand All @@ -39,10 +43,13 @@ public Task DisposeAsync()
return Task.WhenAll(this.testcontainer1.DisposeAsync().AsTask(), this.testcontainer2.DisposeAsync().AsTask());
}

[Fact]
public async Task PingContainer()
[Theory]
[InlineData(nameof(testcontainer2))]
[InlineData(nameof(testcontainer2) + AliasSuffix)]
public async Task PingContainer(string destination)
{
Assert.Equal(0, (await this.testcontainer1.ExecAsync(new[] { "ping", "-c", "4", nameof(this.testcontainer2) })).ExitCode);
var execResult = await this.testcontainer1.ExecAsync(new[] { "ping", "-c", "4", destination });
Assert.Equal(0, execResult.ExitCode);
}
}
}