Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Ensure that stderr is empty after executing scripts #1116

Merged
5 changes: 3 additions & 2 deletions src/Testcontainers.MariaDb/MariaDbBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

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

/// <inheritdoc />
Expand Down
20 changes: 19 additions & 1 deletion src/Testcontainers.MariaDb/MariaDbContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,25 @@ public async Task<ExecResult> 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);
}

/// <summary>
/// Write an unobfuscated MariaDb configuration file that configures the client
/// login path. This prevents warnings in the <see cref="ExecScriptAsync" />
/// result about using a password on the command line.
/// </summary>
/// <param name="ct">Cancellation token.</param>
/// <returns>Task that completes when the configuration file has been executed.</returns>
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);
}
}
15 changes: 14 additions & 1 deletion src/Testcontainers.MongoDb/MongoDbContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,20 @@ public async Task<ExecResult> 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);
}
}
36 changes: 0 additions & 36 deletions src/Testcontainers.MongoDb/MongoDbShellCommand.cs

This file was deleted.

1 change: 0 additions & 1 deletion src/Testcontainers.MongoDb/Usings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Text;
Expand Down
5 changes: 3 additions & 2 deletions src/Testcontainers.MySql/MySqlBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

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

/// <inheritdoc />
Expand Down
20 changes: 19 additions & 1 deletion src/Testcontainers.MySql/MySqlContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,25 @@ public async Task<ExecResult> 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);
}

/// <summary>
/// Write an unobfuscated MySql configuration file that configures the client
/// login path. This prevents warnings in the <see cref="ExecScriptAsync" />
/// result about using a password on the command line.
/// </summary>
/// <param name="ct">Cancellation token.</param>
/// <returns>Task that completes when the configuration file has been executed.</returns>
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);
}
}
4 changes: 2 additions & 2 deletions src/Testcontainers/Builders/ContainerBuilder`3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,9 @@ public TBuilderEntity WithWaitStrategy(IWaitForContainerOS waitStrategy)
}

/// <inheritdoc />
public TBuilderEntity WithStartupCallback(Func<IContainer, CancellationToken, Task> startupCallback)
public TBuilderEntity WithStartupCallback(Func<TContainerEntity, CancellationToken, Task> startupCallback)
{
return Clone(new ContainerConfiguration(startupCallback: startupCallback));
return Clone(new ContainerConfiguration(startupCallback: (container, ct) => startupCallback((TContainerEntity)container, ct)));
}

/// <inheritdoc />
Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers/Builders/IContainerBuilder`2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,6 @@ public interface IContainerBuilder<out TBuilderEntity, out TContainerEntity> : I
/// <param name="startupCallback">The callback method to invoke.</param>
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
[PublicAPI]
TBuilderEntity WithStartupCallback(Func<IContainer, CancellationToken, Task> startupCallback);
TBuilderEntity WithStartupCallback(Func<TContainerEntity, CancellationToken, Task> startupCallback);
}
}
2 changes: 1 addition & 1 deletion src/Testcontainers/Clients/DockerApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
3 changes: 2 additions & 1 deletion src/Testcontainers/Containers/ResourceReaperState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace DotNet.Testcontainers.Containers
using System.Threading;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Images;
using Microsoft.Extensions.Logging;

/// <summary>
/// Resource Reaper states.
Expand All @@ -24,7 +25,7 @@ public enum ResourceReaperState
/// <see cref="ResourceReaper" /> maintains the TCP connection to Ryuk.
/// </summary>
/// <remarks>
/// <see cref="ResourceReaper.GetAndStartNewAsync(IDockerEndpointAuthenticationConfiguration, IImage, IMount, bool, TimeSpan, CancellationToken)" /> will complete now.
/// <see cref="ResourceReaper.GetAndStartNewAsync(IDockerEndpointAuthenticationConfiguration, IImage, IMount, ILogger, bool, TimeSpan, CancellationToken)" /> will complete now.
/// </remarks>
MaintainingConnection,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
3 changes: 2 additions & 1 deletion tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion tests/Testcontainers.MongoDb.Tests/MongoDbContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
3 changes: 2 additions & 1 deletion tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<SharedPostgreSqlInstance>, IDisposable
Expand Down
4 changes: 3 additions & 1 deletion tests/Testcontainers.Redis.Tests/RedisContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Loading