Skip to content

Commit

Permalink
feat: Add Docker host and socket override custom configuration (#691)
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn committed Nov 25, 2022
1 parent 15c7d9e commit 45a8935
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 21 deletions.
24 changes: 13 additions & 11 deletions docs/custom_configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

Testcontainers supports various configurations to set up your test environment. It automatically discovers the Docker environment and applies the configuration. You can set or override the default values either with the Testcontainers [properties file][properties-file-format] (`~/testcontainers.properties`) or with environment variables. If you prefer to configure your test environment at runtime, you can set or override the configuration through the `TestcontainersSettings` class. The following configurations are available:

| Properties File | Environment Variable | Description | Default |
|-------------------------|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| `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.auth.config` | `DOCKER_AUTH_CONFIG` | The Docker configuration file content (GitLab: [Use statically-defined credentials][use-statically-defined-credentials]). | - |
| `docker.cert.path` | `DOCKER_CERT_PATH` | The directory path that contains the client certificate (`{ca,cert,key}.pem`) files. | `~/.docker/` |
| `docker.tls` | `DOCKER_TLS` | Enables TLS. | false |
| `docker.tls.verify` | `DOCKER_TLS_VERIFY` | Enables TLS verify. | false |
| `ryuk.disabled` | `TESTCONTAINERS_RYUK_DISABLED` | Disables Ryuk (resource reaper). | false |
| `ryuk.container.image` | `TESTCONTAINERS_RYUK_CONTAINER_IMAGE` | The Ryuk (resource reaper) Docker image. | `testcontainers/ryuk:0.3.4` |
| `hub.image.name.prefix` | `TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX` | The name to use for substituting the Docker Hub registry part of the image name. | - |
| Properties File | Environment Variable | Description | Default |
|--------------------------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| `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.auth.config` | `DOCKER_AUTH_CONFIG` | The Docker configuration file content (GitLab: [Use statically-defined credentials][use-statically-defined-credentials]). | - |
| `docker.cert.path` | `DOCKER_CERT_PATH` | The directory path that contains the client certificate (`{ca,cert,key}.pem`) files. | `~/.docker/` |
| `docker.tls` | `DOCKER_TLS` | Enables TLS. | `false` |
| `docker.tls.verify` | `DOCKER_TLS_VERIFY` | Enables TLS verify. | `false` |
| `host.override` | `TESTCONTAINERS_HOST_OVERRIDE` | The host that exposes Docker's ports. | - |
| `docker.socket.override` | `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE` | The file path to the Docker daemon socket that is used by Ryuk (resource reaper). | `/var/run/docker.sock` |
| `ryuk.disabled` | `TESTCONTAINERS_RYUK_DISABLED` | Disables Ryuk (resource reaper). | `false` |
| `ryuk.container.image` | `TESTCONTAINERS_RYUK_CONTAINER_IMAGE` | The Ryuk (resource reaper) Docker image. | `testcontainers/ryuk:0.3.4` |
| `hub.image.name.prefix` | `TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX` | The name to use for substituting the Docker Hub registry part of the image name. | - |

## Enable logging

Expand Down
10 changes: 10 additions & 0 deletions src/Testcontainers/Configurations/CustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ protected Uri GetDockerHost(string propertyName)
return this.properties.TryGetValue(propertyName, out var propertyValue) && Uri.TryCreate(propertyValue, UriKind.RelativeOrAbsolute, out var dockerHost) ? dockerHost : null;
}

protected string GetDockerHostOverride(string propertyName)
{
return this.GetPropertyValue(propertyName);
}

protected string GetDockerSocketOverride(string propertyName)
{
return this.GetPropertyValue(propertyName);
}

