Skip to content

Commit

Permalink
feat: Add container builder member to depend on other Docker resources (
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn authored Mar 24, 2023
1 parent 710987a commit f587f1c
Show file tree
Hide file tree
Showing 53 changed files with 656 additions and 653 deletions.
1 change: 1 addition & 0 deletions docs/api/create_docker_container.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Assert.Equal(MagicNumber, magicNumber);

| Builder method | Description |
|-----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
| `DependsOn` | Sets the dependent resource to resolve and create or start before starting this container configuration. |
| `WithDockerEndpoint` | Sets the Docker daemon socket to connect to. |
| `WithAutoRemove` | Will remove the stopped container automatically, similar to `--rm`. |
| `WithCleanUp` | Will remove the container automatically after all tests have been run. |
Expand Down
4 changes: 2 additions & 2 deletions src/Testcontainers.CosmosDb/CosmosDbContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ public UriRewriter(string hostname, ushort port)
}

/// <inheritdoc />
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.RequestUri = new UriBuilder(Uri.UriSchemeHttps, _hostname, _port, request.RequestUri.PathAndQuery).Uri;
return base.SendAsync(request, ct);
return base.SendAsync(request, cancellationToken);
}
}
}
2 changes: 1 addition & 1 deletion src/Testcontainers.MongoDb/MongoDbBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private sealed class WaitUntil : IWaitUntil
/// <inheritdoc />
public async Task<bool> UntilAsync(IContainer container)
{
var (stdout, stderr) = await container.GetLogs(timestampsEnabled: false)
var (stdout, stderr) = await container.GetLogsAsync(timestampsEnabled: false)
.ConfigureAwait(false);

return 2.Equals(Array.Empty<string>()
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.PostgreSql/PostgreSqlBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private sealed class WaitUntil : IWaitUntil
/// <inheritdoc />
public async Task<bool> UntilAsync(IContainer container)
{
var (stdout, stderr) = await container.GetLogs(timestampsEnabled: false)
var (stdout, stderr) = await container.GetLogsAsync(timestampsEnabled: false)
.ConfigureAwait(false);

return 2.Equals(Array.Empty<string>()
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.SqlEdge/SqlEdgeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private sealed class WaitUntil : IWaitUntil
/// <inheritdoc />
public async Task<bool> UntilAsync(IContainer container)
{
var (stdout, _) = await container.GetLogs(timestampsEnabled: false)
var (stdout, _) = await container.GetLogsAsync(timestampsEnabled: false)
.ConfigureAwait(false);

return stdout.Contains("Recovery is complete.");
Expand Down
66 changes: 0 additions & 66 deletions src/Testcontainers/BackwardCompatibility/BackwardsCompatibility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,13 @@
namespace DotNet.Testcontainers
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers;
using DotNet.Testcontainers.Images;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

namespace Containers
{
[PublicAPI]
[Obsolete("Use the IContainer interface instead.")]
public interface ITestcontainersContainer : IDockerContainer
{
}

[PublicAPI]
[Obsolete("Use the IContainer interface instead.")]
public interface IDockerContainer : IAsyncDisposable
{
[NotNull]
ILogger Logger { get; }

[NotNull]
string Id { get; }

[NotNull]
string Name { get; }

[NotNull]
string IpAddress { get; }

[NotNull]
string MacAddress { get; }

[NotNull]
string Hostname { get; }

[NotNull]
IImage Image { get; }

TestcontainersStates State { get; }

TestcontainersHealthStatus Health { get; }

long HealthCheckFailingStreak { get; }

ushort GetMappedPublicPort(int containerPort);

ushort GetMappedPublicPort(string containerPort);

[Obsolete("Use IContainer.GetExitCodeAsync(CancellationToken) instead.")]
Task<long> GetExitCode(CancellationToken ct = default);

Task<long> GetExitCodeAsync(CancellationToken ct = default);

[Obsolete("Use IContainer.GetLogsAsync(DateTime, DateTime, bool, CancellationToken) instead.")]
Task<(string Stdout, string Stderr)> GetLogs(DateTime since = default, DateTime until = default, bool timestampsEnabled = true, CancellationToken ct = default);

Task<(string Stdout, string Stderr)> GetLogsAsync(DateTime since = default, DateTime until = default, bool timestampsEnabled = true, CancellationToken ct = default);

Task StartAsync(CancellationToken ct = default);

Task StopAsync(CancellationToken ct = default);

Task CopyFileAsync(string filePath, byte[] fileContent, int accessMode = 384, int userId = 0, int groupId = 0, CancellationToken ct = default);

Task<byte[]> ReadFileAsync(string filePath, CancellationToken ct = default);

Task<ExecResult> ExecAsync(IList<string> command, CancellationToken ct = default);
}

[PublicAPI]
[Obsolete("Use the DockerContainer class instead.")]
public sealed class TestcontainersContainer : DockerContainer
Expand Down
17 changes: 17 additions & 0 deletions src/Testcontainers/Builders/BuildConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace DotNet.Testcontainers.Builders
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

public static class BuildConfiguration
Expand All @@ -27,6 +29,11 @@ public static T Combine<T>(T oldValue, T newValue)
public static IEnumerable<T> Combine<T>(IEnumerable<T> oldValue, IEnumerable<T> newValue)
where T : class
{
if (newValue == null && oldValue == null)
{
return Array.Empty<T>();
}

if (newValue == null || oldValue == null)
{
return newValue ?? oldValue;
Expand All @@ -46,6 +53,11 @@ public static IEnumerable<T> Combine<T>(IEnumerable<T> oldValue, IEnumerable<T>
public static IReadOnlyList<T> Combine<T>(IReadOnlyList<T> oldValue, IReadOnlyList<T> newValue)
where T : class
{
if (newValue == null && oldValue == null)
{
return Array.Empty<T>();
}

if (newValue == null || oldValue == null)
{
return newValue ?? oldValue;
Expand All @@ -66,6 +78,11 @@ public static IReadOnlyDictionary<TKey, TValue> Combine<TKey, TValue>(IReadOnlyD
where TKey : class
where TValue : class
{
if (newValue == null && oldValue == null)
{
return new ReadOnlyDictionary<TKey, TValue>(new Dictionary<TKey, TValue>());
}

if (newValue == null || oldValue == null)
{
return newValue ?? oldValue;
Expand Down
48 changes: 42 additions & 6 deletions src/Testcontainers/Builders/ContainerBuilder`3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,31 @@ public virtual TBuilderEntity ConfigureContainer(Action<TContainerEntity> module
throw new NotImplementedException();
}

/// <inheritdoc cref="IContainerBuilder{TBuilderEntity, TContainerEntity}" />
public TBuilderEntity DependsOn(IContainer container)
{
var containers = new[] { container };
return this.Clone(new ContainerConfiguration(containers: containers));
}

/// <inheritdoc cref="IContainerBuilder{TBuilderEntity, TContainerEntity}" />
public TBuilderEntity DependsOn(INetwork network)
{
return this.WithNetwork(network);
}

/// <inheritdoc cref="IContainerBuilder{TBuilderEntity, TContainerEntity}" />
public TBuilderEntity DependsOn(IVolume volume, string destination)
{
return this.WithVolumeMount(volume, destination);
}

/// <inheritdoc cref="IContainerBuilder{TBuilderEntity, TContainerEntity}" />
public TBuilderEntity DependsOn(IVolume volume, string destination, AccessMode accessMode)
{
return this.WithVolumeMount(volume, destination, accessMode);
}

/// <inheritdoc cref="IContainerBuilder{TBuilderEntity, TContainerEntity}" />
public TBuilderEntity WithImage(string image)
{
Expand Down Expand Up @@ -363,20 +388,26 @@ public DockerNetwork(string name)
this.Name = name;
}

/// <inheritdoc cref="INetwork" />
/// <inheritdoc />
public string Name { get; }

/// <inheritdoc cref="INetwork" />
/// <inheritdoc />
public Task CreateAsync(CancellationToken ct = default)
{
return Task.CompletedTask;
}

/// <inheritdoc cref="INetwork" />
/// <inheritdoc />
public Task DeleteAsync(CancellationToken ct = default)
{
return Task.CompletedTask;
}

/// <inheritdoc />
public ValueTask DisposeAsync()
{
return default;
}
}
}

Expand Down Expand Up @@ -423,20 +454,25 @@ public DockerVolume(string name)
this.Name = name;
}

/// <inheritdoc cref="IVolume" />
/// <inheritdoc />
public string Name { get; }

/// <inheritdoc cref="IVolume" />
/// <inheritdoc />
public Task CreateAsync(CancellationToken ct = default)
{
return Task.CompletedTask;
}

/// <inheritdoc cref="IVolume" />
/// <inheritdoc />
public Task DeleteAsync(CancellationToken ct = default)
{
return Task.CompletedTask;
}

public ValueTask DisposeAsync()
{
return default;
}
}
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/Testcontainers/Builders/IContainerBuilder`2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,41 @@ public interface IContainerBuilder<out TBuilderEntity, out TContainerEntity> : I
[PublicAPI]
TBuilderEntity ConfigureContainer(Action<TContainerEntity> moduleConfiguration);

/// <summary>
/// Sets the dependent container to resolve and start before starting this container configuration.
/// </summary>
/// <param name="container">The dependent container.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity DependsOn(IContainer container);

/// <summary>
/// Sets the dependent network to resolve and create before starting this container configuration.
/// </summary>
/// <param name="network">The dependent network.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity DependsOn(INetwork network);

/// <summary>
/// Sets the dependent volume to resolve and create before starting this container configuration.
/// </summary>
/// <param name="volume">The dependent volume.</param>
/// <param name="destination">An absolute path as destination in the container.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity DependsOn(IVolume volume, string destination);

/// <summary>
/// Sets the dependent volume to resolve and create before starting this container configuration.
/// </summary>
/// <param name="volume">The dependent volume.</param>
/// <param name="destination">An absolute path as destination in the container.</param>
/// <param name="accessMode">The volume access mode.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity DependsOn(IVolume volume, string destination, AccessMode accessMode);

/// <summary>
/// Sets an image for which to create the container.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Testcontainers/Clients/DockerImageOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ await this.DeleteAsync(image, ct)
{
Dockerfile = configuration.Dockerfile,
Tags = new List<string> { image.FullName },
BuildArgs = configuration.BuildArguments?.ToDictionary(item => item.Key, item => item.Value),
Labels = configuration.Labels?.ToDictionary(item => item.Key, item => item.Value),
BuildArgs = configuration.BuildArguments.ToDictionary(item => item.Key, item => item.Value),
Labels = configuration.Labels.ToDictionary(item => item.Key, item => item.Value),
};

if (configuration.ParameterModifiers != null)
Expand Down
4 changes: 2 additions & 2 deletions src/Testcontainers/Clients/DockerNetworkOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public async Task<string> CreateAsync(INetworkConfiguration configuration, Cance
{
Name = configuration.Name,
Driver = configuration.Driver.Value,
Options = configuration.Options?.ToDictionary(item => item.Key, item => item.Value),
Labels = configuration.Labels?.ToDictionary(item => item.Key, item => item.Value),
Options = configuration.Options.ToDictionary(item => item.Key, item => item.Value),
Labels = configuration.Labels.ToDictionary(item => item.Key, item => item.Value),
};

if (configuration.ParameterModifiers != null)
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers/Clients/DockerVolumeOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public async Task<string> CreateAsync(IVolumeConfiguration configuration, Cancel
var createParameters = new VolumesCreateParameters
{
Name = configuration.Name,
Labels = configuration.Labels?.ToDictionary(item => item.Key, item => item.Value),
Labels = configuration.Labels.ToDictionary(item => item.Key, item => item.Value),
};

if (configuration.ParameterModifiers != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class ContainerConfiguration : ResourceConfiguration<CreateContainerParam
/// <param name="exposedPorts">A dictionary of exposed ports.</param>
/// <param name="portBindings">A dictionary of port bindings.</param>
/// <param name="resourceMappings">A dictionary of resource mappings.</param>
/// <param name="containers">A list of containers.</param>
/// <param name="mounts">A list of mounts.</param>
/// <param name="networks">A list of networks.</param>
/// <param name="networkAliases">A list of network-scoped aliases.</param>
Expand All @@ -51,6 +52,7 @@ public ContainerConfiguration(
IReadOnlyDictionary<string, string> exposedPorts = null,
IReadOnlyDictionary<string, string> portBindings = null,
IReadOnlyDictionary<string, IResourceMapping> resourceMappings = null,
IEnumerable<IContainer> containers = null,
IEnumerable<IMount> mounts = null,
IEnumerable<INetwork> networks = null,
IEnumerable<string> networkAliases = null,
Expand All @@ -74,6 +76,7 @@ public ContainerConfiguration(
this.ExposedPorts = exposedPorts;
this.PortBindings = portBindings;
this.ResourceMappings = resourceMappings;
this.Containers = containers;
this.Mounts = mounts;
this.Networks = networks;
this.NetworkAliases = networkAliases;
Expand Down Expand Up @@ -114,12 +117,13 @@ public ContainerConfiguration(IContainerConfiguration oldValue, IContainerConfig
this.Hostname = BuildConfiguration.Combine(oldValue.Hostname, newValue.Hostname);
this.MacAddress = BuildConfiguration.Combine(oldValue.MacAddress, newValue.MacAddress);
this.WorkingDirectory = BuildConfiguration.Combine(oldValue.WorkingDirectory, newValue.WorkingDirectory);
this.Entrypoint = BuildConfiguration.Combine(oldValue.Entrypoint, newValue.Entrypoint);
this.Entrypoint = BuildConfiguration.Combine<IEnumerable<string>>(oldValue.Entrypoint, newValue.Entrypoint);
this.Command = BuildConfiguration.Combine(oldValue.Command, newValue.Command);
this.Environments = BuildConfiguration.Combine(oldValue.Environments, newValue.Environments);
this.ExposedPorts = BuildConfiguration.Combine(oldValue.ExposedPorts, newValue.ExposedPorts);
this.PortBindings = BuildConfiguration.Combine(oldValue.PortBindings, newValue.PortBindings);
this.ResourceMappings = BuildConfiguration.Combine(oldValue.ResourceMappings, newValue.ResourceMappings);
this.Containers = BuildConfiguration.Combine(oldValue.Containers, newValue.Containers);
this.Mounts = BuildConfiguration.Combine(oldValue.Mounts, newValue.Mounts);
this.Networks = BuildConfiguration.Combine(oldValue.Networks, newValue.Networks);
this.NetworkAliases = BuildConfiguration.Combine(oldValue.NetworkAliases, newValue.NetworkAliases);
Expand Down Expand Up @@ -172,6 +176,9 @@ public ContainerConfiguration(IContainerConfiguration oldValue, IContainerConfig
/// <inheritdoc />
public IReadOnlyDictionary<string, IResourceMapping> ResourceMappings { get; }

/// <inheritdoc />
public IEnumerable<IContainer> Containers { get; }

/// <inheritdoc />
public IEnumerable<IMount> Mounts { get; }

Expand Down
Loading

0 comments on commit f587f1c

Please sign in to comment.