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: Share common interface (IDatabaseContainer) for ADO.NET compatible containers #920

Merged
merged 7 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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;