Skip to content

Commit 9156593

Browse files
0xcedHofmeisterAn
andauthored
chore: Ensure that stderr is empty after executing scripts (#1116)
Co-authored-by: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com>
1 parent 36758c8 commit 9156593

File tree

21 files changed

+84
-59
lines changed

21 files changed

+84
-59
lines changed

src/Testcontainers.MariaDb/MariaDbBuilder.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ protected override MariaDbBuilder Init()
8989
.WithPortBinding(MariaDbPort, true)
9090
.WithDatabase(DefaultDatabase)
9191
.WithUsername(DefaultUsername)
92-
.WithPassword(DefaultPassword);
92+
.WithPassword(DefaultPassword)
93+
.WithStartupCallback((container, ct) => container.WriteConfigurationFileAsync(ct));
9394
}
9495

9596
/// <inheritdoc />
@@ -135,7 +136,7 @@ private sealed class WaitUntil : IWaitUntil
135136
/// <param name="configuration">The container configuration.</param>
136137
public WaitUntil(MariaDbConfiguration configuration)
137138
{
138-
_command = new List<string> { "mariadb", "--protocol=TCP", $"--port={MariaDbPort}", $"--user={configuration.Username}", $"--password={configuration.Password}", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
139+
_command = new List<string> { "mariadb", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
139140
}
140141

141142
/// <inheritdoc />

src/Testcontainers.MariaDb/MariaDbContainer.cs

+19-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,25 @@ public async Task<ExecResult> ExecScriptAsync(string scriptContent, Cancellation
4444
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
4545
.ConfigureAwait(false);
4646

47-
return await ExecAsync(new[] { "mariadb", "--protocol=TCP", $"--port={MariaDbBuilder.MariaDbPort}", $"--user={_configuration.Username}", $"--password={_configuration.Password}", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
47+
return await ExecAsync(new[] { "mariadb", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
4848
.ConfigureAwait(false);
4949
}
50+
51+
/// <summary>
52+
/// Write an unobfuscated MariaDb configuration file that configures the client
53+
/// login path. This prevents warnings in the <see cref="ExecScriptAsync" />
54+
/// result about using a password on the command line.
55+
/// </summary>
56+
/// <param name="ct">Cancellation token.</param>
57+
/// <returns>Task that completes when the configuration file has been executed.</returns>
58+
internal Task WriteConfigurationFileAsync(CancellationToken ct = default)
59+
{
60+
var config = new StringWriter();
61+
config.NewLine = "\n";
62+
config.WriteLine("[client]");
63+
config.WriteLine("protocol=TCP");
64+
config.WriteLine($"user={_configuration.Username}");
65+
config.WriteLine($"password={_configuration.Password}");
66+
return CopyAsync(Encoding.Default.GetBytes(config.ToString()), "/etc/mysql/my.cnf", UnixFileModes.UserRead | UnixFileModes.UserWrite, ct);
67+
}
5068
}

src/Testcontainers.MongoDb/MongoDbContainer.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,20 @@ public async Task<ExecResult> ExecScriptAsync(string scriptContent, Cancellation
4242
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
4343
.ConfigureAwait(false);
4444

45-
return await ExecAsync(new MongoDbShellCommand($"load('{scriptFilePath}')", _configuration.Username, _configuration.Password), ct)
45+
var whichMongoDbShell = await ExecAsync(new[] { "which", "mongosh" }, ct)
46+
.ConfigureAwait(false);
47+
48+
var command = new[]
49+
{
50+
whichMongoDbShell.ExitCode == 0 ? "mongosh" : "mongo",
51+
"--username", _configuration.Username,
52+
"--password", _configuration.Password,
53+
"--quiet",
54+
"--eval",
55+
$"load('{scriptFilePath}')",
56+
};
57+
58+
return await ExecAsync(command, ct)
4659
.ConfigureAwait(false);
4760
}
4861
}

src/Testcontainers.MongoDb/MongoDbShellCommand.cs

-36
This file was deleted.

src/Testcontainers.MongoDb/Usings.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
global using System;
2-
global using System.Collections.Generic;
32
global using System.IO;
43
global using System.Linq;
54
global using System.Text;

src/Testcontainers.MySql/MySqlBuilder.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ protected override MySqlBuilder Init()
8989
.WithPortBinding(MySqlPort, true)
9090
.WithDatabase(DefaultDatabase)
9191
.WithUsername(DefaultUsername)
92-
.WithPassword(DefaultPassword);
92+
.WithPassword(DefaultPassword)
93+
.WithStartupCallback((container, ct) => container.WriteConfigurationFileAsync(ct));
9394
}
9495

9596
/// <inheritdoc />
@@ -135,7 +136,7 @@ private sealed class WaitUntil : IWaitUntil
135136
/// <param name="configuration">The container configuration.</param>
136137
public WaitUntil(MySqlConfiguration configuration)
137138
{
138-
_command = new List<string> { "mysql", "--protocol=TCP", $"--port={MySqlPort}", $"--user={configuration.Username}", $"--password={configuration.Password}", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
139+
_command = new List<string> { "mysql", configuration.Database, "--wait", "--silent", "--execute=SELECT 1;" };
139140
}
140141

141142
/// <inheritdoc />

src/Testcontainers.MySql/MySqlContainer.cs

+19-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,25 @@ public async Task<ExecResult> ExecScriptAsync(string scriptContent, Cancellation
4444
await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
4545
.ConfigureAwait(false);
4646

47-
return await ExecAsync(new[] { "mysql", "--protocol=TCP", $"--port={MySqlBuilder.MySqlPort}", $"--user={_configuration.Username}", $"--password={_configuration.Password}", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
47+
return await ExecAsync(new[] { "mysql", _configuration.Database, $"--execute=source {scriptFilePath};" }, ct)
4848
.ConfigureAwait(false);
4949
}
50+
51+
/// <summary>
52+
/// Write an unobfuscated MySql configuration file that configures the client
53+
/// login path. This prevents warnings in the <see cref="ExecScriptAsync" />
54+
/// result about using a password on the command line.
55+
/// </summary>
56+
/// <param name="ct">Cancellation token.</param>
57+
/// <returns>Task that completes when the configuration file has been executed.</returns>
58+
internal Task WriteConfigurationFileAsync(CancellationToken ct = default)
59+
{
60+
var config = new StringWriter();
61+
config.NewLine = "\n";
62+
config.WriteLine("[client]");
63+
config.WriteLine("protocol=TCP");
64+
config.WriteLine($"user={_configuration.Username}");
65+
config.WriteLine($"password={_configuration.Password}");
66+
return CopyAsync(Encoding.Default.GetBytes(config.ToString()), "/etc/mysql/my.cnf", UnixFileModes.UserRead | UnixFileModes.UserWrite, ct);
67+
}
5068
}

src/Testcontainers/Builders/ContainerBuilder`3.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,9 @@ public TBuilderEntity WithWaitStrategy(IWaitForContainerOS waitStrategy)
366366
}
367367

368368
/// <inheritdoc />
369-
public TBuilderEntity WithStartupCallback(Func<IContainer, CancellationToken, Task> startupCallback)
369+
public TBuilderEntity WithStartupCallback(Func<TContainerEntity, CancellationToken, Task> startupCallback)
370370
{
371-
return Clone(new ContainerConfiguration(startupCallback: startupCallback));
371+
return Clone(new ContainerConfiguration(startupCallback: (container, ct) => startupCallback((TContainerEntity)container, ct)));
372372
}
373373

374374
/// <inheritdoc />

src/Testcontainers/Builders/IContainerBuilder`2.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,6 @@ public interface IContainerBuilder<out TBuilderEntity, out TContainerEntity> : I
452452
/// <param name="startupCallback">The callback method to invoke.</param>
453453
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
454454
[PublicAPI]
455-
TBuilderEntity WithStartupCallback(Func<IContainer, CancellationToken, Task> startupCallback);
455+
TBuilderEntity WithStartupCallback(Func<TContainerEntity, CancellationToken, Task> startupCallback);
456456
}
457457
}

src/Testcontainers/Clients/DockerApiClient.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ await RuntimeInitialized.WaitAsync(ct)
113113
}
114114
catch(Exception e)
115115
{
116-
Logger.LogError(e, "Failed to retrieve Docker container runtime information.");
116+
Logger.LogError(e, "Failed to retrieve Docker container runtime information");
117117
}
118118
finally
119119
{

src/Testcontainers/Containers/ResourceReaperState.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace DotNet.Testcontainers.Containers
44
using System.Threading;
55
using DotNet.Testcontainers.Configurations;
66
using DotNet.Testcontainers.Images;
7+
using Microsoft.Extensions.Logging;
78

89
/// <summary>
910
/// Resource Reaper states.
@@ -24,7 +25,7 @@ public enum ResourceReaperState
2425
/// <see cref="ResourceReaper" /> maintains the TCP connection to Ryuk.
2526
/// </summary>
2627
/// <remarks>
27-
/// <see cref="ResourceReaper.GetAndStartNewAsync(IDockerEndpointAuthenticationConfiguration, IImage, IMount, bool, TimeSpan, CancellationToken)" /> will complete now.
28+
/// <see cref="ResourceReaper.GetAndStartNewAsync(IDockerEndpointAuthenticationConfiguration, IImage, IMount, ILogger, bool, TimeSpan, CancellationToken)" /> will complete now.
2829
/// </remarks>
2930
MaintainingConnection,
3031

tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
3939
var execResult = await _clickHouseContainer.ExecScriptAsync(scriptContent)
4040
.ConfigureAwait(true);
4141

42-
// When
42+
// Then
4343
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
44+
Assert.Empty(execResult.Stderr);
4445
}
4546
}

tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
3939
var execResult = await _cockroachDbContainer.ExecScriptAsync(scriptContent)
4040
.ConfigureAwait(true);
4141

42-
// When
42+
// Then
4343
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
44+
Assert.Empty(execResult.Stderr);
4445
}
4546
}

tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public async Task ExecScriptReturnsSuccessful()
4444
var execResult = await _firebirdSqlContainer.ExecScriptAsync(scriptContent)
4545
.ConfigureAwait(true);
4646

47-
// When
47+
// Then
4848
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
4949
Assert.Empty(execResult.Stderr);
5050
}

tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
4444
var execResult = await _mariaDbContainer.ExecScriptAsync(scriptContent)
4545
.ConfigureAwait(true);
4646

47-
// When
47+
// Then
4848
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
49+
Assert.Empty(execResult.Stderr);
4950
}
5051

5152
[UsedImplicitly]

tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
4444
var execResult = await _mongoDbContainer.ExecScriptAsync(scriptContent)
4545
.ConfigureAwait(true);
4646

47-
// When
47+
// Then
4848
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
49+
Assert.Empty(execResult.Stderr);
4950
}
5051

5152
[UsedImplicitly]

tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
3939
var execResult = await _msSqlContainer.ExecScriptAsync(scriptContent)
4040
.ConfigureAwait(true);
4141

42-
// When
42+
// Then
4343
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
44+
Assert.Empty(execResult.Stderr);
4445
}
4546
}

tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public async Task ExecScriptReturnsSuccessful()
4444
var execResult = await _mySqlContainer.ExecScriptAsync(scriptContent)
4545
.ConfigureAwait(true);
4646

