Skip to content
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 docs/custom_configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Testcontainers supports various configurations to set up your test environment.

| Properties File | Environment Variable | Description | Default |
|---------------------------------|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------------------------------|
| `docker.api.version` | `DOCKER_API_VERSION` | The Docker API version to use. | `1.44` |
| `docker.config` | `DOCKER_CONFIG` | The directory path that contains the Docker configuration (`config.json`) file. | `~/.docker/` |
| `docker.host` | `DOCKER_HOST` | The Docker daemon socket to connect to. | - |
| `docker.context` | `DOCKER_CONTEXT` | The Docker context to connect to. | - |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public override bool IsApplicable()
return !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && DockerEngine != null;
}

/// <inheritdoc />
public Version GetDockerApiVersion()
{
return null;
}

/// <inheritdoc />
public string GetDockerConfig()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public virtual bool IsAvailable()
{
using (var dockerClientConfiguration = authConfig.GetDockerClientConfiguration(ResourceReaper.DefaultSessionId))
{
using (var dockerClient = dockerClientConfiguration.CreateClient())
using (var dockerClient = dockerClientConfiguration.CreateClient(authConfig.Version))
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public override IDockerEndpointAuthenticationConfiguration GetAuthConfig()
return new DockerEndpointAuthenticationConfiguration(_dockerEngine);
}

/// <inheritdoc />
public Version GetDockerApiVersion()
{
return _customConfiguration.GetDockerApiVersion();
}

/// <inheritdoc />
public string GetDockerConfig()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers/Clients/DockerApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private static IDockerClient GetDockerClient(Guid sessionId, IDockerEndpointAuth
{
using (var dockerClientConfiguration = dockerEndpointAuthConfig.GetDockerClientConfiguration(sessionId))
{
return dockerClientConfiguration.CreateClient();
return dockerClientConfiguration.CreateClient(dockerEndpointAuthConfig.Version);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public readonly struct DockerEndpointAuthenticationConfiguration : IDockerEndpointAuthenticationConfiguration
{
// https://github.com/moby/moby/releases/tag/docker-v29.0.0.
private static readonly Version DockerEngineApi = EnvironmentConfiguration.Instance.GetDockerApiVersion() ?? PropertiesFileConfiguration.Instance.GetDockerApiVersion() ?? new Version(1, 44);

// Since the static `TestcontainersSettings` class holds the detected container
// runtime information from the auto-discovery mechanism, we can't add a static
// `NamedPipeConnectionTimeout` property to it because that would create a
Expand All @@ -30,6 +33,9 @@ public DockerEndpointAuthenticationConfiguration(Uri endpoint, Credentials crede
Credentials = credentials;
}

/// <inheritdoc />
public Version Version => DockerEngineApi;

/// <inheritdoc />
public Uri Endpoint { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public interface IDockerEndpointAuthenticationConfiguration
{
/// <summary>
/// Gets the Docker API version.
/// </summary>
[CanBeNull]
Version Version { get; }

/// <summary>
/// Gets the Docker API endpoint.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Testcontainers/Configurations/CustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ protected CustomConfiguration(IReadOnlyDictionary<string, string> properties)
_properties = properties;
}

protected virtual Version GetDockerApiVersion(string propertyName)
{
return _properties.TryGetValue(propertyName, out var propertyValue) && !string.IsNullOrEmpty(propertyValue) && Version.TryParse(propertyValue, out var dockerApiVersion) ? dockerApiVersion : null;
}

protected virtual string GetDockerConfig(string propertyName)
{
return GetPropertyValue<string>(propertyName);
Expand Down
13 changes: 11 additions & 2 deletions src/Testcontainers/Configurations/EnvironmentConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace DotNet.Testcontainers.Configurations
/// </summary>
internal class EnvironmentConfiguration : CustomConfiguration, ICustomConfiguration
{
private const string DockerApiVersion = "DOCKER_API_VERSION";

private const string DockerConfig = "DOCKER_CONFIG";

private const string DockerHost = "DOCKER_HOST";
Expand Down Expand Up @@ -54,11 +56,12 @@ static EnvironmentConfiguration()
public EnvironmentConfiguration()
: base(new[]
{
DockerAuthConfig,
DockerCertPath,
DockerApiVersion,
DockerConfig,
DockerHost,
DockerContext,
DockerAuthConfig,
DockerCertPath,
DockerTls,
DockerTlsVerify,
DockerHostOverride,
Expand All @@ -82,6 +85,12 @@ public EnvironmentConfiguration()
public static ICustomConfiguration Instance { get; }
= new EnvironmentConfiguration();

/// <inheritdoc />
public Version GetDockerApiVersion()
{
return GetDockerApiVersion(DockerApiVersion);
}

/// <inheritdoc />
public string GetDockerConfig()
{
Expand Down
8 changes: 8 additions & 0 deletions src/Testcontainers/Configurations/ICustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ namespace DotNet.Testcontainers.Configurations
/// </summary>
internal interface ICustomConfiguration
{
/// <summary>
/// Gets the Docker API version custom configuration.
/// </summary>
/// <returns>The Docker API version custom configuration.</returns>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
Version GetDockerApiVersion();

/// <summary>
/// Gets the Docker config custom configuration.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public PropertiesFileConfiguration(params string[] lines)
public static ICustomConfiguration Instance { get; }
= new PropertiesFileConfiguration();

/// <inheritdoc />
public Version GetDockerApiVersion()
{
const string propertyName = "docker.api.version";
return GetDockerApiVersion(propertyName);
}

/// <inheritdoc />
public string GetDockerConfig()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public sealed class DockerTlsFixture : ProtectDockerDaemonSocket
{
public DockerTlsFixture()
: base(new ContainerBuilder()
.WithCommand("--tlsverify=false"), "20.10.18")
.WithCommand("--tlsverify=false"), "29.0.0")
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace DotNet.Testcontainers.Tests.Fixtures
[UsedImplicitly]
public sealed class OpenSsl3_1Fixture : DockerMTls
{
public OpenSsl3_1Fixture() : base("24.0.5")
public OpenSsl3_1Fixture() : base("29.0.0")
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public sealed class EnvironmentConfigurationTest : IDisposable

static EnvironmentConfigurationTest()
{
EnvironmentVariables.Add("DOCKER_API_VERSION");
EnvironmentVariables.Add("DOCKER_CONFIG");
EnvironmentVariables.Add("DOCKER_HOST");
EnvironmentVariables.Add("DOCKER_CONTEXT");
Expand All @@ -34,6 +35,18 @@ static EnvironmentConfigurationTest()
EnvironmentVariables.Add("TESTCONTAINERS_NAMED_PIPE_CONNECTION_TIMEOUT");
}

[Theory]
[InlineData("", "", null)]
[InlineData("DOCKER_API_VERSION", "", null)]
[InlineData("DOCKER_API_VERSION", "version", null)]
[InlineData("DOCKER_API_VERSION", "1.52", "1.52")]
public void GetDockerApiVersionCustomConfiguration(string propertyName, string propertyValue, string expected)
{
SetEnvironmentVariable(propertyName, propertyValue);
ICustomConfiguration customConfiguration = new EnvironmentConfiguration();
Assert.Equal(expected, customConfiguration.GetDockerApiVersion()?.ToString());
}

[Theory]
[InlineData("", "", null)]
[InlineData("DOCKER_CONFIG", "", null)]
Expand Down Expand Up @@ -259,6 +272,17 @@ private static void SetEnvironmentVariable(string propertyName, string propertyV

public sealed class PropertiesFileConfigurationTest
{
[Theory]
[InlineData("", null)]
[InlineData("docker.api.version=", null)]
[InlineData("docker.api.version=version", null)]
[InlineData("docker.api.version=1.52", "1.52")]
public void GetDockerApiVersionCustomConfiguration(string configuration, string expected)
{
ICustomConfiguration customConfiguration = new PropertiesFileConfiguration(new[] { configuration });
Assert.Equal(expected, customConfiguration.GetDockerApiVersion()?.ToString());
}

[Theory]
[InlineData("", null)]
[InlineData("docker.config=", null)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace DotNet.Testcontainers.Tests.Unit
using System;
using System.Linq;
using System.Threading.Tasks;
using Docker.DotNet;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Clients;
using DotNet.Testcontainers.Configurations;
Expand All @@ -20,7 +21,7 @@ private static IDockerEndpointAuthenticationConfiguration GetAuthConfig(ProtectD
return new IDockerEndpointAuthenticationProvider[] { new MTlsEndpointAuthenticationProvider(customConfiguration), new TlsEndpointAuthenticationProvider(customConfiguration) }.First(authProvider => authProvider.IsApplicable()).GetAuthConfig();
}

public sealed class MTlsOpenSsl1_1_1 : IClassFixture<OpenSsl1_1_1Fixture>
public sealed class MTlsOpenSsl1_1_1 : IClassFixture<OpenSsl1_1_1Fixture>, IDockerEndpointAuthenticationConfiguration
{
private readonly ProtectDockerDaemonSocket _fixture;

Expand All @@ -32,11 +33,25 @@ public MTlsOpenSsl1_1_1(OpenSsl1_1_1Fixture dockerMTlsFixture)
_authConfig = GetAuthConfig(dockerMTlsFixture);
}

// The outdated image isn't compatible with the default Docker Engine API version.
// For this test, we're overriding the version.
public Version Version
=> null;

public Uri Endpoint
=> _authConfig.Endpoint;

public Credentials Credentials
=> _authConfig.Credentials;

public DockerClientConfiguration GetDockerClientConfiguration(Guid sessionId = default)
=> _authConfig.GetDockerClientConfiguration(sessionId);

[Fact]
public async Task GetVersionReturnsVersion()
{
// Given
var client = new TestcontainersClient(Guid.Empty, _authConfig, NullLogger.Instance);
var client = new TestcontainersClient(Guid.Empty, this, NullLogger.Instance);

// When
var version = await client.System.GetVersionAsync(TestContext.Current.CancellationToken)
Expand Down
Loading