protected JsonDocument GetDockerAuthConfig(string propertyName)
{
_ = this.properties.TryGetValue(propertyName, out var propertyValue);
Expand Down
18 changes: 18 additions & 0 deletions src/Testcontainers/Configurations/EnvironmentConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ internal sealed class EnvironmentConfiguration : CustomConfiguration, ICustomCon

private const string DockerTlsVerify = "DOCKER_TLS_VERIFY";

private const string DockerHostOverride = "TESTCONTAINERS_HOST_OVERRIDE";

private const string DockerSocketOverride = "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE";

private const string RyukDisabled = "TESTCONTAINERS_RYUK_DISABLED";

private const string RyukContainerImage = "TESTCONTAINERS_RYUK_CONTAINER_IMAGE";
Expand All @@ -44,6 +48,8 @@ public EnvironmentConfiguration()
DockerHost,
DockerTls,
DockerTlsVerify,
DockerHostOverride,
DockerSocketOverride,
RyukDisabled,
RyukContainerImage,
HubImageNamePrefix,
Expand All @@ -70,6 +76,18 @@ public Uri GetDockerHost()
return this.GetDockerHost(DockerHost);
}

/// <inheritdoc />
public string GetDockerHostOverride()
{
return this.GetDockerHostOverride(DockerHostOverride);
}

/// <inheritdoc />
public string GetDockerSocketOverride()
{
return this.GetDockerSocketOverride(DockerSocketOverride);
}

/// <inheritdoc />
public JsonDocument GetDockerAuthConfig()
{
Expand Down
34 changes: 25 additions & 9 deletions src/Testcontainers/Configurations/ICustomConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,68 +14,84 @@ internal interface ICustomConfiguration
/// Gets the Docker config custom configuration.
/// </summary>
/// <returns>The Docker config custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
string GetDockerConfig();

/// <summary>
/// Gets the Docker host custom configuration.
/// </summary>
/// <returns>The Docker host custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
Uri GetDockerHost();

/// <summary>
/// Gets the Docker host override custom configuration.
/// </summary>
/// <returns>The Docker host override custom configuration.</returns>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
string GetDockerHostOverride();

/// <summary>
/// Gets the Docker socket override custom configuration.
/// </summary>
/// <returns>The Docker socket override custom configuration.</returns>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
string GetDockerSocketOverride();

/// <summary>
/// Gets the Docker registry authentication custom configuration.
/// </summary>
/// <returns>The Docker authentication custom configuration.</returns>
/// <remarks>https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#access-an-image-from-a-private-container-registry.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
JsonDocument GetDockerAuthConfig();

/// <summary>
/// Gets the Docker certificates path custom configuration.
/// </summary>
/// <returns>The Docker certificates path custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
string GetDockerCertPath();

/// <summary>
/// Gets the Docker TLS custom configuration.
/// </summary>
/// <returns>The Docker TLS custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
bool GetDockerTls();

/// <summary>
/// Gets the Docker TLS verify custom configuration.
/// </summary>
/// <returns>The Docker TLS verify custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
bool GetDockerTlsVerify();

/// <summary>
/// Gets the Ryuk disabled custom configuration.
/// </summary>
/// <returns>The Ryuk disabled custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-ryuk-resource-reaper.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
bool GetRyukDisabled();

/// <summary>
/// Gets the Ryuk container image custom configuration.
/// </summary>
/// <returns>The Ryuk container image custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/configuration/#customizing-ryuk-resource-reaper.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
IDockerImage GetRyukContainerImage();

/// <summary>
/// Gets the Docker Hub image name prefix custom configuration.
/// </summary>
/// <returns>The Docker Hub image name prefix custom configuration.</returns>
/// <remarks>https://www.testcontainers.org/features/image_name_substitution/.</remarks>
/// <remarks>https://dotnet.testcontainers.org/custom_configuration/.</remarks>
[CanBeNull]
string GetHubImageNamePrefix();
}
Expand Down
14 changes: 14 additions & 0 deletions src/Testcontainers/Configurations/PropertiesFileConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ public Uri GetDockerHost()
return this.GetDockerHost(propertyName);
}

/// <inheritdoc />
public string GetDockerHostOverride()
{
const string propertyName = "host.override";
return this.GetDockerHostOverride(propertyName);
}

/// <inheritdoc />
public string GetDockerSocketOverride()
{
const string propertyName = "docker.socket.override";
return this.GetDockerSocketOverride(propertyName);
}

