diff --git a/src/Testcontainers.MariaDb/MariaDbBuilder.cs b/src/Testcontainers.MariaDb/MariaDbBuilder.cs
index cbc7c6da7..98c067bc2 100644
--- a/src/Testcontainers.MariaDb/MariaDbBuilder.cs
+++ b/src/Testcontainers.MariaDb/MariaDbBuilder.cs
@@ -89,7 +89,8 @@ protected override MariaDbBuilder Init()
.WithPortBinding(MariaDbPort, true)
.WithDatabase(DefaultDatabase)
.WithUsername(DefaultUsername)
- .WithPassword(DefaultPassword);
+ .WithPassword(DefaultPassword)
+ .WithStartupCallback((container, ct) => container.WriteConfigurationFileAsync(ct));
}
///
@@ -135,7 +136,7 @@ private sealed class WaitUntil : IWaitUntil
/// The container configuration.
public WaitUntil(MariaDbConfiguration configuration)
{
- _command = new List { "mariadb", "--protocol=TCP", $"--port={MariaDbPort}", $"--user={configuration.Username}", $"--password={configuration.Password}", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
+ _command = new List { "mariadb", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
}
///
diff --git a/src/Testcontainers.MariaDb/MariaDbContainer.cs b/src/Testcontainers.MariaDb/MariaDbContainer.cs
index fd3845fa3..a1bb69eb4 100644
--- a/src/Testcontainers.MariaDb/MariaDbContainer.cs
+++ b/src/Testcontainers.MariaDb/MariaDbContainer.cs
@@ -44,7 +44,25 @@ public async Task ExecScriptAsync(string scriptContent, Cancellation
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
.ConfigureAwait(false);
- return await ExecAsync(new[] { "mariadb", "--protocol=TCP", $"--port={MariaDbBuilder.MariaDbPort}", $"--user={_configuration.Username}", $"--password={_configuration.Password}", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
+ return await ExecAsync(new[] { "mariadb", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
.ConfigureAwait(false);
}
+
+ ///
+ /// Write an unobfuscated MariaDb configuration file that configures the client
+ /// login path. This prevents warnings in the
+ /// result about using a password on the command line.
+ ///
+ /// Cancellation token.
+ /// Task that completes when the configuration file has been executed.
+ internal Task WriteConfigurationFileAsync(CancellationToken ct = default)
+ {
+ var config = new StringWriter();
+ config.NewLine = "\n";
+ config.WriteLine("[client]");
+ config.WriteLine("protocol=TCP");
+ config.WriteLine($"user={_configuration.Username}");
+ config.WriteLine($"password={_configuration.Password}");
+ return CopyAsync(Encoding.Default.GetBytes(config.ToString()), "/etc/mysql/my.cnf", UnixFileModes.UserRead | UnixFileModes.UserWrite, ct);
+ }
}
\ No newline at end of file
diff --git a/src/Testcontainers.MongoDb/MongoDbContainer.cs b/src/Testcontainers.MongoDb/MongoDbContainer.cs
index b5eb44752..f3c4f5e35 100644
--- a/src/Testcontainers.MongoDb/MongoDbContainer.cs
+++ b/src/Testcontainers.MongoDb/MongoDbContainer.cs
@@ -42,7 +42,20 @@ public async Task ExecScriptAsync(string scriptContent, Cancellation
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
.ConfigureAwait(false);
- return await ExecAsync(new MongoDbShellCommand($"load('{scriptFilePath}')", _configuration.Username, _configuration.Password), ct)
+ var whichMongoDbShell = await ExecAsync(new[] { "which", "mongosh" }, ct)
+ .ConfigureAwait(false);
+
+ var command = new[]
+ {
+ whichMongoDbShell.ExitCode == 0 ? "mongosh" : "mongo",
+ "--username", _configuration.Username,
+ "--password", _configuration.Password,
+ "--quiet",
+ "--eval",
+ $"load('{scriptFilePath}')",
+ };
+
+ return await ExecAsync(command, ct)
.ConfigureAwait(false);
}
}
\ No newline at end of file
diff --git a/src/Testcontainers.MongoDb/MongoDbShellCommand.cs b/src/Testcontainers.MongoDb/MongoDbShellCommand.cs
deleted file mode 100644
index 7c288c983..000000000
--- a/src/Testcontainers.MongoDb/MongoDbShellCommand.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Testcontainers.MongoDb;
-
-///
-/// A MongoDb shell command that evaluates a JavaScript expression.
-///
-internal sealed class MongoDbShellCommand : List
-{
- private const string Format = "{0} --username '{1}' --password '{2}' --quiet --eval '{3}'";
-
- private const string Sanitize = "'\"'\"'";
-
- private readonly StringBuilder _mongoDbShellCommand = new StringBuilder();
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The legacy mongo shell was deprecated in MongoDb 5.0 and removed in MongoDb 6.0:
- /// https://www.mongodb.com/docs/mongodb-shell/#the-mdb-shell-versus-the-legacy-mongo-shell.
- ///
- /// The JavaScript expression.
- /// The MongoDb username.
- /// The MongoDb password.
- public MongoDbShellCommand(string js, string username, string password)
- {
- var sanitizedJs = js.Replace("'", Sanitize);
- var sanitizedUsername = username.Replace("'", Sanitize);
- var sanitizedPassword = password.Replace("'", Sanitize);
- _mongoDbShellCommand.AppendFormat(Format, "mongosh", sanitizedUsername, sanitizedPassword, sanitizedJs);
- _mongoDbShellCommand.Append(" || ");
- _mongoDbShellCommand.AppendFormat(Format, "mongo", sanitizedUsername, sanitizedPassword, sanitizedJs);
- Add("/bin/sh");
- Add("-c");
- Add(_mongoDbShellCommand.ToString());
- }
-}
\ No newline at end of file
diff --git a/src/Testcontainers.MongoDb/Usings.cs b/src/Testcontainers.MongoDb/Usings.cs
index e2b02a51e..16243387a 100644
--- a/src/Testcontainers.MongoDb/Usings.cs
+++ b/src/Testcontainers.MongoDb/Usings.cs
@@ -1,5 +1,4 @@
global using System;
-global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Text;
diff --git a/src/Testcontainers.MySql/MySqlBuilder.cs b/src/Testcontainers.MySql/MySqlBuilder.cs
index ac756ec73..4ed177c30 100644
--- a/src/Testcontainers.MySql/MySqlBuilder.cs
+++ b/src/Testcontainers.MySql/MySqlBuilder.cs
@@ -89,7 +89,8 @@ protected override MySqlBuilder Init()
.WithPortBinding(MySqlPort, true)
.WithDatabase(DefaultDatabase)
.WithUsername(DefaultUsername)
- .WithPassword(DefaultPassword);
+ .WithPassword(DefaultPassword)
+ .WithStartupCallback((container, ct) => container.WriteConfigurationFileAsync(ct));
}
///
@@ -135,7 +136,7 @@ private sealed class WaitUntil : IWaitUntil
/// The container configuration.
public WaitUntil(MySqlConfiguration configuration)
{
- _command = new List { "mysql", "--protocol=TCP", $"--port={MySqlPort}", $"--user={configuration.Username}", $"--password={configuration.Password}", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
+ _command = new List { "mysql", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
}
///
diff --git a/src/Testcontainers.MySql/MySqlContainer.cs b/src/Testcontainers.MySql/MySqlContainer.cs
index 001b1fef6..d18ffa3db 100644
--- a/src/Testcontainers.MySql/MySqlContainer.cs
+++ b/src/Testcontainers.MySql/MySqlContainer.cs
@@ -44,7 +44,25 @@ public async Task ExecScriptAsync(string scriptContent, Cancellation
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
.ConfigureAwait(false);
- return await ExecAsync(new[] { "mysql", "--protocol=TCP", $"--port={MySqlBuilder.MySqlPort}", $"--user={_configuration.Username}", $"--password={_configuration.Password}", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
+ return await ExecAsync(new[] { "mysql", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
.ConfigureAwait(false);
}
+
+ ///
+ /// Write an unobfuscated MySql configuration file that configures the client
+ /// login path. This prevents warnings in the
+ /// result about using a password on the command line.
+ ///
+ /// Cancellation token.
+ /// Task that completes when the configuration file has been executed.
+ internal Task WriteConfigurationFileAsync(CancellationToken ct = default)
+ {
+ var config = new StringWriter();
+ config.NewLine = "\n";
+ config.WriteLine("[client]");
+ config.WriteLine("protocol=TCP");
+ config.WriteLine($"user={_configuration.Username}");
+ config.WriteLine($"password={_configuration.Password}");
+ return CopyAsync(Encoding.Default.GetBytes(config.ToString()), "/etc/mysql/my.cnf", UnixFileModes.UserRead | UnixFileModes.UserWrite, ct);
+ }
}
\ No newline at end of file
diff --git a/src/Testcontainers/Builders/ContainerBuilder`3.cs b/src/Testcontainers/Builders/ContainerBuilder`3.cs
index 9fed8de2d..a41a049b2 100644
--- a/src/Testcontainers/Builders/ContainerBuilder`3.cs
+++ b/src/Testcontainers/Builders/ContainerBuilder`3.cs
@@ -366,9 +366,9 @@ public TBuilderEntity WithWaitStrategy(IWaitForContainerOS waitStrategy)
}
///
- public TBuilderEntity WithStartupCallback(Func startupCallback)
+ public TBuilderEntity WithStartupCallback(Func startupCallback)
{
- return Clone(new ContainerConfiguration(startupCallback: startupCallback));
+ return Clone(new ContainerConfiguration(startupCallback: (container, ct) => startupCallback((TContainerEntity)container, ct)));
}
///
diff --git a/src/Testcontainers/Builders/IContainerBuilder`2.cs b/src/Testcontainers/Builders/IContainerBuilder`2.cs
index 6fade9c82..1475881f8 100644
--- a/src/Testcontainers/Builders/IContainerBuilder`2.cs
+++ b/src/Testcontainers/Builders/IContainerBuilder`2.cs
@@ -452,6 +452,6 @@ public interface IContainerBuilder : I
/// The callback method to invoke.
/// A configured instance of .
[PublicAPI]
- TBuilderEntity WithStartupCallback(Func startupCallback);
+ TBuilderEntity WithStartupCallback(Func startupCallback);
}
}
diff --git a/src/Testcontainers/Clients/DockerApiClient.cs b/src/Testcontainers/Clients/DockerApiClient.cs
index cf8f1d91a..826b18b58 100644
--- a/src/Testcontainers/Clients/DockerApiClient.cs
+++ b/src/Testcontainers/Clients/DockerApiClient.cs
@@ -113,7 +113,7 @@ await RuntimeInitialized.WaitAsync(ct)
}
catch(Exception e)
{
- Logger.LogError(e, "Failed to retrieve Docker container runtime information.");
+ Logger.LogError(e, "Failed to retrieve Docker container runtime information");
}
finally
{
diff --git a/src/Testcontainers/Containers/ResourceReaperState.cs b/src/Testcontainers/Containers/ResourceReaperState.cs
index f3ee7398a..c9503e850 100644
--- a/src/Testcontainers/Containers/ResourceReaperState.cs
+++ b/src/Testcontainers/Containers/ResourceReaperState.cs
@@ -4,6 +4,7 @@ namespace DotNet.Testcontainers.Containers
using System.Threading;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Images;
+ using Microsoft.Extensions.Logging;
///
/// Resource Reaper states.
@@ -24,7 +25,7 @@ public enum ResourceReaperState
/// maintains the TCP connection to Ryuk.
///
///
- /// will complete now.
+ /// will complete now.
///
MaintainingConnection,
diff --git a/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs b/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs
index fde12cad5..7d423065b 100644
--- a/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs
+++ b/tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _clickHouseContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
}
\ No newline at end of file
diff --git a/tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs b/tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs
index 14ce462a4..9c3f37566 100644
--- a/tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs
+++ b/tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _cockroachDbContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
}
\ No newline at end of file
diff --git a/tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs b/tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs
index e6cf980f9..220b90619 100644
--- a/tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs
+++ b/tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs
@@ -44,7 +44,7 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _firebirdSqlContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
Assert.Empty(execResult.Stderr);
}
diff --git a/tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs b/tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs
index 3dd575f11..acd8480c5 100644
--- a/tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs
+++ b/tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _mariaDbContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
[UsedImplicitly]
diff --git a/tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs b/tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs
index 9c96aae1f..732ab150f 100644
--- a/tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs
+++ b/tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _mongoDbContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
[UsedImplicitly]
diff --git a/tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs b/tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs
index 19c3c81e4..f7d18102f 100644
--- a/tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs
+++ b/tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _msSqlContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
}
\ No newline at end of file
diff --git a/tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs b/tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
index ea8b958c6..11a8e71a9 100644
--- a/tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
+++ b/tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _mySqlContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
[UsedImplicitly]
diff --git a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
index 08e7755f9..5b6984dd0 100644
--- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
+++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _oracleContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
}
\ No newline at end of file
diff --git a/tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs b/tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs
index 6c0259839..a92461dbd 100644
--- a/tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs
+++ b/tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs
@@ -39,8 +39,9 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _postgreSqlContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
+ Assert.Empty(execResult.Stderr);
}
public sealed class ReuseContainerTest : IClassFixture, IDisposable
diff --git a/tests/Testcontainers.Redis.Tests/RedisContainerTest.cs b/tests/Testcontainers.Redis.Tests/RedisContainerTest.cs
index 937dd769d..15d311e44 100644
--- a/tests/Testcontainers.Redis.Tests/RedisContainerTest.cs
+++ b/tests/Testcontainers.Redis.Tests/RedisContainerTest.cs
@@ -33,7 +33,9 @@ public async Task ExecScriptReturnsSuccessful()
var execResult = await _redisContainer.ExecScriptAsync(scriptContent)
.ConfigureAwait(true);
- // When
+ // Then
+ Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
Assert.True("Hello, scripting!\n".Equals(execResult.Stdout), execResult.Stdout);
+ Assert.Empty(execResult.Stderr);
}
}
\ No newline at end of file