Skip to content

Commit 44a1d3a

Browse files
0xcedHofmeisterAn
andauthored
feat: Share common interface (IDatabaseContainer) for ADO.NET compatible containers (#920)
Co-authored-by: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com>
1 parent 6e31cf3 commit 44a1d3a

File tree

13 files changed

+113
-7
lines changed

13 files changed

+113
-7
lines changed

Testcontainers.sln

+7
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Couchbase.Te
8787
EndProject
8888
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CouchDb.Tests", "tests\Testcontainers.CouchDb.Tests\Testcontainers.CouchDb.Tests.csproj", "{E4520FB1-4466-4DCA-AD08-4075102C68D3}"
8989
EndProject
90+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Databases.Tests", "tests\Testcontainers.Databases.Tests\Testcontainers.Databases.Tests.csproj", "{DA54916E-1128-4200-B6AE-9F5BF02D832D}"
91+
EndProject
9092
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.DynamoDb.Tests", "tests\Testcontainers.DynamoDb.Tests\Testcontainers.DynamoDb.Tests.csproj", "{101515E6-74C1-40F9-85C8-871F742A378D}"
9193
EndProject
9294
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Elasticsearch.Tests", "tests\Testcontainers.Elasticsearch.Tests\Testcontainers.Elasticsearch.Tests.csproj", "{DD5B3678-468F-4D73-AECE-705E3D66CD43}"
@@ -302,6 +304,10 @@ Global
302304
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
303305
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
304306
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Release|Any CPU.Build.0 = Release|Any CPU
307+
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
308+
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Debug|Any CPU.Build.0 = Debug|Any CPU
309+
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Release|Any CPU.ActiveCfg = Release|Any CPU
310+
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Release|Any CPU.Build.0 = Release|Any CPU
305311
{101515E6-74C1-40F9-85C8-871F742A378D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
306312
{101515E6-74C1-40F9-85C8-871F742A378D}.Debug|Any CPU.Build.0 = Debug|Any CPU
307313
{101515E6-74C1-40F9-85C8-871F742A378D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -457,6 +463,7 @@ Global
457463
{BD445A54-F411-4758-955E-397A1E98680C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
458464
{809322BA-D690-4F2B-B884-23F895663963} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
459465
{E4520FB1-4466-4DCA-AD08-4075102C68D3} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
466+
{DA54916E-1128-4200-B6AE-9F5BF02D832D} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
460467
{101515E6-74C1-40F9-85C8-871F742A378D} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
461468
{DD5B3678-468F-4D73-AECE-705E3D66CD43} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
462469
{64F8E9B9-78FD-4E13-BDDF-0340E2D4E1D0} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}

src/Testcontainers.ClickHouse/ClickHouseContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.ClickHouse;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class ClickHouseContainer : DockerContainer
5+
public sealed class ClickHouseContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly ClickHouseConfiguration _configuration;
88

src/Testcontainers.MariaDb/MariaDbContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.MariaDb;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class MariaDbContainer : DockerContainer
5+
public sealed class MariaDbContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly MariaDbConfiguration _configuration;
88

src/Testcontainers.MsSql/MsSqlContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.MsSql;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class MsSqlContainer : DockerContainer
5+
public sealed class MsSqlContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly MsSqlConfiguration _configuration;
88

src/Testcontainers.MySql/MySqlContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.MySql;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class MySqlContainer : DockerContainer
5+
public sealed class MySqlContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly MySqlConfiguration _configuration;
88

src/Testcontainers.Oracle/OracleContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.Oracle;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class OracleContainer : DockerContainer
5+
public sealed class OracleContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly OracleConfiguration _configuration;
88

src/Testcontainers.PostgreSql/PostgreSqlContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.PostgreSql;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class PostgreSqlContainer : DockerContainer
5+
public sealed class PostgreSqlContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly PostgreSqlConfiguration _configuration;
88

src/Testcontainers.SqlEdge/SqlEdgeContainer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace Testcontainers.SqlEdge;
22

33
/// <inheritdoc cref="DockerContainer" />
44
[PublicAPI]
5-
public sealed class SqlEdgeContainer : DockerContainer
5+
public sealed class SqlEdgeContainer : DockerContainer, IDatabaseContainer
66
{
77
private readonly SqlEdgeConfiguration _configuration;
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace DotNet.Testcontainers.Containers
2+
{
3+
using JetBrains.Annotations;
4+
5+
/// <summary>
6+
/// Represents a database container instance that can be accessed with an ADO.NET provider.
7+
/// </summary>
8+
[PublicAPI]
9+
public interface IDatabaseContainer
10+
{
11+
/// <summary>
12+
/// Gets the database connection string.
13+
/// </summary>
14+
/// <returns>The database connection string.</returns>
15+
[NotNull]
16+
string GetConnectionString();
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
root = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
namespace Testcontainers.Databases;
2+
3+
public sealed class DatabaseContainersTest
4+
{
5+
[Theory]
6+
[MemberData(nameof(GetContainerImplementations), parameters: true)]
7+
public void ShouldImplementIDatabaseContainer(Type type)
8+
{
9+
Assert.True(type.IsAssignableTo(typeof(IDatabaseContainer)), $"The type '{type.Name}' does not implement the database interface.");
10+
}
11+
12+
[Theory]
13+
[MemberData(nameof(GetContainerImplementations), parameters: false)]
14+
public void ShouldNotImplementIDatabaseContainer(Type type)
15+
{
16+
Assert.False(type.IsAssignableTo(typeof(IDatabaseContainer)), $"The type '{type.Name}' does implement the database interface.");
17+
}
18+
19+
public static IEnumerable<object[]> GetContainerImplementations(bool expectDataProvider)
20+
{
21+
var testAssemblies = Directory.GetFiles(".", "Testcontainers.*.Tests.dll", SearchOption.TopDirectoryOnly)
22+
.Select(Path.GetFullPath)
23+
.Select(Assembly.LoadFrom)
24+
.ToDictionary(assembly => assembly, assembly => assembly.GetReferencedAssemblies()
25+
.Where(referencedAssembly => referencedAssembly.Name != null)
26+
.Where(referencedAssembly => !referencedAssembly.Name.StartsWith("System"))
27+
.Where(referencedAssembly => !referencedAssembly.Name.StartsWith("xunit"))
28+
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Microsoft.VisualStudio.TestPlatform.ObjectModel"))
29+
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Docker.DotNet"))
30+
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Testcontainers"))
31+
.Select(Assembly.Load)
32+
.SelectMany(referencedAssembly => referencedAssembly.ExportedTypes)
33+
.ToImmutableList());
34+
35+
foreach (var testAssembly in testAssemblies)
36+
{
37+
// TODO: If a module contains multiple container implementations, it would require all container implementations to implement the interface.
38+
foreach (var containerType in testAssembly.Value.Where(type => type.IsAssignableTo(typeof(IContainer))))
39+
{
40+
var hasDataProvider = testAssembly.Value.Exists(type => type.IsSubclassOf(typeof(DbProviderFactory)));
41+
42+
if (expectDataProvider && hasDataProvider)
43+
{
44+
yield return new object[] { containerType };
45+
}
46+
47+
if (!expectDataProvider && !hasDataProvider)
48+
{
49+
yield return new object[] { containerType };
50+
}
51+
}
52+
}
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>net6.0</TargetFrameworks>
4+
<IsPackable>false</IsPackable>
5+
<IsPublishable>false</IsPublishable>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2"/>
9+
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
10+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"/>
11+
<PackageReference Include="xunit" Version="2.5.0"/>
12+
</ItemGroup>
13+
<ItemGroup>
14+
<ProjectReference Include="$(SolutionDir)tests/Testcontainers.*.Tests/Testcontainers.*.Tests.csproj"/>
15+
<ProjectReference Remove="$(SolutionDir)tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj"/>
16+
</ItemGroup>
17+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
global using System;
2+
global using System.Collections.Generic;
3+
global using System.Collections.Immutable;
4+
global using System.Data.Common;
5+
global using System.IO;
6+
global using System.Linq;
7+
global using System.Reflection;
8+
global using DotNet.Testcontainers.Containers;
9+
global using Xunit;

0 commit comments

Comments
 (0)