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

feat: Add Db2 module #1237

Merged
merged 57 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
61bfd3d
Add Db2 module
kevin0x90 Aug 20, 2024
3a0bef9
Merge branch 'develop' into Db2Support
kevin0x90 Aug 20, 2024
5feb0d0
Add windows / linux switch for Db2 dependency
kevin0x90 Aug 20, 2024
5558efe
Adjust conditional references
kevin0x90 Aug 20, 2024
7444da8
Revert conditional Db2 packages to use OS variable
kevin0x90 Aug 20, 2024
780f617
Remove windows condition for non is specific db2 dependency
kevin0x90 Aug 20, 2024
2a690e6
Adjust platform specific Db2 package conditions
kevin0x90 Aug 21, 2024
7d05809
Add Db2 windows dependency condition
kevin0x90 Aug 21, 2024
e11fdb2
Add Db2 dependency conditionals to test project
kevin0x90 Aug 21, 2024
128b996
Run Db2 connection test only on windows due to issues with the ubuntu…
kevin0x90 Aug 21, 2024
3597532
Attempt to exclude Db2 connection test on ubuntu runner
kevin0x90 Aug 21, 2024
398976b
Update docker platform trait for windows only test
kevin0x90 Aug 21, 2024
8f219eb
Set environment variables for Db2 test to run on linux
kevin0x90 Aug 22, 2024
65c88d9
Add condition to only set db2 env variables for linux, fix variable s…
kevin0x90 Aug 22, 2024
fd98e17
Update cicd.yml
kevin0x90 Aug 22, 2024
827b5cf
Update cicd.yml
kevin0x90 Aug 22, 2024
0872bf9
Update cicd.yml
kevin0x90 Aug 22, 2024
974b869
Add Db2 environment variables debug
kevin0x90 Aug 23, 2024
2aee543
Remove command continuation for Db2 variables
kevin0x90 Aug 23, 2024
45694ab
Adjust Db2 env variables
kevin0x90 Aug 23, 2024
9f3ab65
Generate runsettings file to prepare environment variables required f…
kevin0x90 Aug 23, 2024
d7be1e7
Adjust Db2 linux runsetting generation to fill a template file instea…
kevin0x90 Aug 24, 2024
8682b88
Add documentation and adjust test case for connectionstring
kevin0x90 Aug 31, 2024
0ca7952
Merge branch 'develop' into Db2Support
kevin0x90 Aug 31, 2024
0f81656
Add Db2 module documentation to navigation
kevin0x90 Sep 1, 2024
9ed4196
Add in-memory mapping and do not archive logs, no autoconfig to reduc…
kevin0x90 Sep 2, 2024
cd3a803
Merge branch 'develop' into Db2Support
kevin0x90 Sep 2, 2024
b6eccbc
Merge branch 'develop' into Db2Support
kevin0x90 Sep 3, 2024
3fcf5e9
Merge branch 'develop' into Db2Support
kevin0x90 Sep 6, 2024
15f59ef
Use source includes for documentation
kevin0x90 Sep 9, 2024
21948f9
Merge branch 'develop' into Db2Support
kevin0x90 Sep 10, 2024
86e6479
Minor cleanup
kevin0x90 Sep 10, 2024
53b351f
Merge branch 'develop' into Db2Support
kevin0x90 Sep 16, 2024
63e650d
Merge branch 'develop' into Db2Support
kevin0x90 Oct 1, 2024
3415734
Remoe no longer existing papercut module from solution file after wro…
kevin0x90 Oct 1, 2024
8bff452
Remove no longer existing sql edge project from solution
kevin0x90 Oct 1, 2024
f8fa99a
Merge branch 'develop' into Db2Support
kevin0x90 Oct 4, 2024
5023ccb
Merge branch 'develop' into Db2Support
kevin0x90 Oct 12, 2024
918c818
Merge branch 'develop' into Db2Support
kevin0x90 Oct 15, 2024
be5474a
Merge branch 'develop' into Db2Support
kevin0x90 Oct 18, 2024
7c243c2
Merge branch 'develop' into Db2Support
kevin0x90 Nov 1, 2024
7eaebb4
Merge branch 'develop' into Db2Support
kevin0x90 Nov 3, 2024
29158fe
Merge branch 'develop' into Db2Support
kevin0x90 Nov 10, 2024
dfabfe5
Merge branch 'develop' into Db2Support
kevin0x90 Nov 16, 2024
ab14114
Merge branch 'develop' into Db2Support
kevin0x90 Nov 18, 2024
4527b63
Merge branch 'develop' into Db2Support
kevin0x90 Nov 21, 2024
481d128
Merge branch 'Db2Support' of github.com:kevin0x90/testcontainers-dotn…
HofmeisterAn Jan 27, 2025
b8254fd
chore: Merge develop, align repo standards
HofmeisterAn Jan 27, 2025
55ae22d
chore: Revert sln changes
HofmeisterAn Jan 27, 2025
506537d
Merge branch 'develop' into Db2Support
kevin0x90 Jan 31, 2025
16ffff8
Merge branch 'develop' into Db2Support
kevin0x90 Feb 2, 2025
d4f83d2
Merge branch 'develop' into Db2Support
kevin0x90 Feb 8, 2025
505eeb7
Implement code review feedback
kevin0x90 Feb 10, 2025
a2da43e
Merge branch 'develop' into Db2Support
kevin0x90 Feb 10, 2025
dd5d7c0
Merge branch 'develop' into Db2Support
kevin0x90 Feb 11, 2025
75d564d
chore: Update remaining parts
HofmeisterAn Feb 13, 2025
7fc391b
fix: Replace link to targets file
HofmeisterAn Feb 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
{ name: "Testcontainers.CosmosDb", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Couchbase", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.CouchDb", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Db2", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.DynamoDb", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Elasticsearch", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.EventStoreDb", runs-on: "ubuntu-22.04" },
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
<PackageVersion Include="Confluent.SchemaRegistry" Version="2.8.0"/>
<PackageVersion Include="Consul" Version="1.6.10.9"/>
<PackageVersion Include="CouchbaseNetClient" Version="3.6.4"/>
<PackageVersion Include="Net.IBM.Data.Db2-lnx" Version="9.0.0.100"/>
<PackageVersion Include="Net.IBM.Data.Db2" Version="9.0.0.100"/>
<PackageVersion Include="DotPulsar" Version="3.3.2"/>
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.16.3"/>
<PackageVersion Include="EventStore.Client.Grpc.Streams" Version="22.0.0"/>
Expand Down
14 changes: 14 additions & 0 deletions Testcontainers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Couchbase",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CouchDb", "src\Testcontainers.CouchDb\Testcontainers.CouchDb.csproj", "{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Db2", "src\Testcontainers.Db2\Testcontainers.Db2.csproj", "{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.DynamoDb", "src\Testcontainers.DynamoDb\Testcontainers.DynamoDb.csproj", "{2EAFA567-9F68-4C52-9DBC-8F3EC11BB2CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Elasticsearch", "src\Testcontainers.Elasticsearch\Testcontainers.Elasticsearch.csproj", "{641DDEA5-B6E0-41E6-BA11-7A28C0913127}"
Expand Down Expand Up @@ -135,6 +137,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CouchDb.Test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Databases.Tests", "tests\Testcontainers.Databases.Tests\Testcontainers.Databases.Tests.csproj", "{DA54916E-1128-4200-B6AE-9F5BF02D832D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Db2.Tests", "tests\Testcontainers.Db2.Tests\Testcontainers.Db2.Tests.csproj", "{AF9853AB-86E7-49DE-8DF8-454838E90D6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.DynamoDb.Tests", "tests\Testcontainers.DynamoDb.Tests\Testcontainers.DynamoDb.Tests.csproj", "{101515E6-74C1-40F9-85C8-871F742A378D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Elasticsearch.Tests", "tests\Testcontainers.Elasticsearch.Tests\Testcontainers.Elasticsearch.Tests.csproj", "{DD5B3678-468F-4D73-AECE-705E3D66CD43}"
Expand Down Expand Up @@ -266,6 +270,10 @@ Global
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC}.Release|Any CPU.Build.0 = Release|Any CPU
{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9}.Release|Any CPU.Build.0 = Release|Any CPU
{2EAFA567-9F68-4C52-9DBC-8F3EC11BB2CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EAFA567-9F68-4C52-9DBC-8F3EC11BB2CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EAFA567-9F68-4C52-9DBC-8F3EC11BB2CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -466,6 +474,10 @@ Global
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Release|Any CPU.Build.0 = Release|Any CPU
{AF9853AB-86E7-49DE-8DF8-454838E90D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF9853AB-86E7-49DE-8DF8-454838E90D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF9853AB-86E7-49DE-8DF8-454838E90D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF9853AB-86E7-49DE-8DF8-454838E90D6F}.Release|Any CPU.Build.0 = Release|Any CPU
{101515E6-74C1-40F9-85C8-871F742A378D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{101515E6-74C1-40F9-85C8-871F742A378D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{101515E6-74C1-40F9-85C8-871F742A378D}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -635,6 +647,7 @@ Global
{A724806F-8C94-4438-8011-04A9A1575318} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{58E94721-2681-4D82-8D94-0B2F9DB0D575} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{DCECB1F6-D9AA-431F-AE42-25D56B9E7DFC} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{ED3C611F-DFE2-4AB7-A323-B500E95B4FF9} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{2EAFA567-9F68-4C52-9DBC-8F3EC11BB2CE} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{641DDEA5-B6E0-41E6-BA11-7A28C0913127} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{84D707E0-C9FA-4327-85DC-0AFEBEA73572} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
Expand Down Expand Up @@ -685,6 +698,7 @@ Global
{809322BA-D690-4F2B-B884-23F895663963} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{E4520FB1-4466-4DCA-AD08-4075102C68D3} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{DA54916E-1128-4200-B6AE-9F5BF02D832D} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{AF9853AB-86E7-49DE-8DF8-454838E90D6F} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{101515E6-74C1-40F9-85C8-871F742A378D} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{DD5B3678-468F-4D73-AECE-705E3D66CD43} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{64F8E9B9-78FD-4E13-BDDF-0340E2D4E1D0} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
Expand Down
31 changes: 31 additions & 0 deletions docs/modules/db2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Db2

[Db2](https://www.ibm.com/db2) is a relational database engine developed by IBM.

Add the following dependency to your project file:

```shell title="NuGet"
dotnet add package Testcontainers.Db2
```

!!! warning

The Linux client dependency, [Net.IBM.Data.Db2-lnx](https://www.nuget.org/packages/Net.IBM.Data.Db2-lnx), requires additional configurations. We use the [Testcontainers.Db2.Tests.targets](https://github.com/testcontainers/testcontainers-dotnet/blob/develop/tests/Testcontainers.Db2.Tests/Testcontainers.Db2.Tests.targets) file to configure the environment variables: `LD_LIBRARY_PATH`, `PATH`, `DB2_CLI_DRIVER_INSTALL_PATH`, at runtime.

You can start an Db2 container instance from any .NET application. This example uses xUnit.net's `IAsyncLifetime` interface to manage the lifecycle of the container. The container is started in the `InitializeAsync` method before the test method runs, ensuring that the environment is ready for testing. After the test completes, the container is removed in the `DisposeAsync` method.

=== "Usage Example"
```csharp
--8<-- "tests/Testcontainers.Db2.Tests/Db2ContainerTest.cs:UseDb2Container"
```

The test example uses the following NuGet dependencies:

=== "Package References"
```xml
--8<-- "tests/Testcontainers.Db2.Tests/Testcontainers.Db2.Tests.csproj:PackageReferences"
```

To execute the tests, use the command `dotnet test` from a terminal.

--8<-- "docs/modules/_call_out_test_projects.txt"
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ nav:
- examples/aspnet.md
- Modules:
- modules/index.md
- modules/db2.md
- modules/elasticsearch.md
- modules/mongodb.md
- modules/mssql.md
Expand Down
1 change: 1 addition & 0 deletions src/Testcontainers.Db2/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
149 changes: 149 additions & 0 deletions src/Testcontainers.Db2/Db2Builder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
namespace Testcontainers.Db2;

/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
[PublicAPI]
public sealed class Db2Builder : ContainerBuilder<Db2Builder, Db2Container, Db2Configuration>
{
public const string Db2Image = "icr.io/db2_community/db2:12.1.0.0";

public const ushort Db2Port = 50000;

public const string DefaultDatabase = "test";

public const string DefaultUsername = "db2inst1";

public const string DefaultPassword = "db2inst1";

private const string AcceptLicenseAgreementEnvVar = "LICENSE";

private const string AcceptLicenseAgreement = "accept";

private const string DeclineLicenseAgreement = "decline";

/// <summary>
/// Initializes a new instance of the <see cref="Db2Builder" /> class.
/// </summary>
public Db2Builder()
: this(new Db2Configuration())
{
DockerResourceConfiguration = Init().DockerResourceConfiguration;
}

/// <summary>
/// Initializes a new instance of the <see cref="Db2Builder" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
private Db2Builder(Db2Configuration resourceConfiguration)
: base(resourceConfiguration)
{
DockerResourceConfiguration = resourceConfiguration;
}

/// <inheritdoc />
protected override Db2Configuration DockerResourceConfiguration { get; }

/// <summary>
/// Accepts the license agreement.
/// </summary>
/// <remarks>
/// When <paramref name="acceptLicenseAgreement" /> is set to <c>true</c>, the Db2 <see href="www.ibm.com/terms/?id=L-SNMD-UVTL8R">license</see> is accepted.
/// </remarks>
/// <param name="acceptLicenseAgreement">A boolean value indicating whether the Db2 license agreement is accepted.</param>
/// <returns>A configured instance of <see cref="Db2Builder" />.</returns>
public Db2Builder WithAcceptLicenseAgreement(bool acceptLicenseAgreement)
{
var licenseAgreement = acceptLicenseAgreement ? AcceptLicenseAgreement : DeclineLicenseAgreement;
return WithEnvironment(AcceptLicenseAgreementEnvVar, licenseAgreement);
}

/// <summary>
/// Sets the Db2 database name.
/// </summary>
/// <param name="database">The Db2 database.</param>
/// <returns>A configured instance of <see cref="Db2Builder" />.</returns>
public Db2Builder WithDatabase(string database)
{
return Merge(DockerResourceConfiguration, new Db2Configuration(database: database))
.WithEnvironment("DBNAME", database);
}

/// <summary>
/// Sets the Db2 username.
/// </summary>
/// <param name="username">The Db2 username.</param>
/// <returns>A configured instance of <see cref="Db2Builder" />.</returns>
public Db2Builder WithUsername(string username)
{
return Merge(DockerResourceConfiguration, new Db2Configuration(username: username))
.WithEnvironment("DB2INSTANCE", username)
.WithTmpfsMount(string.Join("/", string.Empty, "home", username, "data"));
}

/// <summary>
/// Sets the Db2 password.
/// </summary>
/// <param name="password">The Db2 password.</param>
/// <returns>A configured instance of <see cref="Db2Builder" />.</returns>
public Db2Builder WithPassword(string password)
{
return Merge(DockerResourceConfiguration, new Db2Configuration(password: password))
.WithEnvironment("DB2INST1_PASSWORD", password);
}

/// <inheritdoc />
public override Db2Container Build()
{
Validate();
return new Db2Container(DockerResourceConfiguration);
}

/// <inheritdoc />
protected override Db2Builder Init() => base.Init()
.WithImage(Db2Image)
.WithPortBinding(Db2Port, true)
.WithDatabase(DefaultDatabase)
.WithUsername(DefaultUsername)
.WithPassword(DefaultPassword)
.WithPrivileged(true)
.WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Setup has completed."));

/// <inheritdoc />
protected override void Validate()
{
const string message = "The image '{0}' requires you to accept a license agreement.";

base.Validate();

Predicate<Db2Configuration> licenseAgreementNotAccepted = value =>
!value.Environments.TryGetValue(AcceptLicenseAgreementEnvVar, out var licenseAgreementValue) || !AcceptLicenseAgreement.Equals(licenseAgreementValue, StringComparison.Ordinal);

_ = Guard.Argument(DockerResourceConfiguration, nameof(DockerResourceConfiguration.Image))
.ThrowIf(argument => licenseAgreementNotAccepted(argument.Value), argument => throw new ArgumentException(string.Format(message, DockerResourceConfiguration.Image.FullName), argument.Name));

_ = Guard.Argument(DockerResourceConfiguration.Username, nameof(DockerResourceConfiguration.Username))
.NotNull()
.NotEmpty();

_ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password))
.NotNull()
.NotEmpty();
}

/// <inheritdoc />
protected override Db2Builder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new Db2Configuration(resourceConfiguration));
}

/// <inheritdoc />
protected override Db2Builder Clone(IContainerConfiguration resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new Db2Configuration(resourceConfiguration));
}

/// <inheritdoc />
protected override Db2Builder Merge(Db2Configuration oldValue, Db2Configuration newValue)
{
return new Db2Builder(new Db2Configuration(oldValue, newValue));
}
}
80 changes: 80 additions & 0 deletions src/Testcontainers.Db2/Db2Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace Testcontainers.Db2;

/// <inheritdoc cref="ContainerConfiguration" />
[PublicAPI]
public sealed class Db2Configuration : ContainerConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="Db2Configuration" /> class.
/// </summary>
/// <param name="database">The Db2 database.</param>
/// <param name="username">The Db2 username.</param>
/// <param name="password">The Db2 password.</param>
public Db2Configuration(
string database = null,
string username = null,
string password = null)
{
Database = database;
Username = username;
Password = password;
}

/// <summary>
/// Initializes a new instance of the <see cref="Db2Configuration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public Db2Configuration(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="Db2Configuration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public Db2Configuration(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="Db2Configuration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public Db2Configuration(Db2Configuration resourceConfiguration)
: this(new Db2Configuration(), resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="Db2Configuration" /> class.
/// </summary>
/// <param name="oldValue">The old Docker resource configuration.</param>
/// <param name="newValue">The new Docker resource configuration.</param>
public Db2Configuration(Db2Configuration oldValue, Db2Configuration 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 Db2 database.
/// </summary>
public string Database { get; }

/// <summary>
/// Gets the Db2 username.
/// </summary>
public string Username { get; }

/// <summary>
/// Gets the Db2 password.
/// </summary>
public string Password { get; }
}
48 changes: 48 additions & 0 deletions src/Testcontainers.Db2/Db2Container.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace Testcontainers.Db2;

/// <inheritdoc cref="DockerContainer" />
[PublicAPI]
public sealed class Db2Container : DockerContainer, IDatabaseContainer
{
private readonly Db2Configuration _configuration;

public Db2Container(Db2Configuration configuration) : base(configuration)
{
_configuration = configuration;
}

/// <summary>
/// Gets the Db2 connection string.
/// </summary>
/// <returns>The Db2 connection string.</returns>
public string GetConnectionString()
{
var properties = new Dictionary<string, string>();
properties.Add("Server", Hostname + ":" + GetMappedPublicPort(Db2Builder.Db2Port));
properties.Add("Database", _configuration.Database);
properties.Add("UID", _configuration.Username);
properties.Add("PWD", _configuration.Password);
return string.Join(";", properties.Select(property => string.Join("=", property.Key, property.Value)));
}

/// <summary>
/// Executes the SQL script in the Db2 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)
{
const string db2ShellCommandFormat = "su - {1} -c \"db2 connect to {0} && db2 -tvf '{2}'\"";

var scriptFilePath = string.Join("/", string.Empty, "tmp", Guid.NewGuid().ToString("D"), Path.GetRandomFileName());

var db2ShellCommand = string.Format(db2ShellCommandFormat, _configuration.Database, _configuration.Username, scriptFilePath);

await CopyAsync(Encoding.Default.GetBytes(scriptContent), scriptFilePath, Unix.FileMode644, ct)
.ConfigureAwait(false);

return await ExecAsync(new [] { "/bin/sh", "-c", db2ShellCommand}, ct)
.ConfigureAwait(false);
}
}
Loading
Loading