diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0b136cb..4387e8e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -13,23 +13,23 @@
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
@@ -42,14 +42,14 @@
-
-
+
+
-
+
-
+
\ No newline at end of file
diff --git a/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs
index 1117904..7733496 100644
--- a/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs
+++ b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs
@@ -28,7 +28,7 @@ public abstract class ControllerTestsBase : IAsyncLifetime
protected Dictionary> contractProducts;
protected DatabaseHelper helper;
protected ITestOutputHelper TestOutputHelper;
- protected DockerHelper DockerHelper;
+ protected Int32 SqlPort;
protected static void AssertDecimalMatchesTo4Places(decimal actual, decimal expected)
{
@@ -38,16 +38,10 @@ protected static void AssertDecimalMatchesTo4Places(decimal actual, decimal expe
public virtual async ValueTask InitializeAsync()
{
- this.TestId = Guid.NewGuid();
- String scenarioName = this.TestId.ToString();
- NlogLogger logger = new NlogLogger();
- logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName);
- LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly);
+ IntegrationTestEnvironment environment = await IntegrationTestEnvironment.GetAsync();
+ this.SqlPort = environment.SqlPort;
- this.DockerHelper = new TestDockerHelper();
- this.DockerHelper.Logger = logger;
-
- await this.DockerHelper.StartContainersForScenarioRun(scenarioName, DockerServices.SqlServer);
+ this.TestId = Guid.NewGuid();
String dbConnString = GetLocalConnectionString($"TransactionProcessorReadModel-{this.TestId}");
@@ -61,10 +55,7 @@ public virtual async ValueTask InitializeAsync()
await this.SetupStandingData();
}
- public virtual async ValueTask DisposeAsync()
- {
- await this.DockerHelper.StopContainersForScenarioRun(DockerServices.None);
- }
+ public virtual ValueTask DisposeAsync() => default;
protected EstateManagementContext context;
@@ -112,10 +103,7 @@ public virtual async ValueTask DisposeAsync()
public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!");
public String GetLocalConnectionString(String databaseName) {
- var dockerHelper = this.DockerHelper as TestDockerHelper;
- Int32? databaseHostPort = dockerHelper.GetSqlPort();
-
- return $"server=localhost,{databaseHostPort};database={databaseName};user id={SqlCredentials.usename};password={SqlCredentials.password};Encrypt=false";
+ return $"server=localhost,{this.SqlPort};database={databaseName};user id={SqlCredentials.usename};password={SqlCredentials.password};Encrypt=false";
}
//internal async Task StartSqlContainer(){
@@ -169,7 +157,7 @@ public override async Task CreateSubscriptions(){
}
public Int32? GetSqlPort() {
- var sqlContainer = this.Containers.SingleOrDefault(c => c.Item1 == DockerServices.SqlServer);
+ var sqlContainer = this.Containers.FirstOrDefault(c => c.Item1 == DockerServices.SqlServer);
if (sqlContainer == default) {
return null;
}
diff --git a/EstateReportingAPI.IntegrationTests/IntegrationTestEnvironment.cs b/EstateReportingAPI.IntegrationTests/IntegrationTestEnvironment.cs
new file mode 100644
index 0000000..e84becc
--- /dev/null
+++ b/EstateReportingAPI.IntegrationTests/IntegrationTestEnvironment.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Shared.IntegrationTesting;
+using Shared.IntegrationTesting.TestContainers;
+using Shared.Logger;
+using NLog;
+
+namespace EstateReportingAPI.IntegrationTests;
+
+internal sealed class IntegrationTestEnvironment
+{
+ private static readonly SemaphoreSlim InitialisationLock = new(1, 1);
+ private static IntegrationTestEnvironment? Instance;
+
+ private IntegrationTestEnvironment(TestDockerHelper dockerHelper, int sqlPort)
+ {
+ this.DockerHelper = dockerHelper;
+ this.SqlPort = sqlPort;
+ }
+
+ public TestDockerHelper DockerHelper { get; }
+
+ public int SqlPort { get; }
+
+ public static async Task GetAsync()
+ {
+ if (Instance != null)
+ {
+ return Instance;
+ }
+
+ await InitialisationLock.WaitAsync().ConfigureAwait(false);
+ try
+ {
+ if (Instance != null)
+ {
+ return Instance;
+ }
+
+ string scenarioName = "IntegrationTests";
+ NlogLogger logger = new();
+ logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName);
+ LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly);
+
+ TestDockerHelper dockerHelper = new();
+ dockerHelper.Logger = logger;
+
+ await dockerHelper.StartContainersForScenarioRun(scenarioName, DockerServices.SqlServer);
+
+ int sqlPort = dockerHelper.GetSqlPort()
+ ?? throw new InvalidOperationException("SQL Server container did not expose port 1433.");
+
+ Instance = new IntegrationTestEnvironment(dockerHelper, sqlPort);
+ return Instance;
+ }
+ finally
+ {
+ InitialisationLock.Release();
+ }
+ }
+}