Skip to content

Commit 38da0b6

Browse files
Use one container with named databases and fix connection string issues
1 parent d3d2706 commit 38da0b6

File tree

1 file changed

+63
-52
lines changed

1 file changed

+63
-52
lines changed
Lines changed: 63 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using EPiServer.Data;
2-
using EPiServer.Framework;
1+
using EPiServer.Framework;
32
using EPiServer.Framework.Initialization;
3+
using Mediachase.Data.Provider;
44
using Microsoft.AspNetCore.Hosting;
5+
using Microsoft.Data.SqlClient;
56
using Microsoft.Extensions.Configuration;
67
using Microsoft.Extensions.DependencyInjection;
78
using Microsoft.Extensions.Hosting;
@@ -14,61 +15,53 @@ public class OptimizelyIntegrationTestBase(bool includeCommerce) : IAsyncLifetim
1415
{
1516
private IHost _host = null!;
1617

17-
private MsSqlContainer _cmsDbContainer = null!;
18+
// Since we use same container with different db names we can remove one of these :P
19+
private MsSqlContainer _databaseContainer = null!;
1820

19-
private MsSqlContainer _commerceDbContainer = null!;
20-
2121
protected IServiceProvider Services { get; private set; } = null!;
22-
22+
2323
public virtual async Task InitializeAsync()
2424
{
2525
// Create Cms SQL Server container
26-
_cmsDbContainer = CreateNamedSqlContainer( "Cms");
26+
var container = await CreateDatabaseContainer();
2727

28-
// Create Commerce SQL Server container
29-
if (includeCommerce)
30-
{
31-
_commerceDbContainer = CreateNamedSqlContainer("Commerce");
32-
}
33-
34-
// Start database containers
35-
await _cmsDbContainer.StartAsync();
28+
// Create CMS databse
29+
var cmsDatabaseConnectionString = await CreateNamedDatabaseConnectionString(container, "Cms");
3630

31+
string? commerceDatabaseConnectionString = null;
3732
if (includeCommerce)
3833
{
39-
await _commerceDbContainer.StartAsync();
34+
commerceDatabaseConnectionString = await CreateNamedDatabaseConnectionString(container, "Commerce");
4035
}
41-
36+
37+
4238
// Build CMS host
4339
_host = Host.CreateDefaultBuilder()
44-
.ConfigureCmsDefaults()
45-
.ConfigureWebHostDefaults(webHostBuilder =>
40+
.ConfigureWebHostDefaults(webHostBuilder =>
4641
{
47-
webHostBuilder.ConfigureServices((context, services) =>
48-
{
49-
services.Configure<DataAccessOptions>(opt =>
42+
webHostBuilder
43+
.ConfigureServices((context, services) =>
5044
{
51-
var containerConnectionString = _cmsDbContainer.GetConnectionString();
52-
53-
opt.SetConnectionString(containerConnectionString);
54-
});
55-
56-
// Add data importer service to setup default content for the tests
57-
services.AddTransient<OptimizelyDataImporter>();
58-
});
59-
60-
webHostBuilder.ConfigureAppConfiguration((context, configBuilder) =>
61-
{
62-
var testSettings = new Dictionary<string, string?>
45+
// Add data importer service to setup default content for the tests
46+
services.AddTransient<OptimizelyDataImporter>();
47+
})
48+
.ConfigureAppConfiguration((context, configBuilder) =>
6349
{
64-
// TODO: Find Constant for connection string!
65-
["ConnectionStrings:EcfSqlConnection"] = _commerceDbContainer.GetConnectionString()
66-
};
67-
68-
configBuilder.AddInMemoryCollection(testSettings);
69-
});
50+
// Workaround to set separate database names inisde container
51+
if (includeCommerce && !string.IsNullOrWhiteSpace(commerceDatabaseConnectionString))
52+
{
53+
var testSettings = new Dictionary<string, string?>
54+
{
55+
// TODO: Find Constant for connection string!
56+
["ConnectionStrings:EPiServerDB"] = cmsDatabaseConnectionString,
57+
["ConnectionStrings:EcfSqlConnection"] = commerceDatabaseConnectionString,
58+
};
7059

71-
if (includeCommerce)
60+
configBuilder.AddInMemoryCollection(testSettings);
61+
}
62+
});
63+
64+
if (includeCommerce && !string.IsNullOrWhiteSpace(commerceDatabaseConnectionString))
7265
{
7366
webHostBuilder.UseStartup<StartupWithCmsAndCommerce>();
7467
}
@@ -78,9 +71,13 @@ public virtual async Task InitializeAsync()
7871
}
7972

8073
})
81-
.Build();
74+
.ConfigureCmsDefaults()
75+
.Build();
76+
77+
// Run initialization engine (simulate application startup)
8278

83-
// Run initialization engine (simulate application startup)
79+
// TODO: Runs all initializable modules even if commerce is not included!
80+
// Solve with custom IAssemblyScanner?
8481
var initializer = _host.Services.GetRequiredService<InitializationEngine>();
8582
if (initializer.InitializationState != InitializationState.Initialized)
8683
initializer.Initialize();
@@ -94,20 +91,34 @@ public async Task DisposeAsync()
9491
{
9592
await _host.StopAsync();
9693

97-
await _cmsDbContainer.DisposeAsync();
98-
99-
if (includeCommerce)
100-
{
101-
await _commerceDbContainer.DisposeAsync();
102-
}
94+
await _databaseContainer.DisposeAsync();
10395
}
10496

105-
private MsSqlContainer CreateNamedSqlContainer(string componentName)
97+
private async Task<MsSqlContainer> CreateDatabaseContainer()
10698
{
107-
return new MsSqlBuilder()
108-
.WithName(componentName + GetType()) // Unique name per test class and component
99+
var container = new MsSqlBuilder()
109100
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
110101
.WithPassword("yourStrong(!)Password")
111102
.Build();
103+
104+
await container.StartAsync();
105+
106+
_databaseContainer = container;
107+
108+
return _databaseContainer;
109+
}
110+
111+
private async Task<string> CreateNamedDatabaseConnectionString(MsSqlContainer container, string databaseName)
112+
{
113+
databaseName = $"{GetType().Name}-{databaseName}";
114+
115+
var masterConnectionString = container.GetConnectionString();
116+
await using var connection = new SqlConnection(masterConnectionString);
117+
await connection.OpenAsync();
118+
await using var command = new SqlCommand($"CREATE DATABASE [{databaseName}]", connection);
119+
await command.ExecuteNonQueryAsync();
120+
121+
// Workaround to set separate database names inside container
122+
return masterConnectionString.Replace("master", databaseName);
112123
}
113124
}

0 commit comments

Comments
 (0)