diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 26e9a3944..0f8cae249 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -23,12 +23,12 @@ jobs:
uses: actions/checkout@v2
- name: Initialize CodeQL
- uses: github/codeql-action/init@v1
+ uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ uses: github/codeql-action/analyze@v2
diff --git a/src/Testcontainers/Builders/Base64Provider.cs b/src/Testcontainers/Builders/Base64Provider.cs
index df1758cf9..7131a7add 100644
--- a/src/Testcontainers/Builders/Base64Provider.cs
+++ b/src/Testcontainers/Builders/Base64Provider.cs
@@ -8,7 +8,7 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
- ///
+ ///
internal sealed class Base64Provider : IDockerRegistryAuthenticationProvider
{
private readonly JsonElement rootElement;
@@ -41,7 +41,11 @@ public Base64Provider(JsonElement jsonElement, ILogger logger)
///
public bool IsApplicable(string hostname)
{
- return !default(JsonElement).Equals(this.rootElement) && this.rootElement.EnumerateObject().Any();
+#if NETSTANDARD2_1_OR_GREATER
+ return !default(JsonElement).Equals(this.rootElement) && !JsonValueKind.Null.Equals(this.rootElement.ValueKind) && this.rootElement.EnumerateObject().Any(property => property.Name.Contains(hostname, StringComparison.OrdinalIgnoreCase));
+#else
+ return !default(JsonElement).Equals(this.rootElement) && !JsonValueKind.Null.Equals(this.rootElement.ValueKind) && this.rootElement.EnumerateObject().Any(property => property.Name.IndexOf(hostname, StringComparison.OrdinalIgnoreCase) >= 0);
+#endif
}
///
diff --git a/src/Testcontainers/Builders/CredsHelperProvider.cs b/src/Testcontainers/Builders/CredsHelperProvider.cs
index 29ddbc6ce..2edf480f7 100644
--- a/src/Testcontainers/Builders/CredsHelperProvider.cs
+++ b/src/Testcontainers/Builders/CredsHelperProvider.cs
@@ -1,66 +1,109 @@
namespace DotNet.Testcontainers.Builders
{
+ using System;
+ using System.Linq;
using System.Text.Json;
using DotNet.Testcontainers.Configurations;
+ using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
- ///
+ ///
internal sealed class CredsHelperProvider : IDockerRegistryAuthenticationProvider
{
- private const string TokenUsername = "";
- private readonly JsonElement dockerConfig;
+ private readonly JsonElement rootElement;
+
private readonly ILogger logger;
- public CredsHelperProvider(JsonElement dockerConfig, ILogger logger)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The JSON document that holds the Docker config credsHelper node.
+ /// The logger.
+ [PublicAPI]
+ public CredsHelperProvider(JsonDocument jsonDocument, ILogger logger)
+ : this(jsonDocument.RootElement, logger)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The JSON element that holds the Docker config credsHelper node.
+ /// The logger.
+ [PublicAPI]
+ public CredsHelperProvider(JsonElement jsonElement, ILogger logger)
{
- this.dockerConfig = dockerConfig;
+ this.rootElement = jsonElement.TryGetProperty("credHelpers", out var credHelpers) ? credHelpers : default;
this.logger = logger;
}
///
public bool IsApplicable(string hostname)
{
- return this.FindCredHelperName(hostname) != null;
+#if NETSTANDARD2_1_OR_GREATER
+ return !default(JsonElement).Equals(this.rootElement) && !JsonValueKind.Null.Equals(this.rootElement.ValueKind) && this.rootElement.EnumerateObject().Any(property => property.Name.Contains(hostname, StringComparison.OrdinalIgnoreCase));
+#else
+ return !default(JsonElement).Equals(this.rootElement) && !JsonValueKind.Null.Equals(this.rootElement.ValueKind) && this.rootElement.EnumerateObject().Any(property => property.Name.IndexOf(hostname, StringComparison.OrdinalIgnoreCase) >= 0);
+#endif
}
///
public IDockerRegistryAuthenticationConfiguration GetAuthConfig(string hostname)
{
- this.logger.SearchingDockerRegistryCredential("CredsHelper");
- var credHelperName = this.FindCredHelperName(hostname);
- if (credHelperName == null)
+ this.logger.SearchingDockerRegistryCredential("CredHelpers");
+
+ if (!this.IsApplicable(hostname))
+ {
+ return null;
+ }
+
+#if NETSTANDARD2_1_OR_GREATER
+ var registryEndpointProperty = this.rootElement.EnumerateObject().LastOrDefault(property => property.Name.Contains(hostname, StringComparison.OrdinalIgnoreCase));
+#else
+ var registryEndpointProperty = this.rootElement.EnumerateObject().LastOrDefault(property => property.Name.IndexOf(hostname, StringComparison.OrdinalIgnoreCase) >= 0);
+#endif
+
+ if (!JsonValueKind.String.Equals(registryEndpointProperty.Value.ValueKind))
{
return null;
}
- var credentialProviderOutput = ExternalProcessCredentialProvider.GetCredentialProviderOutput(credHelperName, hostname);
- if (credentialProviderOutput == null)
+ if (string.IsNullOrEmpty(registryEndpointProperty.Value.GetString()))
{
return null;
}
- DockerRegistryAuthenticationConfiguration dockerRegistryAuthenticationConfiguration;
+ var credentialProviderOutput = DockerCredentialProcess.Get(registryEndpointProperty.Value.GetString(), hostname);
+ if (string.IsNullOrEmpty(credentialProviderOutput))
+ {
+ return null;
+ }
+
+ JsonElement credential;
+
try
{
- var credentialProviderOutputJson = JsonSerializer.Deserialize(credentialProviderOutput);
- var username = credentialProviderOutputJson.GetProperty("Username").GetString();
- var secret = credentialProviderOutputJson.GetProperty("Secret").GetString();
- dockerRegistryAuthenticationConfiguration = username == TokenUsername ? new DockerRegistryAuthenticationConfiguration(hostname, identityToken: secret) : new DockerRegistryAuthenticationConfiguration(hostname, username, secret);
+ credential = JsonDocument.Parse(credentialProviderOutput).RootElement;
}
catch (JsonException)
{
return null;
}
+ var username = credential.TryGetProperty("Username", out var usernameProperty) ? usernameProperty.GetString() : null;
+
+ var password = credential.TryGetProperty("Secret", out var passwordProperty) ? passwordProperty.GetString() : null;
+
this.logger.DockerRegistryCredentialFound(hostname);
- return dockerRegistryAuthenticationConfiguration;
- }
- private string FindCredHelperName(string hostname)
- {
- return this.dockerConfig.TryGetProperty("credHelpers", out var credHelpersProperty) && credHelpersProperty.ValueKind != JsonValueKind.Null && credHelpersProperty.TryGetProperty(hostname, out var credHelperProperty)
- ? credHelperProperty.GetString()
- : null;
+ if ("".Equals(username, StringComparison.OrdinalIgnoreCase))
+ {
+ return new DockerRegistryAuthenticationConfiguration(hostname, null, null, password);
+ }
+ else
+ {
+ return new DockerRegistryAuthenticationConfiguration(hostname, username, password);
+ }
}
}
}
diff --git a/src/Testcontainers/Builders/CredsStoreProvider.cs b/src/Testcontainers/Builders/CredsStoreProvider.cs
index d5eb42d28..a90bac2e6 100644
--- a/src/Testcontainers/Builders/CredsStoreProvider.cs
+++ b/src/Testcontainers/Builders/CredsStoreProvider.cs
@@ -6,7 +6,7 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
- ///
+ ///
internal sealed class CredsStoreProvider : IDockerRegistryAuthenticationProvider
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions();
@@ -59,8 +59,8 @@ public IDockerRegistryAuthenticationConfiguration GetAuthConfig(string hostname)
return null;
}
- var credentialProviderOutput = ExternalProcessCredentialProvider.GetCredentialProviderOutput(this.rootElement.GetString(), hostname);
- if (credentialProviderOutput == null)
+ var credentialProviderOutput = DockerCredentialProcess.Get(this.rootElement.GetString(), hostname);
+ if (string.IsNullOrEmpty(credentialProviderOutput))
{
return null;
}
diff --git a/src/Testcontainers/Builders/DockerCredentialProcess.cs b/src/Testcontainers/Builders/DockerCredentialProcess.cs
new file mode 100644
index 000000000..81404c315
--- /dev/null
+++ b/src/Testcontainers/Builders/DockerCredentialProcess.cs
@@ -0,0 +1,41 @@
+namespace DotNet.Testcontainers.Builders
+{
+ using System;
+ using System.Diagnostics;
+
+ internal static class DockerCredentialProcess
+ {
+ public static string Get(string credentialProviderName, string hostname)
+ {
+ var dockerCredentialStartInfo = new ProcessStartInfo();
+ dockerCredentialStartInfo.FileName = "docker-credential-" + credentialProviderName;
+ dockerCredentialStartInfo.Arguments = "get";
+ dockerCredentialStartInfo.RedirectStandardInput = true;
+ dockerCredentialStartInfo.RedirectStandardOutput = true;
+ dockerCredentialStartInfo.UseShellExecute = false;
+
+ var dockerCredentialProcess = new Process();
+ dockerCredentialProcess.StartInfo = dockerCredentialStartInfo;
+
+ try
+ {
+ if (!dockerCredentialProcess.Start())
+ {
+ return null;
+ }
+
+ dockerCredentialProcess.StandardInput.WriteLine(hostname);
+ dockerCredentialProcess.StandardInput.Close();
+ return dockerCredentialProcess.StandardOutput.ReadToEnd().Trim();
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ finally
+ {
+ dockerCredentialProcess.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
index 3d75c0a53..040f182c6 100644
--- a/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
@@ -3,7 +3,7 @@
using System.Linq;
using DotNet.Testcontainers.Configurations;
- ///
+ ///
internal sealed class DockerEndpointAuthenticationProvider : IDockerEndpointAuthenticationProvider
{
///
diff --git a/src/Testcontainers/Builders/DockerRegistryAuthenticationProvider.cs b/src/Testcontainers/Builders/DockerRegistryAuthenticationProvider.cs
index 347160151..4c1b5d069 100644
--- a/src/Testcontainers/Builders/DockerRegistryAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/DockerRegistryAuthenticationProvider.cs
@@ -9,7 +9,7 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
- ///
+ ///
internal sealed class DockerRegistryAuthenticationProvider : IDockerRegistryAuthenticationProvider
{
private const string DockerHub = "index.docker.io";
@@ -83,10 +83,9 @@ private IDockerRegistryAuthenticationConfiguration GetUncachedAuthConfig(string
{
authConfig = new IDockerRegistryAuthenticationProvider[]
{
- new CredsHelperProvider(dockerConfigDocument.RootElement, this.logger),
- new CredsStoreProvider(dockerConfigDocument, this.logger),
- new Base64Provider(dockerConfigDocument, this.logger),
- }.AsParallel()
+ new CredsHelperProvider(dockerConfigDocument, this.logger), new CredsStoreProvider(dockerConfigDocument, this.logger), new Base64Provider(dockerConfigDocument, this.logger),
+ }
+ .AsParallel()
.Select(authenticationProvider => authenticationProvider.GetAuthConfig(hostname))
.FirstOrDefault(authenticationProvider => authenticationProvider != null);
}
diff --git a/src/Testcontainers/Builders/EnvironmentEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/EnvironmentEndpointAuthenticationProvider.cs
index 67f50e89a..0275f8346 100644
--- a/src/Testcontainers/Builders/EnvironmentEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/EnvironmentEndpointAuthenticationProvider.cs
@@ -3,7 +3,7 @@
using System;
using DotNet.Testcontainers.Configurations;
- ///
+ ///
internal sealed class EnvironmentEndpointAuthenticationProvider : IDockerEndpointAuthenticationProvider
{
private readonly Uri dockerEngine;
diff --git a/src/Testcontainers/Builders/IAuthenticationProvider.cs b/src/Testcontainers/Builders/IAuthenticationProvider.cs
deleted file mode 100644
index e94b83199..000000000
--- a/src/Testcontainers/Builders/IAuthenticationProvider.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace DotNet.Testcontainers.Builders
-{
- using JetBrains.Annotations;
-
- ///
- /// A Docker authentication provider.
- ///
- /// Type of the authentication configuration.
- [PublicAPI]
- internal interface IAuthenticationProvider
- {
- ///
- /// Is true when the authentication provider contains any credentials, otherwise false.
- ///
- /// True when the authentication provider contains any credentials, otherwise false.
- [PublicAPI]
- bool IsApplicable();
-
- ///
- /// Gets the Docker authentication configuration.
- ///
- /// The Docker hostname.
- /// The Docker authentication configuration or null if no configuration matches the hostname.
- [PublicAPI]
- [CanBeNull]
- TAuthenticationConfiguration GetAuthConfig(string hostname);
- }
-}
diff --git a/src/Testcontainers/Builders/IDockerEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/IDockerEndpointAuthenticationProvider.cs
new file mode 100644
index 000000000..44856c593
--- /dev/null
+++ b/src/Testcontainers/Builders/IDockerEndpointAuthenticationProvider.cs
@@ -0,0 +1,27 @@
+namespace DotNet.Testcontainers.Builders
+{
+ using DotNet.Testcontainers.Configurations;
+ using JetBrains.Annotations;
+
+ ///
+ /// A Docker endpoint authentication provider.
+ ///
+ [PublicAPI]
+ internal interface IDockerEndpointAuthenticationProvider
+ {
+ ///
+ /// Is true when the authentication provider contains any Docker endpoint credentials, otherwise false.
+ ///
+ /// True when the authentication provider contains any Docker endpoint credentials, otherwise false.
+ [PublicAPI]
+ bool IsApplicable();
+
+ ///
+ /// Gets the Docker endpoint authentication configuration.
+ ///
+ /// The Docker endpoint authentication configuration or null if no configuration matches the hostname.
+ [PublicAPI]
+ [CanBeNull]
+ IDockerEndpointAuthenticationConfiguration GetAuthConfig();
+ }
+}
diff --git a/src/Testcontainers/Builders/IDockerRegistryAuthenticationProvider.cs b/src/Testcontainers/Builders/IDockerRegistryAuthenticationProvider.cs
new file mode 100644
index 000000000..119869de5
--- /dev/null
+++ b/src/Testcontainers/Builders/IDockerRegistryAuthenticationProvider.cs
@@ -0,0 +1,29 @@
+namespace DotNet.Testcontainers.Builders
+{
+ using DotNet.Testcontainers.Configurations;
+ using JetBrains.Annotations;
+
+ ///
+ /// A Docker registry authentication provider.
+ ///
+ [PublicAPI]
+ internal interface IDockerRegistryAuthenticationProvider
+ {
+ ///
+ /// Is true when the authentication provider contains any Docker registry credentials, otherwise false.
+ ///
+ /// The Docker hostname.
+ /// True when the authentication provider contains any Docker registry credentials, otherwise false.
+ [PublicAPI]
+ bool IsApplicable(string hostname);
+
+ ///
+ /// Gets the Docker registry authentication configuration.
+ ///
+ /// The Docker hostname.
+ /// The Docker registry authentication configuration or null if no configuration matches the hostname.
+ [PublicAPI]
+ [CanBeNull]
+ IDockerRegistryAuthenticationConfiguration GetAuthConfig(string hostname);
+ }
+}
diff --git a/src/Testcontainers/Builders/ITestcontainersBuilder.cs b/src/Testcontainers/Builders/ITestcontainersBuilder.cs
index 81c6b5fe2..626cdc660 100644
--- a/src/Testcontainers/Builders/ITestcontainersBuilder.cs
+++ b/src/Testcontainers/Builders/ITestcontainersBuilder.cs
@@ -274,7 +274,7 @@ public interface ITestcontainersBuilder : IAbstractBuilder
/// Password to authenticate.
/// A configured instance of .
[PublicAPI]
- [Obsolete("Be aware we will replace this method in the future. Instead, we will use the local Docker credential store. Then, no additional configurations are necessary.")]
+ [Obsolete("Use the local Docker credential store.")]
ITestcontainersBuilder WithRegistryAuthentication(string registryEndpoint, string username, string password);
///
diff --git a/src/Testcontainers/Builders/NpipeEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/NpipeEndpointAuthenticationProvider.cs
index 3a9fb23d3..0c04ba523 100644
--- a/src/Testcontainers/Builders/NpipeEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/NpipeEndpointAuthenticationProvider.cs
@@ -4,7 +4,7 @@
using System.Runtime.InteropServices;
using DotNet.Testcontainers.Configurations;
- ///
+ ///
internal sealed class NpipeEndpointAuthenticationProvider : IDockerEndpointAuthenticationProvider
{
#pragma warning disable S1075
diff --git a/src/Testcontainers/Builders/TestcontainersBuilder.cs b/src/Testcontainers/Builders/TestcontainersBuilder.cs
index 91a7b0329..6bdf0d5e6 100644
--- a/src/Testcontainers/Builders/TestcontainersBuilder.cs
+++ b/src/Testcontainers/Builders/TestcontainersBuilder.cs
@@ -19,7 +19,7 @@ namespace DotNet.Testcontainers.Builders
///
///
///
- /// var builder = new builder<TestcontainersContainer>()
+ /// var builder = new TestcontainersBuilder<TestcontainersContainer>()
/// .WithName("nginx")
/// .WithImage("nginx")
/// .WithEntrypoint("...")
@@ -52,7 +52,7 @@ public TestcontainersBuilder()
labels: DefaultLabels.Instance,
outputConsumer: Consume.DoNotConsumeStdoutAndStderr(),
waitStrategies: Wait.ForUnixContainer().Build(),
- startupCallback: (testcontainers, ct) => Task.CompletedTask,
+ startupCallback: (_, ct) => Task.CompletedTask,
autoRemove: false,
privileged: false),
_ => { })
diff --git a/src/Testcontainers/Builders/UnixEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/UnixEndpointAuthenticationProvider.cs
index 4aee083c1..55b84aa52 100644
--- a/src/Testcontainers/Builders/UnixEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/UnixEndpointAuthenticationProvider.cs
@@ -4,7 +4,7 @@
using System.Runtime.InteropServices;
using DotNet.Testcontainers.Configurations;
- ///
+ ///
internal sealed class UnixEndpointAuthenticationProvider : IDockerEndpointAuthenticationProvider
{
private static readonly Uri DockerEngine = new Uri("unix:/var/run/docker.sock");
diff --git a/src/Testcontainers/Configurations/Images/DockerRegistryAuthenticationConfiguration.cs b/src/Testcontainers/Configurations/Images/DockerRegistryAuthenticationConfiguration.cs
index 2d71c6cda..71da468c4 100644
--- a/src/Testcontainers/Configurations/Images/DockerRegistryAuthenticationConfiguration.cs
+++ b/src/Testcontainers/Configurations/Images/DockerRegistryAuthenticationConfiguration.cs
@@ -1,9 +1,6 @@
namespace DotNet.Testcontainers.Configurations
{
///
- ///
- /// In the future, we will replace this class. Instead, we will use the local Docker credentials.
- ///
internal readonly struct DockerRegistryAuthenticationConfiguration : IDockerRegistryAuthenticationConfiguration
{
///
@@ -12,6 +9,7 @@ namespace DotNet.Testcontainers.Configurations
/// The Docker registry endpoint.
/// The username.
/// The password.
+ /// The identity token.
public DockerRegistryAuthenticationConfiguration(
string registryEndpoint = null,
string username = null,
diff --git a/src/Testcontainers/Logging.cs b/src/Testcontainers/Logging.cs
index d5f58aab9..3f3258b28 100644
--- a/src/Testcontainers/Logging.cs
+++ b/src/Testcontainers/Logging.cs
@@ -66,10 +66,10 @@ private static readonly Action _CanNotGetResourceReape
= LoggerMessage.Define(LogLevel.Debug, default, "Can not get resource reaper {Id} endpoint");
private static readonly Action _CanNotConnectToResourceReaper
- = LoggerMessage.Define(LogLevel.Error, default, "Can not connect to resource reaper {Id} at {Endpoint}");
+ = LoggerMessage.Define(LogLevel.Debug, default, "Can not connect to resource reaper {Id} at {Endpoint}");
private static readonly Action _LostConnectionToResourceReaper
- = LoggerMessage.Define(LogLevel.Error, default, "Lost connection to resource reaper {Id} at {Endpoint}");
+ = LoggerMessage.Define(LogLevel.Debug, default, "Lost connection to resource reaper {Id} at {Endpoint}");
private static readonly Action _DockerConfigFileNotFound
= LoggerMessage.Define(LogLevel.Information, default, "Docker config {DockerConfigFilePath} not found");
@@ -176,13 +176,13 @@ public static void CanNotGetResourceReaperEndpoint(this ILogger logger, Guid id,
public static void CanNotConnectToResourceReaper(this ILogger logger, Guid id, string host, ushort port, Exception e)
{
var endpoint = $"{host}:{port}";
- _CanNotConnectToResourceReaper(logger, id, endpoint, logger.IsEnabled(LogLevel.Debug) ? e : null);
+ _CanNotConnectToResourceReaper(logger, id, endpoint, e);
}
public static void LostConnectionToResourceReaper(this ILogger logger, Guid id, string host, ushort port, Exception e)
{
var endpoint = $"{host}:{port}";
- _LostConnectionToResourceReaper(logger, id, endpoint, logger.IsEnabled(LogLevel.Debug) ? e : null);
+ _LostConnectionToResourceReaper(logger, id, endpoint, e);
}
public static void DockerConfigFileNotFound(this ILogger logger, string dockerConfigFilePath)
diff --git a/tests/Testcontainers.Tests/Assets/.dockerignore b/tests/Testcontainers.Tests/Assets/.dockerignore
index 964a69458..4c9a422f7 100644
--- a/tests/Testcontainers.Tests/Assets/.dockerignore
+++ b/tests/Testcontainers.Tests/Assets/.dockerignore
@@ -1,2 +1,2 @@
-**/*.md
credHelpers
+**/*.md
diff --git a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat
similarity index 77%
rename from tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat
rename to tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat
index c0b760452..c0c9098a4 100644
--- a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat
+++ b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.bat
@@ -1,2 +1,3 @@
@echo off
+set /P hostname=
echo {"Username":"username","Secret":"password"}
diff --git a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh
similarity index 92%
rename from tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh
rename to tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh
index d31ed7343..a48231371 100755
--- a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh
+++ b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-password.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-
+read
echo '{"Username":"username","Secret":"password"}'
diff --git a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat
similarity index 78%
rename from tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat
rename to tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat
index f78dfea62..2ca98397c 100644
--- a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat
+++ b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.bat
@@ -1,2 +1,3 @@
@echo off
+set /P hostname=
echo {"Username":"","Secret":"identitytoken"}
diff --git a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh
similarity index 93%
rename from tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh
rename to tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh
index ee361914d..3313d9743 100755
--- a/tests/DotNet.Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh
+++ b/tests/Testcontainers.Tests/Assets/credHelpers/docker-credential-token.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-
+read
echo '{"Username":"","Secret":"identitytoken"}'
diff --git a/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs b/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
index 075b26381..1278bdd3c 100644
--- a/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
@@ -2,6 +2,7 @@
{
using System;
using System.IO;
+ using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Json;
using DotNet.Testcontainers.Builders;
@@ -62,8 +63,9 @@ public sealed class Base64ProviderTest
{
[Theory]
[InlineData("{}", false)]
+ [InlineData("{\"auths\":null}", false)]
[InlineData("{\"auths\":{}}", false)]
- [InlineData("{\"auths\":{\"ghcr.io\":{}}}", true)]
+ [InlineData("{\"auths\":{\"ghcr.io\":{}}}", false)]
[InlineData("{\"auths\":{\"" + DockerRegistry + "\":{}}}", true)]
[InlineData("{\"auths\":{\"" + DockerRegistry + "\":{\"auth\":null}}}", true)]
[InlineData("{\"auths\":{\"" + DockerRegistry + "\":{\"auth\":\"\"}}}", true)]
@@ -125,6 +127,7 @@ public void ShouldGetNull(string jsonDocument, bool isApplicable)
#pragma warning disable xUnit1004
[Fact(Skip = "The pipeline has no configured credential store (maybe we can use the Windows tests in the future).")]
+
#pragma warning restore xUnit1004
public void ShouldGetAuthConfig()
{
@@ -147,11 +150,23 @@ public void ShouldGetAuthConfig()
public sealed class CredsHelperProviderTest
{
+ static CredsHelperProviderTest()
+ {
+ Environment.SetEnvironmentVariable("PATH", string.Join(Path.PathSeparator, (Environment.GetEnvironmentVariable("PATH") ?? string.Empty)
+ .Split(Path.PathSeparator)
+ .Prepend(Path.Combine(Directory.GetCurrentDirectory(), "Assets", "credHelpers"))
+ .Distinct()));
+ }
+
[Theory]
[InlineData("{}", false)]
[InlineData("{\"credHelpers\":null}", false)]
- [InlineData("{\"credHelpers\":{\"" + DockerRegistry + "\":null}}", false)]
- [InlineData("{\"credHelpers\":{\"registry2\":\"script.bat\"}}", false)]
+ [InlineData("{\"credHelpers\":{}}", false)]
+ [InlineData("{\"credHelpers\":{\"ghcr.io\":{}}}", false)]
+ [InlineData("{\"credHelpers\":{\"" + DockerRegistry + "\":{}}}", true)]
+ [InlineData("{\"credHelpers\":{\"" + DockerRegistry + "\":null}}", true)]
+ [InlineData("{\"credHelpers\":{\"" + DockerRegistry + "\":\"\"}}", true)]
+ [InlineData("{\"credHelpers\":{\"" + DockerRegistry + "\":\"script.sh\"}}", true)]
public void ShouldGetNull(string jsonDocument, bool isApplicable)
{
// Given
@@ -171,15 +186,9 @@ public void ShouldGetNull(string jsonDocument, bool isApplicable)
[InlineData("token", null, null, "identitytoken")]
public void ShouldGetAuthConfig(string credHelperName, string expectedUsername, string expectedPassword, string expectedIdentityToken)
{
- var path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
- var pathSeparator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ";" : ":";
- var credHelpersPath = Path.Combine(Environment.CurrentDirectory, "Assets", "credHelpers");
- Environment.SetEnvironmentVariable("PATH", string.Join(pathSeparator, credHelpersPath, path));
- var extension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".bat" : ".sh";
- var credHelperScriptSuffix = $"{credHelperName}{extension}";
-
// Given
- var jsonDocument = "{\"credHelpers\":{\"" + DockerRegistry + "\":\"" + credHelperScriptSuffix + "\"}}";
+ var credHelpersScriptName = Path.ChangeExtension(credHelperName, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "bat" : "sh");
+ var jsonDocument = "{\"credHelpers\":{\"" + DockerRegistry + "\":\"" + credHelpersScriptName + "\"}}";
var jsonElement = JsonDocument.Parse(jsonDocument).RootElement;
// When