-
-
Notifications
You must be signed in to change notification settings - Fork 294
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Replace PostgreSQL module (#772)
- Loading branch information
1 parent
c9bc198
commit 07b5c8c
Showing
17 changed files
with
354 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
root = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
namespace Testcontainers.PostgreSql; | ||
|
||
/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" /> | ||
[PublicAPI] | ||
public sealed class PostgreSqlBuilder : ContainerBuilder<PostgreSqlBuilder, PostgreSqlContainer, PostgreSqlConfiguration> | ||
{ | ||
public const string PostgreSqlImage = "postgres:15.1"; | ||
|
||
public const ushort PostgreSqlPort = 5432; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlBuilder" /> class. | ||
/// </summary> | ||
public PostgreSqlBuilder() | ||
: this(new PostgreSqlConfiguration()) | ||
{ | ||
DockerResourceConfiguration = Init().DockerResourceConfiguration; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlBuilder" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
private PostgreSqlBuilder(PostgreSqlConfiguration resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
DockerResourceConfiguration = resourceConfiguration; | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override PostgreSqlConfiguration DockerResourceConfiguration { get; } | ||
|
||
/// <summary> | ||
/// Sets the PostgreSql database. | ||
/// </summary> | ||
/// <remarks> | ||
/// The Docker image does not allow to configure the database. | ||
/// </remarks> | ||
/// <param name="database">The PostgreSql database.</param> | ||
/// <returns>A configured instance of <see cref="PostgreSqlBuilder" />.</returns> | ||
public PostgreSqlBuilder WithDatabase(string database) | ||
{ | ||
return Merge(DockerResourceConfiguration, new PostgreSqlConfiguration(database: database)) | ||
.WithEnvironment("POSTGRES_DB", database); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the PostgreSql username. | ||
/// </summary> | ||
/// <remarks> | ||
/// The Docker image does not allow to configure the username. | ||
/// </remarks> | ||
/// <param name="username">The PostgreSql username.</param> | ||
/// <returns>A configured instance of <see cref="PostgreSqlBuilder" />.</returns> | ||
public PostgreSqlBuilder WithUsername(string username) | ||
{ | ||
return Merge(DockerResourceConfiguration, new PostgreSqlConfiguration(username: username)) | ||
.WithEnvironment("POSTGRES_USER", username); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the PostgreSql password. | ||
/// </summary> | ||
/// <param name="password">The PostgreSql password.</param> | ||
/// <returns>A configured instance of <see cref="PostgreSqlBuilder" />.</returns> | ||
public PostgreSqlBuilder WithPassword(string password) | ||
{ | ||
return Merge(DockerResourceConfiguration, new PostgreSqlConfiguration(password: password)) | ||
.WithEnvironment("POSTGRES_PASSWORD", password); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override PostgreSqlContainer Build() | ||
{ | ||
Validate(); | ||
return new PostgreSqlContainer(DockerResourceConfiguration, TestcontainersSettings.Logger); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override PostgreSqlBuilder Init() | ||
{ | ||
return base.Init() | ||
.WithImage(PostgreSqlImage) | ||
.WithPortBinding(PostgreSqlPort, true) | ||
.WithDatabase("postgres") | ||
.WithUsername("postgres") | ||
.WithPassword(Guid.NewGuid().ToString("D")) | ||
// Disable durability: https://www.postgresql.org/docs/current/non-durability.html. | ||
.WithCommand("-c", "fsync=off") | ||
.WithCommand("-c", "full_page_writes=off") | ||
.WithCommand("-c", "synchronous_commit=off") | ||
.WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("pg_isready")); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override void Validate() | ||
{ | ||
base.Validate(); | ||
|
||
_ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password)) | ||
.NotNull() | ||
.NotEmpty(); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override PostgreSqlBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) | ||
{ | ||
return Merge(DockerResourceConfiguration, new PostgreSqlConfiguration(resourceConfiguration)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override PostgreSqlBuilder Clone(IContainerConfiguration resourceConfiguration) | ||
{ | ||
return Merge(DockerResourceConfiguration, new PostgreSqlConfiguration(resourceConfiguration)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override PostgreSqlBuilder Merge(PostgreSqlConfiguration oldValue, PostgreSqlConfiguration newValue) | ||
{ | ||
return new PostgreSqlBuilder(new PostgreSqlConfiguration(oldValue, newValue)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
namespace Testcontainers.PostgreSql; | ||
|
||
/// <inheritdoc cref="ContainerConfiguration" /> | ||
[PublicAPI] | ||
public sealed class PostgreSqlConfiguration : ContainerConfiguration | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="database">The PostgreSql database.</param> | ||
/// <param name="username">The PostgreSql username.</param> | ||
/// <param name="password">The PostgreSql password.</param> | ||
public PostgreSqlConfiguration( | ||
string database = null, | ||
string username = null, | ||
string password = null) | ||
{ | ||
Database = database; | ||
Username = username; | ||
Password = password; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public PostgreSqlConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public PostgreSqlConfiguration(IContainerConfiguration resourceConfiguration) | ||
: base(resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="resourceConfiguration">The Docker resource configuration.</param> | ||
public PostgreSqlConfiguration(PostgreSqlConfiguration resourceConfiguration) | ||
: this(new PostgreSqlConfiguration(), resourceConfiguration) | ||
{ | ||
// Passes the configuration upwards to the base implementations to create an updated immutable copy. | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlConfiguration" /> class. | ||
/// </summary> | ||
/// <param name="oldValue">The old Docker resource configuration.</param> | ||
/// <param name="newValue">The new Docker resource configuration.</param> | ||
public PostgreSqlConfiguration(PostgreSqlConfiguration oldValue, PostgreSqlConfiguration newValue) | ||
: base(oldValue, newValue) | ||
{ | ||
Database = BuildConfiguration.Combine(oldValue.Database, newValue.Database); | ||
Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username); | ||
Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the PostgreSql database. | ||
/// </summary> | ||
public string Database { get; } | ||
|
||
/// <summary> | ||
/// Gets the PostgreSql username. | ||
/// </summary> | ||
public string Username { get; } | ||
|
||
/// <summary> | ||
/// Gets the PostgreSql password. | ||
/// </summary> | ||
public string Password { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
namespace Testcontainers.PostgreSql; | ||
|
||
/// <inheritdoc cref="DockerContainer" /> | ||
[PublicAPI] | ||
public sealed class PostgreSqlContainer : DockerContainer | ||
{ | ||
private readonly PostgreSqlConfiguration _configuration; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PostgreSqlContainer" /> class. | ||
/// </summary> | ||
/// <param name="configuration">The container configuration.</param> | ||
/// <param name="logger">The logger.</param> | ||
public PostgreSqlContainer(PostgreSqlConfiguration configuration, ILogger logger) | ||
: base(configuration, logger) | ||
{ | ||
_configuration = configuration; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the PostgreSql connection string. | ||
/// </summary> | ||
/// <returns>The PostgreSql connection string.</returns> | ||
public string GetConnectionString() | ||
{ | ||
var properties = new Dictionary<string, string>(); | ||
properties.Add("Host", Hostname); | ||
properties.Add("Port", GetMappedPublicPort(PostgreSqlBuilder.PostgreSqlPort).ToString()); | ||
properties.Add("Database", _configuration.Database); | ||
properties.Add("Username", _configuration.Username); | ||
properties.Add("Password", _configuration.Password); | ||
return string.Join(";", properties.Select(property => string.Join("=", property.Key, property.Value))); | ||
} | ||
|
||
/// <summary> | ||
/// Executes the SQL script in the PostgreSql container. | ||
/// </summary> | ||
/// <param name="scriptContent">The content of the SQL script to execute.</param> | ||
/// <param name="ct">Cancellation token.</param> | ||
/// <returns>Task that completes when the SQL script has been executed.</returns> | ||
public async Task<ExecResult> ExecScriptAsync(string scriptContent, CancellationToken ct = default) | ||
{ | ||
var scriptFilePath = string.Join("/", string.Empty, "tmp", Guid.NewGuid().ToString("D"), Path.GetRandomFileName()); | ||
|
||
await CopyFileAsync(scriptFilePath, Encoding.Default.GetBytes(scriptContent), 493, 0, 0, ct) | ||
.ConfigureAwait(false); | ||
|
||
return await ExecAsync(new[] { "psql", "--username", _configuration.Username, "--dbname", _configuration.Database, "--file", scriptFilePath }, ct) | ||
.ConfigureAwait(false); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Testcontainers.PostgreSql/Testcontainers.PostgreSql.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks> | ||
<LangVersion>latest</LangVersion> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1"/> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="$(SolutionDir)src/Testcontainers/Testcontainers.csproj"/> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 0 additions & 45 deletions
45
src/Testcontainers/_OBSOLETE_/Modules/Databases/PostgreSqlTestcontainer.cs
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.