/// <inheritdoc />
public JsonDocument GetDockerAuthConfig()
{
Expand Down
5 changes: 4 additions & 1 deletion src/Testcontainers/Containers/ResourceReaper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ public sealed class ResourceReaper : IAsyncDisposable
private const ushort RyukPort = 8080;

/// <summary>
/// 60 seconds timeout.
/// 60 seconds connection timeout.
/// </summary>
private const int ConnectionTimeoutInSeconds = 60;

/// <summary>
/// 2 seconds retry timeout.
/// </summary>
private const int RetryTimeoutInSeconds = 2;

private static readonly SemaphoreSlim DefaultLock = new SemaphoreSlim(1, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ static EnvironmentConfigurationTest()
EnvironmentVariables.Add("DOCKER_CERT_PATH");
EnvironmentVariables.Add("DOCKER_TLS");
EnvironmentVariables.Add("DOCKER_TLS_VERIFY");
EnvironmentVariables.Add("TESTCONTAINERS_HOST_OVERRIDE");
EnvironmentVariables.Add("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE");
EnvironmentVariables.Add("TESTCONTAINERS_RYUK_DISABLED");
EnvironmentVariables.Add("TESTCONTAINERS_RYUK_CONTAINER_IMAGE");
EnvironmentVariables.Add("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX");
Expand Down Expand Up @@ -48,6 +50,28 @@ public void GetDockerHostCustomConfiguration(string propertyName, string propert
Assert.Equal(expected, customConfiguration.GetDockerHost()?.ToString());
}

[Theory]
[InlineData("", "", null)]
[InlineData("TESTCONTAINERS_HOST_OVERRIDE", "", null)]
[InlineData("TESTCONTAINERS_HOST_OVERRIDE", "docker.svc.local", "docker.svc.local")]
public void GetDockerHostOverrideCustomConfiguration(string propertyName, string propertyValue, string expected)
{
SetEnvironmentVariable(propertyName, propertyValue);
ICustomConfiguration customConfiguration = new EnvironmentConfiguration();
Assert.Equal(expected, customConfiguration.GetDockerHostOverride());
}

[Theory]
[InlineData("", "", null)]
[InlineData("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "", null)]
[InlineData("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock", "/var/run/docker.sock")]
public void GetDockerSocketOverrideCustomConfiguration(string propertyName, string propertyValue, string expected)
{
SetEnvironmentVariable(propertyName, propertyValue);
ICustomConfiguration customConfiguration = new EnvironmentConfiguration();
Assert.Equal(expected, customConfiguration.GetDockerSocketOverride());
}

[Theory]
[InlineData("", "", null)]
[InlineData("DOCKER_AUTH_CONFIG", "", null)]
Expand Down Expand Up @@ -179,6 +203,26 @@ public void GetDockerHostCustomConfiguration(string configuration, string expect
Assert.Equal(expected, customConfiguration.GetDockerHost()?.ToString());
}

[Theory]
[InlineData("", null)]
[InlineData("host.override=", null)]
[InlineData("host.override=docker.svc.local", "docker.svc.local")]
public void GetDockerHostOverrideCustomConfiguration(string configuration, string expected)
{
ICustomConfiguration customConfiguration = new PropertiesFileConfiguration(new[] { configuration });
Assert.Equal(expected, customConfiguration.GetDockerHostOverride());
}

[Theory]
[InlineData("", null)]
[InlineData("docker.socket.override=", null)]
[InlineData("docker.socket.override=/var/run/docker.sock", "/var/run/docker.sock")]
public void GetDockerSocketOverrideCustomConfiguration(string configuration, string expected)
{
ICustomConfiguration customConfiguration = new PropertiesFileConfiguration(new[] { configuration });
Assert.Equal(expected, customConfiguration.GetDockerSocketOverride());
}

[Theory]
[InlineData("", null)]
[InlineData("docker.auth.config=", null)]
Expand Down

0 comments on commit 45a8935

Please sign in to comment.