Skip to content

Commit

Permalink
Add support for tests with postgres testcontainer
Browse files Browse the repository at this point in the history
  • Loading branch information
aeshub committed Jan 17, 2025
1 parent b0b9241 commit 06ca867
Show file tree
Hide file tree
Showing 16 changed files with 112 additions and 66 deletions.
14 changes: 8 additions & 6 deletions backend/api.test/Controllers/AreaControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,40 @@
using Api.Services;
using Api.Test.Database;
using Microsoft.Extensions.DependencyInjection;
using Testcontainers.PostgreSql;
using Xunit;

namespace Api.Test.Controllers
{
public class AreaControllerTests : IAsyncLifetime
{
public required DatabaseUtilities DatabaseUtilities;
public required PostgreSqlContainer Container;
public required HttpClient Client;
public required JsonSerializerOptions SerializerOptions;

public required IAreaService AreaService;

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<IAreaService>();
}

public Task DisposeAsync() => Task.CompletedTask;
public async Task DisposeAsync() => await Container.DisposeAsync();

[Fact]
public async Task CheckThatAreaIsCorrectlyCreatedThroughEndpoint()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}

Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Controllers/InspectionAreaControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ 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);

Client = TestSetupHelpers.ConfigureHttpClient(factory);
SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions();

DatabaseUtilities = new DatabaseUtilities(
TestSetupHelpers.ConfigureFlotillaDbContext(connectionString)
TestSetupHelpers.ConfigureSqLiteContext(connectionString)
);

InspectionAreaService = serviceProvider.GetRequiredService<IInspectionAreaService>();
Expand Down
5 changes: 2 additions & 3 deletions backend/api.test/Controllers/InstallationControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,16 @@ 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);

Client = TestSetupHelpers.ConfigureHttpClient(factory);
SerializerOptions = TestSetupHelpers.ConfigureJsonSerializerOptions();

DatabaseUtilities = new DatabaseUtilities(
TestSetupHelpers.ConfigureFlotillaDbContext(connectionString)
TestSetupHelpers.ConfigureSqLiteContext(connectionString)
);
MissionDefinitionService =
serviceProvider.GetRequiredService<IMissionDefinitionService>();
Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Controllers/PlantControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IPlantService>();
Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Controllers/RobotControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}

Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Controllers/RoleAccessTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -35,7 +34,7 @@ public async Task InitializeAsync()
serviceProvider.GetService<IHttpContextAccessor>()!;

DatabaseUtilities = new DatabaseUtilities(
TestSetupHelpers.ConfigureFlotillaDbContext(connectionString)
TestSetupHelpers.ConfigureSqLiteContext(connectionString)
);
}

Expand Down
10 changes: 5 additions & 5 deletions backend/api.test/Database/DatabaseUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions backend/api.test/EventHandlers/TestMissionEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -66,7 +66,7 @@ async ValueTask IAsyncDisposable.DisposeAsync()

private FlotillaDbContext CreateContext()
{
return TestSetupHelpers.ConfigureFlotillaDbContext(ConnectionString);
return TestSetupHelpers.ConfigureSqLiteContext(ConnectionString);
}

[Fact]
Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Services/MissionRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IMissionRunService>();
}
Expand Down
7 changes: 3 additions & 4 deletions backend/api.test/Services/RobotService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IRobotService>();
Expand Down
42 changes: 37 additions & 5 deletions backend/api.test/TestSetupHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@
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
{
DataSource = $"file:{databaseName}?mode=memory",
Cache = SqliteCacheMode.Shared,
}.ToString();

var context = ConfigureFlotillaDbContext(connectionString);
var context = ConfigureSqLiteContext(connectionString);
await context.Database.EnsureCreatedAsync();

var connection = context.Database.GetDbConnection();
Expand All @@ -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
Expand All @@ -47,7 +67,7 @@ TestWebApplicationFactory<Program> factory
return factory.Services;
}

public static FlotillaDbContext ConfigureFlotillaDbContext(string connectionString)
public static FlotillaDbContext ConfigureSqLiteContext(string connectionString)
{
var optionsBuilder = new DbContextOptionsBuilder<FlotillaDbContext>();
optionsBuilder.EnableSensitiveDataLogging();
Expand All @@ -57,11 +77,23 @@ public static FlotillaDbContext ConfigureFlotillaDbContext(string connectionStri
return context;
}

public static FlotillaDbContext ConfigurePostgreSqlContext(string connectionString)
{
var optionsBuilder = new DbContextOptionsBuilder<FlotillaDbContext>();
optionsBuilder.UseNpgsql(
connectionString,
o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery)
);
var context = new FlotillaDbContext(optionsBuilder.Options);
return context;
}

public static TestWebApplicationFactory<Program> ConfigureWebApplicationFactory(
string databaseName
string? databaseName = null,
string? postgreSqlConnectionString = null
)
{
return new TestWebApplicationFactory<Program>(databaseName);
return new TestWebApplicationFactory<Program>(databaseName, postgreSqlConnectionString);
}

public static HttpClient ConfigureHttpClient(TestWebApplicationFactory<Program> factory)
Expand Down
44 changes: 32 additions & 12 deletions backend/api.test/TestWebApplicationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@

namespace Api.Test
{
public class TestWebApplicationFactory<TProgram>(string databaseName)
: WebApplicationFactory<Program>
public class TestWebApplicationFactory<TProgram>(
string? sqLiteDatabaseName = null,
string? postgresConnectionString = null
) : WebApplicationFactory<Program>
where TProgram : class
{
public IConfiguration? Configuration;
Expand All @@ -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<FlotillaDbContext>(options =>
options.UseSqlite(
sqlLiteConnectionString,
o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery)
)
);
services.AddDbContext<FlotillaDbContext>(options =>
options.UseSqlite(
sqlLiteConnectionString,
o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery)
)
);
}
else if (postgresConnectionString != null)
{
services.AddDbContext<FlotillaDbContext>(
options =>
options.UseNpgsql(
postgresConnectionString,
o =>
{
o.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery);
o.EnableRetryOnFailure();
}
),
ServiceLifetime.Transient
);
}

services.AddScoped<IAccessRoleService, AccessRoleService>();
services.AddScoped<IIsarService, MockIsarService>();
Expand Down
Loading

0 comments on commit 06ca867

Please sign in to comment.