47-
// When
47+
// Then
4848
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
49+
Assert.Empty(execResult.Stderr);
4950
}
5051

5152
[UsedImplicitly]

tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public async Task ExecScriptReturnsSuccessful()
3939
var execResult = await _oracleContainer.ExecScriptAsync(scriptContent)
4040
.ConfigureAwait(true);
4141

42-
// When
42+
// Then
4343
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
44+
Assert.Empty(execResult.Stderr);
4445
}
4546
}

tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ public async Task ExecScriptReturnsSuccessful()
3939
var execResult = await _postgreSqlContainer.ExecScriptAsync(scriptContent)
4040
.ConfigureAwait(true);
4141

42-
// When
42+
// Then
4343
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
44+
Assert.Empty(execResult.Stderr);
4445
}
4546

4647
public sealed class ReuseContainerTest : IClassFixture<SharedPostgreSqlInstance>, IDisposable

tests/Testcontainers.Redis.Tests/RedisContainerTest.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ public async Task ExecScriptReturnsSuccessful()
3333
var execResult = await _redisContainer.ExecScriptAsync(scriptContent)
3434
.ConfigureAwait(true);
3535

36-
// When
36+
// Then
37+
Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr);
3738
Assert.True("Hello, scripting!\n".Equals(execResult.Stdout), execResult.Stdout);
39+
Assert.Empty(execResult.Stderr);
3840
}
3941
}

0 commit comments

Comments
 (0)