Skip to content

Commit 3d22bf5

Browse files
committed
FirebirdSql: Automatically use the UntilDatabaseIsAvailable wait strategy
If the `DbProviderFactory` is available (obtained through reflection).
1 parent aa2d3a9 commit 3d22bf5

File tree

12 files changed

+102
-25
lines changed

12 files changed

+102
-25
lines changed

.github/workflows/cicd.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ jobs:
5656
{ name: "Testcontainers.EventHubs", runs-on: "ubuntu-22.04" },
5757
{ name: "Testcontainers.FakeGcsServer", runs-on: "ubuntu-22.04" },
5858
{ name: "Testcontainers.FirebirdSql", runs-on: "ubuntu-22.04" },
59+
{ name: "Testcontainers.FirebirdSql.AdoNetClient", runs-on: "ubuntu-22.04" },
5960
{ name: "Testcontainers.Firestore", runs-on: "ubuntu-22.04" },
6061
{ name: "Testcontainers.InfluxDb", runs-on: "ubuntu-22.04" },
6162
{ name: "Testcontainers.JanusGraph", runs-on: "ubuntu-22.04" },

Testcontainers.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.FakeGcsServe
161161
EndProject
162162
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.FirebirdSql.Tests", "tests\Testcontainers.FirebirdSql.Tests\Testcontainers.FirebirdSql.Tests.csproj", "{E39095AC-9B34-4178-A486-04C902B6FD33}"
163163
EndProject
164+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.FirebirdSql.AdoNetClient.Tests", "tests\Testcontainers.FirebirdSql.AdoNetClient.Tests\Testcontainers.FirebirdSql.AdoNetClient.Tests.csproj", "{C23EE831-F23B-4829-819B-A3F92D89CEDA}"
165+
EndProject
164166
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Firestore.Tests", "tests\Testcontainers.Firestore.Tests\Testcontainers.Firestore.Tests.csproj", "{2F0D7CD6-7EA9-46FC-B8F2-25D55699525F}"
165167
EndProject
166168
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.InfluxDb.Tests", "tests\Testcontainers.InfluxDb.Tests\Testcontainers.InfluxDb.Tests.csproj", "{B45B0EF2-5852-4ED3-904A-8FC62A3253D7}"
@@ -544,6 +546,10 @@ Global
544546
{E39095AC-9B34-4178-A486-04C902B6FD33}.Debug|Any CPU.Build.0 = Debug|Any CPU
545547
{E39095AC-9B34-4178-A486-04C902B6FD33}.Release|Any CPU.ActiveCfg = Release|Any CPU
546548
{E39095AC-9B34-4178-A486-04C902B6FD33}.Release|Any CPU.Build.0 = Release|Any CPU
549+
{C23EE831-F23B-4829-819B-A3F92D89CEDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
550+
{C23EE831-F23B-4829-819B-A3F92D89CEDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
551+
{C23EE831-F23B-4829-819B-A3F92D89CEDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
552+
{C23EE831-F23B-4829-819B-A3F92D89CEDA}.Release|Any CPU.Build.0 = Release|Any CPU
547553
{2F0D7CD6-7EA9-46FC-B8F2-25D55699525F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
548554
{2F0D7CD6-7EA9-46FC-B8F2-25D55699525F}.Debug|Any CPU.Build.0 = Debug|Any CPU
549555
{2F0D7CD6-7EA9-46FC-B8F2-25D55699525F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -815,5 +821,6 @@ Global
815821
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
816822
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
817823
{E901DF14-6F05-4FC2-825A-3055FAD33561} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
824+
{C23EE831-F23B-4829-819B-A3F92D89CEDA} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
818825
EndGlobalSection
819826
EndGlobal

src/Testcontainers.FirebirdSql/FirebirdSqlBuilder.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,28 @@ protected override FirebirdSqlBuilder Init()
9191
.WithUsername(DefaultUsername)
9292
.WithPassword(DefaultPassword)
9393
.WithResourceMapping(Encoding.Default.GetBytes(TestQueryString), "/home/firebird_check.sql")
94-
.WithWaitStrategy(Wait.ForUnixContainer().UntilContainerIsHealthy());
94+
.WithWaitStrategy(GetDefaultWaitStrategy(Wait.ForUnixContainer()));
95+
}
96+
97+
private static IWaitForContainerOS GetDefaultWaitStrategy(IWaitForContainerOS waitStrategy)
98+
{
99+
return TryGetDbProviderFactory("FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient, PublicKeyToken=3750abcc3150b00c", out var dbProviderFactory)
100+
? waitStrategy.UntilDatabaseIsAvailable(dbProviderFactory)
101+
: waitStrategy.UntilContainerIsHealthy();
102+
}
103+
104+
private static bool TryGetDbProviderFactory(string factoryTypeName, out DbProviderFactory dbProviderFactory)
105+
{
106+
try
107+
{
108+
dbProviderFactory = (DbProviderFactory)Type.GetType(factoryTypeName)?.GetField("Instance")?.GetValue(null);
109+
return dbProviderFactory != null;
110+
}
111+
catch
112+
{
113+
dbProviderFactory = null;
114+
return false;
115+
}
95116
}
96117

97118
/// <inheritdoc />

src/Testcontainers.FirebirdSql/Usings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
global using System;
22
global using System.Collections.Generic;
3+
global using System.Data.Common;
34
global using System.IO;
45
global using System.Linq;
56
global using System.Text;

tests/Testcontainers.Databases.Tests/DatabasesContainerTest.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ public void ShouldNotImplementIDatabaseContainer(Type type)
1818

1919
public static TheoryData<Type> GetContainerImplementations(bool expectDataProvider)
2020
{
21-
var theoryData = new TheoryData<Type>();
22-
2321
var testAssemblies = Directory.GetFiles(".", "Testcontainers.*.Tests.dll", SearchOption.TopDirectoryOnly)
2422
.Where(fileName => !fileName.Contains("Testcontainers.Xunit.Tests"))
2523
.Select(Path.GetFullPath)
@@ -35,6 +33,9 @@ public static TheoryData<Type> GetContainerImplementations(bool expectDataProvid
3533
.SelectMany(referencedAssembly => referencedAssembly.ExportedTypes)
3634
.ToImmutableList());
3735

36+
var containerTypes = new HashSet<Type>();
37+
var dbContainerTypes = new HashSet<Type>();
38+
3839
foreach (var testAssembly in testAssemblies)
3940
{
4041
// TODO: If a module contains multiple container implementations, it would require all container implementations to implement the interface.
@@ -55,18 +56,19 @@ public static TheoryData<Type> GetContainerImplementations(bool expectDataProvid
5556

5657
var hasDataProvider = testAssembly.Value.Exists(type => type.IsSubclassOf(typeof(DbProviderFactory)));
5758

58-
if (expectDataProvider && hasDataProvider)
59+
if (hasDataProvider)
5960
{
60-
theoryData.Add(containerType);
61+
dbContainerTypes.Add(containerType);
6162
}
62-
63-
if (!expectDataProvider && !hasDataProvider)
63+
else
6464
{
65-
theoryData.Add(containerType);
65+
containerTypes.Add(containerType);
6666
}
6767
}
6868
}
6969

70+
var theoryData = new TheoryData<Type>();
71+
theoryData.AddRange((expectDataProvider ? dbContainerTypes : containerTypes.Except(dbContainerTypes)).ToArray());
7072
return theoryData;
7173
}
7274
}

tests/Testcontainers.Databases.Tests/Usings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
global using System;
2+
global using System.Collections.Generic;
23
global using System.Collections.Immutable;
34
global using System.Data.Common;
45
global using System.IO;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
root = true
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>net9.0</TargetFrameworks>
4+
<IsPackable>false</IsPackable>
5+
<IsPublishable>false</IsPublishable>
6+
<DefineConstants>$(DefineConstants);ADONET_CLIENT</DefineConstants>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
10+
<PackageReference Include="coverlet.collector"/>
11+
<PackageReference Include="ReflectionMagic"/>
12+
<PackageReference Include="xunit.runner.visualstudio"/>
13+
<PackageReference Include="xunit"/>
14+
<PackageReference Include="FirebirdSql.Data.FirebirdClient"/>
15+
</ItemGroup>
16+
<ItemGroup>
17+
<ProjectReference Include="../../src/Testcontainers.FirebirdSql/Testcontainers.FirebirdSql.csproj"/>
18+
<ProjectReference Include="../../src/Testcontainers.Xunit/Testcontainers.Xunit.csproj"/>
19+
<ProjectReference Include="../Testcontainers.Commons/Testcontainers.Commons.csproj"/>
20+
</ItemGroup>
21+
<ItemGroup>
22+
<Compile Include="../Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs" />
23+
</ItemGroup>
24+
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
global using System.Data;
2+
global using System.Data.Common;
3+
global using System.Linq;
4+
global using System.Threading.Tasks;
5+
global using DotNet.Testcontainers.Commons;
6+
global using DotNet.Testcontainers.Configurations;
7+
global using FirebirdSql.Data.FirebirdClient;
8+
global using JetBrains.Annotations;
9+
global using ReflectionMagic;
10+
global using Testcontainers.Xunit;
11+
global using Xunit;
12+
global using Xunit.Abstractions;

tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace Testcontainers.FirebirdSql;
22

33
public abstract class FirebirdSqlContainerTest(FirebirdSqlContainerTest.FirebirdSqlDefaultFixture fixture)
44
{
5+
#if ADONET_CLIENT
56
[Fact]
67
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
78
public void ConnectionStateReturnsOpen()
@@ -15,6 +16,20 @@ public void ConnectionStateReturnsOpen()
1516
// Then
1617
Assert.Equal(ConnectionState.Open, connection.State);
1718
}
19+
#endif
20+
21+
[Fact]
22+
public void WaitStrategyUsed()
23+
{
24+
FirebirdSqlConfiguration configuration = fixture.Container.AsDynamic()._configuration;
25+
var waitStrategy = configuration.WaitStrategies.Last();
26+
IWaitUntil waitUntil = DynamicHelper.Unwrap(waitStrategy.AsDynamic()._waitUntil);
27+
#if ADONET_CLIENT
28+
Assert.Equal("UntilDatabaseIsAvailable", waitUntil.GetType().Name);
29+
#else
30+
Assert.Equal("UntilContainerIsHealthy", waitUntil.GetType().Name);
31+
#endif
32+
}
1833

1934
[Fact]
2035
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
@@ -32,20 +47,17 @@ public async Task ExecScriptReturnsSuccessful()
3247
Assert.Empty(execResult.Stderr);
3348
}
3449

50+
#if ADONET_CLIENT
3551
public class FirebirdSqlDefaultFixture(IMessageSink messageSink)
3652
: DbContainerFixture<FirebirdSqlBuilder, FirebirdSqlContainer>(messageSink)
3753
{
3854
public override DbProviderFactory DbProviderFactory
3955
=> FirebirdClientFactory.Instance;
4056
}
41-
42-
[UsedImplicitly]
43-
public class FirebirdSqlWaitForDatabaseFixture(IMessageSink messageSink)
44-
: FirebirdSqlDefaultFixture(messageSink)
45-
{
46-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
47-
=> builder.WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
48-
}
57+
#else
58+
public class FirebirdSqlDefaultFixture(IMessageSink messageSink)
59+
: ContainerFixture<FirebirdSqlBuilder, FirebirdSqlContainer>(messageSink);
60+
#endif
4961

5062
[UsedImplicitly]
5163
public class FirebirdSql25ScFixture(IMessageSink messageSink)
@@ -83,10 +95,6 @@ protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
8395
public sealed class FirebirdSqlDefaultConfiguration(FirebirdSqlDefaultFixture fixture)
8496
: FirebirdSqlContainerTest(fixture), IClassFixture<FirebirdSqlDefaultFixture>;
8597

86-
[UsedImplicitly]
87-
public sealed class FirebirdSqlWaitForDatabaseConfiguration(FirebirdSqlWaitForDatabaseFixture fixture)
88-
: FirebirdSqlContainerTest(fixture), IClassFixture<FirebirdSqlWaitForDatabaseFixture>;
89-
9098
[UsedImplicitly]
9199
public sealed class FirebirdSql25ScConfiguration(FirebirdSql25ScFixture fixture)
92100
: FirebirdSqlContainerTest(fixture), IClassFixture<FirebirdSql25ScFixture>;

0 commit comments

Comments
 (0)