diff --git a/Packages.props b/Packages.props
index b39430ff1..ef7c70552 100644
--- a/Packages.props
+++ b/Packages.props
@@ -8,7 +8,7 @@
-
+
diff --git a/Testcontainers.sln b/Testcontainers.sln
index 0969d4f4e..813d4d211 100644
--- a/Testcontainers.sln
+++ b/Testcontainers.sln
@@ -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}"
@@ -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
@@ -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}
diff --git a/src/Testcontainers.ClickHouse/ClickHouseContainer.cs b/src/Testcontainers.ClickHouse/ClickHouseContainer.cs
index 3b7328860..d1bc808ff 100644
--- a/src/Testcontainers.ClickHouse/ClickHouseContainer.cs
+++ b/src/Testcontainers.ClickHouse/ClickHouseContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.ClickHouse;
///
[PublicAPI]
-public sealed class ClickHouseContainer : DockerContainer
+public sealed class ClickHouseContainer : DockerContainer, IDatabaseContainer
{
private readonly ClickHouseConfiguration _configuration;
diff --git a/src/Testcontainers.MariaDb/MariaDbContainer.cs b/src/Testcontainers.MariaDb/MariaDbContainer.cs
index 97fba03c9..08b603344 100644
--- a/src/Testcontainers.MariaDb/MariaDbContainer.cs
+++ b/src/Testcontainers.MariaDb/MariaDbContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.MariaDb;
///
[PublicAPI]
-public sealed class MariaDbContainer : DockerContainer
+public sealed class MariaDbContainer : DockerContainer, IDatabaseContainer
{
private readonly MariaDbConfiguration _configuration;
diff --git a/src/Testcontainers.MsSql/MsSqlContainer.cs b/src/Testcontainers.MsSql/MsSqlContainer.cs
index 865f38e20..78c8f2c36 100644
--- a/src/Testcontainers.MsSql/MsSqlContainer.cs
+++ b/src/Testcontainers.MsSql/MsSqlContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.MsSql;
///
[PublicAPI]
-public sealed class MsSqlContainer : DockerContainer
+public sealed class MsSqlContainer : DockerContainer, IDatabaseContainer
{
private readonly MsSqlConfiguration _configuration;
diff --git a/src/Testcontainers.MySql/MySqlContainer.cs b/src/Testcontainers.MySql/MySqlContainer.cs
index 59dc19c8b..5b55be35e 100644
--- a/src/Testcontainers.MySql/MySqlContainer.cs
+++ b/src/Testcontainers.MySql/MySqlContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.MySql;
///
[PublicAPI]
-public sealed class MySqlContainer : DockerContainer
+public sealed class MySqlContainer : DockerContainer, IDatabaseContainer
{
private readonly MySqlConfiguration _configuration;
diff --git a/src/Testcontainers.Oracle/OracleContainer.cs b/src/Testcontainers.Oracle/OracleContainer.cs
index fa8cdab92..e1b1ae4c1 100644
--- a/src/Testcontainers.Oracle/OracleContainer.cs
+++ b/src/Testcontainers.Oracle/OracleContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.Oracle;
///
[PublicAPI]
-public sealed class OracleContainer : DockerContainer
+public sealed class OracleContainer : DockerContainer, IDatabaseContainer
{
private readonly OracleConfiguration _configuration;
diff --git a/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs b/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
index 3ac48447c..c771e6f11 100644
--- a/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
+++ b/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.PostgreSql;
///
[PublicAPI]
-public sealed class PostgreSqlContainer : DockerContainer
+public sealed class PostgreSqlContainer : DockerContainer, IDatabaseContainer
{
private readonly PostgreSqlConfiguration _configuration;
diff --git a/src/Testcontainers.SqlEdge/SqlEdgeContainer.cs b/src/Testcontainers.SqlEdge/SqlEdgeContainer.cs
index ccbb3124b..17ff0f4f1 100644
--- a/src/Testcontainers.SqlEdge/SqlEdgeContainer.cs
+++ b/src/Testcontainers.SqlEdge/SqlEdgeContainer.cs
@@ -2,7 +2,7 @@ namespace Testcontainers.SqlEdge;
///
[PublicAPI]
-public sealed class SqlEdgeContainer : DockerContainer
+public sealed class SqlEdgeContainer : DockerContainer, IDatabaseContainer
{
private readonly SqlEdgeConfiguration _configuration;
diff --git a/src/Testcontainers/Clients/ContainerConfigurationConverter.cs b/src/Testcontainers/Clients/ContainerConfigurationConverter.cs
index 7a2736117..84f7dfb7c 100644
--- a/src/Testcontainers/Clients/ContainerConfigurationConverter.cs
+++ b/src/Testcontainers/Clients/ContainerConfigurationConverter.cs
@@ -50,7 +50,7 @@ public ContainerConfigurationConverter(IContainerConfiguration configuration)
private static string GetQualifiedPort(string containerPort)
{
- return new[] { UdpPortSuffix, TcpPortSuffix, SctpPortSuffix }.Any(portSuffix => containerPort.EndsWith(portSuffix, StringComparison.OrdinalIgnoreCase)) ? containerPort.ToLowerInvariant() : containerPort + TcpPortSuffix;
+ return Array.Exists(new[] { UdpPortSuffix, TcpPortSuffix, SctpPortSuffix }, portSuffix => containerPort.EndsWith(portSuffix, StringComparison.OrdinalIgnoreCase)) ? containerPort.ToLowerInvariant() : containerPort + TcpPortSuffix;
}
private sealed class ToCollection : CollectionConverter
diff --git a/src/Testcontainers/Clients/DockerContainerOperations.cs b/src/Testcontainers/Clients/DockerContainerOperations.cs
index de7526acc..33d7e7d9e 100644
--- a/src/Testcontainers/Clients/DockerContainerOperations.cs
+++ b/src/Testcontainers/Clients/DockerContainerOperations.cs
@@ -34,21 +34,11 @@ public async Task> GetAllAsync(FilterByProper
.ConfigureAwait(false);
}
- public Task ByIdAsync(string id, CancellationToken ct = default)
- {
- return ByPropertyAsync("id", id, ct);
- }
-
- public Task ByNameAsync(string name, CancellationToken ct = default)
- {
- return ByPropertyAsync("name", name, ct);
- }
-
- public async Task ByPropertyAsync(string property, string value, CancellationToken ct = default)
+ public async Task ByIdAsync(string id, CancellationToken ct = default)
{
try
{
- return await Docker.Containers.InspectContainerAsync(value, ct)
+ return await Docker.Containers.InspectContainerAsync(id, ct)
.ConfigureAwait(false);
}
catch (DockerApiException)
@@ -65,18 +55,12 @@ public async Task ExistsWithIdAsync(string id, CancellationToken ct = defa
return response != null;
}
- public async Task ExistsWithNameAsync(string name, CancellationToken ct = default)
+ public async Task GetExitCodeAsync(string id, CancellationToken ct = default)
{
- var response = await ByNameAsync(name, ct)
+ var response = await Docker.Containers.WaitContainerAsync(id, ct)
.ConfigureAwait(false);
- return response != null;
- }
-
- public async Task GetExitCodeAsync(string id, CancellationToken ct = default)
- {
- return (await Docker.Containers.WaitContainerAsync(id, ct)
- .ConfigureAwait(false)).StatusCode;
+ return response.StatusCode;
}
public async Task<(string Stdout, string Stderr)> GetLogsAsync(string id, TimeSpan since, TimeSpan until, bool timestampsEnabled = true, CancellationToken ct = default)
diff --git a/src/Testcontainers/Clients/DockerImageOperations.cs b/src/Testcontainers/Clients/DockerImageOperations.cs
index f469bd569..7dc2df009 100644
--- a/src/Testcontainers/Clients/DockerImageOperations.cs
+++ b/src/Testcontainers/Clients/DockerImageOperations.cs
@@ -37,21 +37,11 @@ public async Task> GetAllAsync(FilterByProperty
.ConfigureAwait(false);
}
- public Task ByIdAsync(string id, CancellationToken ct = default)
- {
- return ByPropertyAsync("id", id, ct);
- }
-
- public Task ByNameAsync(string name, CancellationToken ct = default)
- {
- return ByPropertyAsync("reference", name, ct);
- }
-
- public async Task ByPropertyAsync(string property, string value, CancellationToken ct = default)
+ public async Task ByIdAsync(string id, CancellationToken ct = default)
{
try
{
- return await Docker.Images.InspectImageAsync(value, ct)
+ return await Docker.Images.InspectImageAsync(id, ct)
.ConfigureAwait(false);
}
catch (DockerApiException)
@@ -68,14 +58,6 @@ public async Task ExistsWithIdAsync(string id, CancellationToken ct = defa
return response != null;
}
- public async Task ExistsWithNameAsync(string name, CancellationToken ct = default)
- {
- var response = await ByNameAsync(name, ct)
- .ConfigureAwait(false);
-
- return response != null;
- }
-
public async Task CreateAsync(IImage image, IDockerRegistryAuthenticationConfiguration dockerRegistryAuthConfig, CancellationToken ct = default)
{
var createParameters = new ImagesCreateParameters
@@ -108,7 +90,7 @@ public async Task BuildAsync(IImageFromDockerfileConfiguration configura
{
var image = configuration.Image;
- var imageExists = await ExistsWithNameAsync(image.FullName, ct)
+ var imageExists = await ExistsWithIdAsync(image.FullName, ct)
.ConfigureAwait(false);
if (imageExists && configuration.DeleteIfExists.HasValue && configuration.DeleteIfExists.Value)
@@ -143,7 +125,7 @@ await DeleteAsync(image, ct)
await Docker.Images.BuildImageFromDockerfileAsync(buildParameters, dockerfileArchiveStream, Array.Empty(), new Dictionary(), _traceProgress, ct)
.ConfigureAwait(false);
- var imageHasBeenCreated = await ExistsWithNameAsync(image.FullName, ct)
+ var imageHasBeenCreated = await ExistsWithIdAsync(image.FullName, ct)
.ConfigureAwait(false);
if (!imageHasBeenCreated)
diff --git a/src/Testcontainers/Clients/DockerNetworkOperations.cs b/src/Testcontainers/Clients/DockerNetworkOperations.cs
index 503db9c0e..b0afbf444 100644
--- a/src/Testcontainers/Clients/DockerNetworkOperations.cs
+++ b/src/Testcontainers/Clients/DockerNetworkOperations.cs
@@ -32,21 +32,11 @@ public async Task> GetAllAsync(FilterByProperty fil
.ConfigureAwait(false);
}
- public Task ByIdAsync(string id, CancellationToken ct = default)
- {
- return ByPropertyAsync("id", id, ct);
- }
-
- public Task ByNameAsync(string name, CancellationToken ct = default)
- {
- return ByPropertyAsync("name", name, ct);
- }
-
- public async Task ByPropertyAsync(string property, string value, CancellationToken ct = default)
+ public async Task ByIdAsync(string id, CancellationToken ct = default)
{
try
{
- return await Docker.Networks.InspectNetworkAsync(value, ct)
+ return await Docker.Networks.InspectNetworkAsync(id, ct)
.ConfigureAwait(false);
}
catch (DockerApiException)
@@ -63,14 +53,6 @@ public async Task ExistsWithIdAsync(string id, CancellationToken ct = defa
return response != null;
}
- public async Task ExistsWithNameAsync(string name, CancellationToken ct = default)
- {
- var response = await ByNameAsync(name, ct)
- .ConfigureAwait(false);
-
- return response != null;
- }
-
public async Task CreateAsync(INetworkConfiguration configuration, CancellationToken ct = default)
{
var createParameters = new NetworksCreateParameters
diff --git a/src/Testcontainers/Clients/DockerSystemOperations.cs b/src/Testcontainers/Clients/DockerSystemOperations.cs
index ad2751c85..72853fcfc 100644
--- a/src/Testcontainers/Clients/DockerSystemOperations.cs
+++ b/src/Testcontainers/Clients/DockerSystemOperations.cs
@@ -19,6 +19,7 @@ public async Task GetIsWindowsEngineEnabled(CancellationToken ct = default
{
var version = await GetVersionAsync(ct)
.ConfigureAwait(false);
+
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
}
diff --git a/src/Testcontainers/Clients/DockerVolumeOperations.cs b/src/Testcontainers/Clients/DockerVolumeOperations.cs
index 4224bd92b..e1266d809 100644
--- a/src/Testcontainers/Clients/DockerVolumeOperations.cs
+++ b/src/Testcontainers/Clients/DockerVolumeOperations.cs
@@ -36,21 +36,11 @@ public async Task> GetAllAsync(FilterByProperty filt
return response.Volumes;
}
- public Task ByIdAsync(string id, CancellationToken ct = default)
- {
- return ByPropertyAsync("id", id, ct);
- }
-
- public Task ByNameAsync(string name, CancellationToken ct = default)
- {
- return ByPropertyAsync("name", name, ct);
- }
-
- public async Task ByPropertyAsync(string property, string value, CancellationToken ct = default)
+ public async Task ByIdAsync(string id, CancellationToken ct = default)
{
try
{
- return await Docker.Volumes.InspectAsync(value, ct)
+ return await Docker.Volumes.InspectAsync(id, ct)
.ConfigureAwait(false);
}
catch (DockerApiException)
@@ -67,14 +57,6 @@ public async Task ExistsWithIdAsync(string id, CancellationToken ct = defa
return response != null;
}
- public async Task ExistsWithNameAsync(string name, CancellationToken ct = default)
- {
- var response = await ByNameAsync(name, ct)
- .ConfigureAwait(false);
-
- return response != null;
- }
-
public async Task CreateAsync(IVolumeConfiguration configuration, CancellationToken ct = default)
{
var createParameters = new VolumesCreateParameters
diff --git a/src/Testcontainers/Clients/IHasListOperations.cs b/src/Testcontainers/Clients/IHasListOperations.cs
index e22229e6b..e5421df1d 100644
--- a/src/Testcontainers/Clients/IHasListOperations.cs
+++ b/src/Testcontainers/Clients/IHasListOperations.cs
@@ -12,12 +12,6 @@ internal interface IHasListOperations
Task ByIdAsync(string id, CancellationToken ct = default);
- Task ByNameAsync(string name, CancellationToken ct = default);
-
- Task ByPropertyAsync(string property, string value, CancellationToken ct = default);
-
Task ExistsWithIdAsync(string id, CancellationToken ct = default);
-
- Task ExistsWithNameAsync(string name, CancellationToken ct = default);
}
}
diff --git a/src/Testcontainers/Clients/TestcontainersClient.cs b/src/Testcontainers/Clients/TestcontainersClient.cs
index 2d9e45587..737b82bf3 100644
--- a/src/Testcontainers/Clients/TestcontainersClient.cs
+++ b/src/Testcontainers/Clients/TestcontainersClient.cs
@@ -293,7 +293,7 @@ public async Task RunAsync(IContainerConfiguration configuration, Cancel
.ConfigureAwait(false);
}
- var cachedImage = await Image.ByNameAsync(configuration.Image.FullName, ct)
+ var cachedImage = await Image.ByIdAsync(configuration.Image.FullName, ct)
.ConfigureAwait(false);
if (configuration.ImagePullPolicy(cachedImage))
@@ -323,7 +323,7 @@ await Task.WhenAll(configuration.ResourceMappings.Values.Select(resourceMapping
///
public async Task BuildAsync(IImageFromDockerfileConfiguration configuration, CancellationToken ct = default)
{
- var cachedImage = await Image.ByNameAsync(configuration.Image.FullName, ct)
+ var cachedImage = await Image.ByIdAsync(configuration.Image.FullName, ct)
.ConfigureAwait(false);
if (configuration.ImageBuildPolicy(cachedImage))
diff --git a/src/Testcontainers/Containers/DockerContainer.cs b/src/Testcontainers/Containers/DockerContainer.cs
index e7db53b33..1e9bbf855 100644
--- a/src/Testcontainers/Containers/DockerContainer.cs
+++ b/src/Testcontainers/Containers/DockerContainer.cs
@@ -7,7 +7,6 @@ namespace DotNet.Testcontainers.Containers
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
- using Docker.DotNet;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Clients;
using DotNet.Testcontainers.Configurations;
@@ -472,15 +471,8 @@ protected virtual async Task UnsafeStopAsync(CancellationToken ct = default)
await _client.StopAsync(_container.ID, ct)
.ConfigureAwait(false);
- try
- {
- _container = await _client.Container.ByIdAsync(_container.ID, ct)
- .ConfigureAwait(false);
- }
- catch (DockerApiException)
- {
- _container = new ContainerInspectResponse();
- }
+ _container = await _client.Container.ByIdAsync(_container.ID, ct)
+ .ConfigureAwait(false);
Stopped?.Invoke(this, EventArgs.Empty);
}
@@ -488,7 +480,7 @@ await _client.StopAsync(_container.ID, ct)
///
protected override bool Exists()
{
- return ContainerHasBeenCreatedStates.HasFlag(State);
+ return _container != null && ContainerHasBeenCreatedStates.HasFlag(State);
}
}
}
diff --git a/src/Testcontainers/Containers/IDatabaseContainer.cs b/src/Testcontainers/Containers/IDatabaseContainer.cs
new file mode 100644
index 000000000..8a97e6766
--- /dev/null
+++ b/src/Testcontainers/Containers/IDatabaseContainer.cs
@@ -0,0 +1,18 @@
+namespace DotNet.Testcontainers.Containers
+{
+ using JetBrains.Annotations;
+
+ ///
+ /// Represents a database container instance that can be accessed with an ADO.NET provider.
+ ///
+ [PublicAPI]
+ public interface IDatabaseContainer
+ {
+ ///
+ /// Gets the database connection string.
+ ///
+ /// The database connection string.
+ [NotNull]
+ string GetConnectionString();
+ }
+}
diff --git a/src/Testcontainers/Images/FutureDockerImage.cs b/src/Testcontainers/Images/FutureDockerImage.cs
index bb3b2be13..211c690b2 100644
--- a/src/Testcontainers/Images/FutureDockerImage.cs
+++ b/src/Testcontainers/Images/FutureDockerImage.cs
@@ -115,7 +115,7 @@ protected override async Task UnsafeCreateAsync(CancellationToken ct = default)
_ = await _client.BuildAsync(_configuration, ct)
.ConfigureAwait(false);
- _image = await _client.Image.ByNameAsync(_configuration.Image.FullName, ct)
+ _image = await _client.Image.ByIdAsync(_configuration.Image.FullName, ct)
.ConfigureAwait(false);
}
diff --git a/src/Testcontainers/Images/MatchImage.cs b/src/Testcontainers/Images/MatchImage.cs
index 8819cdcc7..58c5d227f 100644
--- a/src/Testcontainers/Images/MatchImage.cs
+++ b/src/Testcontainers/Images/MatchImage.cs
@@ -5,32 +5,33 @@ namespace DotNet.Testcontainers.Images
internal static class MatchImage
{
+ private static readonly char[] SlashSeparator = { '/' };
+
+ private static readonly char[] ColonSeparator = { ':' };
+
public static IImage Match(string image)
{
_ = Guard.Argument(image, nameof(image))
.NotNull()
.NotEmpty();
- var imageComponents = image
- .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+ var imageComponents = image.Split(SlashSeparator, StringSplitOptions.RemoveEmptyEntries);
+
+ var registry = string.Join("/", imageComponents.Take(imageComponents.Length - 1));
- var repository = string.Join("/", imageComponents
- .Take(imageComponents.Length - 1));
+ imageComponents = imageComponents[imageComponents.Length - 1].Split(ColonSeparator, StringSplitOptions.RemoveEmptyEntries);
- var name = imageComponents
- .Last()
- .Split(':')
- .DefaultIfEmpty(string.Empty)
- .First();
+ if (2.Equals(imageComponents.Length))
+ {
+ return new DockerImage(registry, imageComponents[0], imageComponents[1]);
+ }
- var tag = imageComponents
- .Last()
- .Split(':')
- .Skip(1)
- .DefaultIfEmpty(string.Empty)
- .First();
+ if (1.Equals(imageComponents.Length))
+ {
+ return new DockerImage(registry, imageComponents[0], string.Empty);
+ }
- return new DockerImage(repository, name, tag);
+ throw new ArgumentException("Cannot parse image: " + image, nameof(image));
}
}
}
diff --git a/tests/Testcontainers.Databases.Tests/.editorconfig b/tests/Testcontainers.Databases.Tests/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/tests/Testcontainers.Databases.Tests/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/tests/Testcontainers.Databases.Tests/DatabasesContainerTest.cs b/tests/Testcontainers.Databases.Tests/DatabasesContainerTest.cs
new file mode 100644
index 000000000..694f7b5ec
--- /dev/null
+++ b/tests/Testcontainers.Databases.Tests/DatabasesContainerTest.cs
@@ -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