Skip to content

Commit

Permalink
chore: Ensure that stderr is empty after executing scripts (#1116)
Browse files Browse the repository at this point in the history
Co-authored-by: Andre Hofmeister <[email protected]>
  • Loading branch information
0xced and HofmeisterAn authored Mar 14, 2024
1 parent 36758c8 commit 9156593
Show file tree
Hide file tree
Showing 21 changed files with 84 additions and 59 deletions.
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);
}
}

0 comments on commit 9156593

Please sign in to comment.