Skip to content

Commit

Permalink
feat: Share common interface (IDatabaseContainer) for ADO.NET compati…
Browse files Browse the repository at this point in the history
…ble containers (#920)

Co-authored-by: Andre Hofmeister <[email protected]>
  • Loading branch information
0xced and HofmeisterAn authored Oct 14, 2023
1 parent 6e31cf3 commit 44a1d3a
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 7 deletions.
7 changes: 7 additions & 0 deletions Testcontainers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Couchbase.Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.CouchDb.Tests", "tests\Testcontainers.CouchDb.Tests\Testcontainers.CouchDb.Tests.csproj", "{E4520FB1-4466-4DCA-AD08-4075102C68D3}"
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.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 @@ -302,6 +304,10 @@ Global
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4520FB1-4466-4DCA-AD08-4075102C68D3}.Release|Any CPU.Build.0 = Release|Any CPU
{DA54916E-1128-4200-B6AE-9F5BF02D832D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
{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 @@ -457,6 +463,7 @@ Global
{BD445A54-F411-4758-955E-397A1E98680C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{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}
{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
2 changes: 1 addition & 1 deletion src/Testcontainers.ClickHouse/ClickHouseContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.ClickHouse;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.MariaDb/MariaDbContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.MariaDb;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.MsSql/MsSqlContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.MsSql;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.MySql/MySqlContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.MySql;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.Oracle/OracleContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.Oracle;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.PostgreSql;

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

Expand Down
2 changes: 1 addition & 1 deletion src/Testcontainers.SqlEdge/SqlEdgeContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace Testcontainers.SqlEdge;

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

Expand Down
18 changes: 18 additions & 0 deletions src/Testcontainers/Containers/IDatabaseContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace DotNet.Testcontainers.Containers
{
using JetBrains.Annotations;

/// <summary>
/// Represents a database container instance that can be accessed with an ADO.NET provider.
/// </summary>
[PublicAPI]
public interface IDatabaseContainer
{
/// <summary>
/// Gets the database connection string.
/// </summary>
/// <returns>The database connection string.</returns>
[NotNull]
string GetConnectionString();
}
}
1 change: 1 addition & 0 deletions tests/Testcontainers.Databases.Tests/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
54 changes: 54 additions & 0 deletions tests/Testcontainers.Databases.Tests/DatabasesContainerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace Testcontainers.Databases;

public sealed class DatabaseContainersTest
{
[Theory]
[MemberData(nameof(GetContainerImplementations), parameters: true)]
public void ShouldImplementIDatabaseContainer(Type type)
{
Assert.True(type.IsAssignableTo(typeof(IDatabaseContainer)), $"The type '{type.Name}' does not implement the database interface.");
}

[Theory]
[MemberData(nameof(GetContainerImplementations), parameters: false)]
public void ShouldNotImplementIDatabaseContainer(Type type)
{
Assert.False(type.IsAssignableTo(typeof(IDatabaseContainer)), $"The type '{type.Name}' does implement the database interface.");
}

public static IEnumerable<object[]> GetContainerImplementations(bool expectDataProvider)
{
var testAssemblies = Directory.GetFiles(".", "Testcontainers.*.Tests.dll", SearchOption.TopDirectoryOnly)
.Select(Path.GetFullPath)
.Select(Assembly.LoadFrom)
.ToDictionary(assembly => assembly, assembly => assembly.GetReferencedAssemblies()
.Where(referencedAssembly => referencedAssembly.Name != null)
.Where(referencedAssembly => !referencedAssembly.Name.StartsWith("System"))
.Where(referencedAssembly => !referencedAssembly.Name.StartsWith("xunit"))
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Microsoft.VisualStudio.TestPlatform.ObjectModel"))
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Docker.DotNet"))
.Where(referencedAssembly => !referencedAssembly.Name.Equals("Testcontainers"))
.Select(Assembly.Load)
.SelectMany(referencedAssembly => referencedAssembly.ExportedTypes)
.ToImmutableList());

foreach (var testAssembly in testAssemblies)
{
// TODO: If a module contains multiple container implementations, it would require all container implementations to implement the interface.
foreach (var containerType in testAssembly.Value.Where(type => type.IsAssignableTo(typeof(IContainer))))
{
var hasDataProvider = testAssembly.Value.Exists(type => type.IsSubclassOf(typeof(DbProviderFactory)));

if (expectDataProvider && hasDataProvider)
{
yield return new object[] { containerType };
}

if (!expectDataProvider && !hasDataProvider)
{
yield return new object[] { containerType };
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2"/>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"/>
<PackageReference Include="xunit" Version="2.5.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)tests/Testcontainers.*.Tests/Testcontainers.*.Tests.csproj"/>
<ProjectReference Remove="$(SolutionDir)tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj"/>
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions tests/Testcontainers.Databases.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global using System;
global using System.Collections.Generic;
global using System.Collections.Immutable;
global using System.Data.Common;
global using System.IO;
global using System.Linq;
global using System.Reflection;
global using DotNet.Testcontainers.Containers;
global using Xunit;

0 comments on commit 44a1d3a

Please sign in to comment.