diff --git a/backend/api.test/Controllers/AreaControllerTests.cs b/backend/api.test/Controllers/AreaControllerTests.cs index f354ffe2..0c2563f8 100644 --- a/backend/api.test/Controllers/AreaControllerTests.cs +++ b/backend/api.test/Controllers/AreaControllerTests.cs @@ -9,6 +9,7 @@ using Api.Services; using Api.Test.Database; using Microsoft.Extensions.DependencyInjection; +using Testcontainers.PostgreSql; using Xunit; namespace Api.Test.Controllers @@ -16,6 +17,7 @@ namespace Api.Test.Controllers public class AreaControllerTests : IAsyncLifetime { public required DatabaseUtilities DatabaseUtilities; + public required PostgreSqlContainer Container; public required HttpClient Client; public required JsonSerializerOptions SerializerOptions; @@ -23,24 +25,24 @@ public class AreaControllerTests : IAsyncLifetime public async Task InitializeAsync() { - string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName + (Container, string connectionString, var connection) = + await TestSetupHelpers.ConfigurePostgreSqlDatabase(); + var factory = TestSetupHelpers.ConfigureWebApplicationFactory( + postgreSqlConnectionString: connectionString ); - var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); Client = TestSetupHelpers.ConfigureHttpClient(factory); SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions(); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigurePostgreSqlContext(connectionString) ); AreaService = serviceProvider.GetRequiredService(); } - public Task DisposeAsync() => Task.CompletedTask; + public async Task DisposeAsync() => await Container.DisposeAsync(); [Fact] public async Task CheckThatAreaIsCorrectlyCreatedThroughEndpoint() diff --git a/backend/api.test/Controllers/EmergencyActionControllerTests.cs b/backend/api.test/Controllers/EmergencyActionControllerTests.cs index 5977a6dc..f461f402 100644 --- a/backend/api.test/Controllers/EmergencyActionControllerTests.cs +++ b/backend/api.test/Controllers/EmergencyActionControllerTests.cs @@ -17,14 +17,13 @@ public class EmergencyActionControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); Client = TestSetupHelpers.ConfigureHttpClient(factory); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); } diff --git a/backend/api.test/Controllers/InspectionAreaControllerTests.cs b/backend/api.test/Controllers/InspectionAreaControllerTests.cs index fb82983c..e982e2f0 100644 --- a/backend/api.test/Controllers/InspectionAreaControllerTests.cs +++ b/backend/api.test/Controllers/InspectionAreaControllerTests.cs @@ -27,9 +27,8 @@ public class InspectionAreaControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); @@ -37,7 +36,7 @@ public async Task InitializeAsync() SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions(); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); InspectionAreaService = serviceProvider.GetRequiredService(); diff --git a/backend/api.test/Controllers/InstallationControllerTests.cs b/backend/api.test/Controllers/InstallationControllerTests.cs index f167dad9..755666d2 100644 --- a/backend/api.test/Controllers/InstallationControllerTests.cs +++ b/backend/api.test/Controllers/InstallationControllerTests.cs @@ -19,9 +19,8 @@ public class InstallationControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); diff --git a/backend/api.test/Controllers/MissionSchedulingControllerTests.cs b/backend/api.test/Controllers/MissionSchedulingControllerTests.cs index 1985a1b9..2e7e8a88 100644 --- a/backend/api.test/Controllers/MissionSchedulingControllerTests.cs +++ b/backend/api.test/Controllers/MissionSchedulingControllerTests.cs @@ -26,9 +26,8 @@ public class MissionSchedulingControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); @@ -36,7 +35,7 @@ public async Task InitializeAsync() SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions(); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); MissionDefinitionService = serviceProvider.GetRequiredService(); diff --git a/backend/api.test/Controllers/PlantControllerTests.cs b/backend/api.test/Controllers/PlantControllerTests.cs index 3e497222..fed4e739 100644 --- a/backend/api.test/Controllers/PlantControllerTests.cs +++ b/backend/api.test/Controllers/PlantControllerTests.cs @@ -20,15 +20,14 @@ public class PlantControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); Client = TestSetupHelpers.ConfigureHttpClient(factory); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); PlantService = serviceProvider.GetRequiredService(); diff --git a/backend/api.test/Controllers/RobotControllerTests.cs b/backend/api.test/Controllers/RobotControllerTests.cs index ba982dc0..e0726c30 100644 --- a/backend/api.test/Controllers/RobotControllerTests.cs +++ b/backend/api.test/Controllers/RobotControllerTests.cs @@ -22,16 +22,15 @@ public class RobotControllerTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); Client = TestSetupHelpers.ConfigureHttpClient(factory); SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions(); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); } diff --git a/backend/api.test/Controllers/RoleAccessTests.cs b/backend/api.test/Controllers/RoleAccessTests.cs index fbdcb050..ed9c3d96 100644 --- a/backend/api.test/Controllers/RoleAccessTests.cs +++ b/backend/api.test/Controllers/RoleAccessTests.cs @@ -23,9 +23,8 @@ public class RoleAccessTests : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); @@ -35,7 +34,7 @@ public async Task InitializeAsync() serviceProvider.GetService()!; DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); } diff --git a/backend/api.test/Database/DatabaseUtilities.cs b/backend/api.test/Database/DatabaseUtilities.cs index 7042f0e5..4eae1bcf 100644 --- a/backend/api.test/Database/DatabaseUtilities.cs +++ b/backend/api.test/Database/DatabaseUtilities.cs @@ -24,11 +24,11 @@ public class DatabaseUtilities private readonly RobotService _robotService; private readonly UserInfoService _userInfoService; private readonly SourceService _sourceService; - private readonly string _testInstallationCode = "testInstallationCode"; - private readonly string _testInstallationName = "testInstallation"; - private readonly string _testPlantCode = "testPlantCode"; - private readonly string _testInspectionAreaName = "testInspectionArea"; - private readonly string _testAreaName = "testArea"; + private readonly string _testInstallationCode = "InstCode"; + private readonly string _testInstallationName = "Installation"; + private readonly string _testPlantCode = "PlantCode"; + private readonly string _testInspectionAreaName = "InspectionArea"; + private readonly string _testAreaName = "Area"; public DatabaseUtilities(FlotillaDbContext context) { diff --git a/backend/api.test/EventHandlers/TestMissionEventHandler.cs b/backend/api.test/EventHandlers/TestMissionEventHandler.cs index d6fed515..0cb49e0c 100644 --- a/backend/api.test/EventHandlers/TestMissionEventHandler.cs +++ b/backend/api.test/EventHandlers/TestMissionEventHandler.cs @@ -37,7 +37,7 @@ public class TestMissionEventHandler : IAsyncLifetime, IAsyncDisposable public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (ConnectionString, _) = await TestSetupHelpers.ConfigureDatabase(databaseName); + (ConnectionString, _) = await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); DatabaseUtilities = new DatabaseUtilities(Context); @@ -66,7 +66,7 @@ async ValueTask IAsyncDisposable.DisposeAsync() private FlotillaDbContext CreateContext() { - return TestSetupHelpers.ConfigureFlotillaDbContext(ConnectionString); + return TestSetupHelpers.ConfigureSqLiteContext(ConnectionString); } [Fact] diff --git a/backend/api.test/Services/MissionRunService.cs b/backend/api.test/Services/MissionRunService.cs index a45457ba..613d6b3c 100644 --- a/backend/api.test/Services/MissionRunService.cs +++ b/backend/api.test/Services/MissionRunService.cs @@ -17,14 +17,13 @@ public class MissionServiceTest : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); MissionRunService = serviceProvider.GetRequiredService(); } diff --git a/backend/api.test/Services/RobotService.cs b/backend/api.test/Services/RobotService.cs index 5d26c11e..2a80d7bb 100644 --- a/backend/api.test/Services/RobotService.cs +++ b/backend/api.test/Services/RobotService.cs @@ -19,14 +19,13 @@ public class RobotServiceTest : IAsyncLifetime public async Task InitializeAsync() { string databaseName = Guid.NewGuid().ToString(); - (string connectionString, var connection) = await TestSetupHelpers.ConfigureDatabase( - databaseName - ); + (string connectionString, var connection) = + await TestSetupHelpers.ConfigureSqLiteDatabase(databaseName); var factory = TestSetupHelpers.ConfigureWebApplicationFactory(databaseName); var serviceProvider = TestSetupHelpers.ConfigureServiceProvider(factory); DatabaseUtilities = new DatabaseUtilities( - TestSetupHelpers.ConfigureFlotillaDbContext(connectionString) + TestSetupHelpers.ConfigureSqLiteContext(connectionString) ); RobotService = serviceProvider.GetRequiredService(); diff --git a/backend/api.test/TestSetupHelpers.cs b/backend/api.test/TestSetupHelpers.cs index 8c8af5a3..9a4b7308 100644 --- a/backend/api.test/TestSetupHelpers.cs +++ b/backend/api.test/TestSetupHelpers.cs @@ -9,12 +9,13 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Testcontainers.PostgreSql; namespace Api.Test; public static class TestSetupHelpers { - public static async Task<(string, DbConnection)> ConfigureDatabase(string databaseName) + public static async Task<(string, DbConnection)> ConfigureSqLiteDatabase(string databaseName) { string connectionString = new SqliteConnectionStringBuilder { @@ -22,7 +23,7 @@ public static class TestSetupHelpers Cache = SqliteCacheMode.Shared, }.ToString(); - var context = ConfigureFlotillaDbContext(connectionString); + var context = ConfigureSqLiteContext(connectionString); await context.Database.EnsureCreatedAsync(); var connection = context.Database.GetDbConnection(); @@ -31,6 +32,25 @@ public static class TestSetupHelpers return (connectionString, connection); } + public static async Task<( + PostgreSqlContainer, + string, + DbConnection + )> ConfigurePostgreSqlDatabase() + { + var container = new PostgreSqlBuilder().Build(); + await container.StartAsync(); + + string? connectionString = container.GetConnectionString(); + var context = ConfigurePostgreSqlContext(connectionString); + await context.Database.MigrateAsync(); + + var connection = context.Database.GetDbConnection(); + await connection.OpenAsync(); + + return (container, connectionString, connection); + } + public static JsonSerializerOptions ConfigureJsonSerializerOptions() { return new JsonSerializerOptions @@ -47,7 +67,7 @@ TestWebApplicationFactory factory return factory.Services; } - public static FlotillaDbContext ConfigureFlotillaDbContext(string connectionString) + public static FlotillaDbContext ConfigureSqLiteContext(string connectionString) { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.EnableSensitiveDataLogging(); @@ -57,11 +77,23 @@ public static FlotillaDbContext ConfigureFlotillaDbContext(string connectionStri return context; } + public static FlotillaDbContext ConfigurePostgreSqlContext(string connectionString) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseNpgsql( + connectionString, + o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery) + ); + var context = new FlotillaDbContext(optionsBuilder.Options); + return context; + } + public static TestWebApplicationFactory ConfigureWebApplicationFactory( - string databaseName + string? databaseName = null, + string? postgreSqlConnectionString = null ) { - return new TestWebApplicationFactory(databaseName); + return new TestWebApplicationFactory(databaseName, postgreSqlConnectionString); } public static HttpClient ConfigureHttpClient(TestWebApplicationFactory factory) diff --git a/backend/api.test/TestWebApplicationFactory.cs b/backend/api.test/TestWebApplicationFactory.cs index 1a69e57f..afcced13 100644 --- a/backend/api.test/TestWebApplicationFactory.cs +++ b/backend/api.test/TestWebApplicationFactory.cs @@ -15,8 +15,10 @@ namespace Api.Test { - public class TestWebApplicationFactory(string databaseName) - : WebApplicationFactory + public class TestWebApplicationFactory( + string? sqLiteDatabaseName = null, + string? postgresConnectionString = null + ) : WebApplicationFactory where TProgram : class { public IConfiguration? Configuration; @@ -35,18 +37,36 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) ); builder.ConfigureTestServices(services => { - string sqlLiteConnectionString = new SqliteConnectionStringBuilder + if (sqLiteDatabaseName != null) { - DataSource = $"file:{databaseName}?mode=memory", - Cache = SqliteCacheMode.Shared, - }.ToString(); + string sqlLiteConnectionString = new SqliteConnectionStringBuilder + { + DataSource = $"file:{sqLiteDatabaseName}?mode=memory", + Cache = SqliteCacheMode.Shared, + }.ToString(); - services.AddDbContext(options => - options.UseSqlite( - sqlLiteConnectionString, - o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery) - ) - ); + services.AddDbContext(options => + options.UseSqlite( + sqlLiteConnectionString, + o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery) + ) + ); + } + else if (postgresConnectionString != null) + { + services.AddDbContext( + options => + options.UseNpgsql( + postgresConnectionString, + o => + { + o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery); + o.EnableRetryOnFailure(); + } + ), + ServiceLifetime.Transient + ); + } services.AddScoped(); services.AddScoped(); diff --git a/backend/api.test/api.test.csproj b/backend/api.test/api.test.csproj index 58647026..75b7bc7a 100644 --- a/backend/api.test/api.test.csproj +++ b/backend/api.test/api.test.csproj @@ -13,6 +13,7 @@ + all diff --git a/backend/api/appsettings.Test.json b/backend/api/appsettings.Test.json index e9e96baf..865dac6c 100644 --- a/backend/api/appsettings.Test.json +++ b/backend/api/appsettings.Test.json @@ -36,6 +36,6 @@ "ShouldFailOnMaxRetries": true }, "Database": { - "UseInMemoryDatabase": true + "UseInMemoryDatabase": false } }