Skip to content

Commit 00c1cef

Browse files
Easier fixture.
1 parent 04f2131 commit 00c1cef

14 files changed

Lines changed: 143 additions & 123 deletions

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContainer/TestDbContainer.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Data.Common;
2+
13
using DotNet.Testcontainers.Containers;
24

35
using Microsoft.EntityFrameworkCore;
@@ -9,10 +11,10 @@
911

1012
namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer;
1113

12-
public abstract class TestDbContainer<TDbContext> : IAsyncLifetime
13-
where TDbContext : TestDbContextBase, new()
14+
public abstract class TestDbContainer : IAsyncLifetime
1415
{
15-
private static readonly TimeSpan WaitTime = TimeSpan.FromSeconds(30);
16+
private readonly TimeSpan _waitTime = TimeSpan.FromSeconds(30);
17+
private readonly HashSet<string> _connected = [];
1618
protected readonly IDatabaseContainer? DbContainer;
1719

1820
protected TestDbContainer()
@@ -22,12 +24,23 @@ protected TestDbContainer()
2224

2325
protected abstract IDatabaseContainer? GetDbContainer();
2426

25-
protected virtual string GetConnectionString()
27+
protected virtual string GetConnectionString(string databaseName)
2628
{
27-
return DbContainer?.GetConnectionString() ?? string.Empty;
29+
if (DbContainer == null)
30+
{
31+
return string.Empty;
32+
}
33+
34+
var builder = new DbConnectionStringBuilder()
35+
{
36+
ConnectionString = DbContainer.GetConnectionString()
37+
};
38+
39+
builder["database"] = databaseName;
40+
return builder.ToString();
2841
}
2942

30-
protected abstract void Configure(DbContextOptionsBuilder optionsBuilder);
43+
protected abstract void Configure(DbContextOptionsBuilder optionsBuilder, string databaseName);
3144

3245
public async Task InitializeAsync()
3346
{
@@ -37,18 +50,23 @@ public async Task InitializeAsync()
3750
}
3851
}
3952

40-
public async Task<TDbContext> CreateContextAsync()
53+
public async Task<TDbContext> CreateContextAsync<TDbContext>(string databaseName)
54+
where TDbContext : TestDbContextBase, new()
4155
{
4256
var dbContext = new TDbContext
4357
{
4458
ConfigureOptions = (builder) =>
4559
{
4660
builder.UseLoggerFactory(NullLoggerFactory.Instance);
47-
Configure(builder);
61+
Configure(builder, databaseName);
4862
}
4963
};
5064

51-
await EnsureConnectedAsync(dbContext);
65+
if (_connected.Add(databaseName))
66+
{
67+
await EnsureConnectedAsync(dbContext, databaseName);
68+
}
69+
5270
try
5371
{
5472
await dbContext.Database.EnsureCreatedAsync();
@@ -61,9 +79,11 @@ public async Task<TDbContext> CreateContextAsync()
6179
return dbContext;
6280
}
6381

64-
protected virtual async Task EnsureConnectedAsync(TDbContext context)
82+
protected virtual async Task EnsureConnectedAsync<TDbContext>(TDbContext context, string databaseName)
83+
where TDbContext : TestDbContextBase
6584
{
66-
using var cts = new CancellationTokenSource(WaitTime);
85+
using var cts = new CancellationTokenSource(_waitTime);
86+
6787
while (!await context.Database.CanConnectAsync(cts.Token))
6888
{
6989
await Task.Delay(100, cts.Token);

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContainer/TestDbContainerMySql.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,53 @@
33
using Microsoft.EntityFrameworkCore;
44

55
using PhenX.EntityFrameworkCore.BulkInsert.MySql;
6-
using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext;
76

87
using Testcontainers.MySql;
98

9+
using Xunit;
10+
1011
namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer;
1112

12-
public abstract class TestDbContainerMySql<TDbContext>(string reuseId) : TestDbContainer<TDbContext>
13-
where TDbContext : TestDbContextBase, new()
13+
[CollectionDefinition(Name)]
14+
public class TestDbContainerMySqlCollection : ICollectionFixture<TestDbContainerMySql>
15+
{
16+
public const string Name = "MySql";
17+
}
18+
19+
public class TestDbContainerMySql() : TestDbContainer
1420
{
1521
protected override IDatabaseContainer? GetDbContainer()
1622
{
1723
return new MySqlBuilder()
1824
.WithCommand("--log-bin-trust-function-creators=1", "--local-infile=1", "--innodb-print-all-deadlocks=ON")
1925
.WithReuse(true)
20-
.WithLabel("reuse-id", reuseId)
26+
.WithUsername("root")
27+
.WithPassword("root")
2128
.Build();
2229
}
2330

24-
protected override string GetConnectionString()
31+
protected override string GetConnectionString(string databaseName)
2532
{
26-
return $"{base.GetConnectionString()};AllowLoadLocalInfile=true;";
33+
return $"{base.GetConnectionString(databaseName)};AllowLoadLocalInfile=true;";
2734
}
2835

29-
protected override void Configure(DbContextOptionsBuilder optionsBuilder)
36+
protected override void Configure(DbContextOptionsBuilder optionsBuilder, string databaseName)
3037
{
38+
var connectionString = GetConnectionString(databaseName);
39+
3140
optionsBuilder
32-
.UseMySql(GetConnectionString(), ServerVersion.AutoDetect(GetConnectionString()), o =>
41+
.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), o =>
3342
{
3443
o.UseNetTopologySuite();
3544
})
3645
.UseBulkInsertMySql();
3746
}
47+
48+
protected override async Task EnsureConnectedAsync<TDbContext>(TDbContext context, string databaseName)
49+
{
50+
var container = (MySqlContainer)DbContainer!;
51+
52+
await container.ExecScriptAsync($"CREATE DATABASE `{databaseName}`");
53+
await base.EnsureConnectedAsync(context, databaseName);
54+
}
3855
}

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContainer/TestDbContainerPostgreSql.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
using Microsoft.EntityFrameworkCore;
44

55
using PhenX.EntityFrameworkCore.BulkInsert.PostgreSql;
6-
using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext;
76

87
using Testcontainers.PostgreSql;
98

9+
using Xunit;
10+
1011
namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer;
1112

12-
public abstract class TestDbContainerPostgreSql<TDbContext>(string reuseId) : TestDbContainer<TDbContext>
13-
where TDbContext : TestDbContextBase, new()
13+
[CollectionDefinition(Name)]
14+
public class TestDbContainerPostgreSqlCollection : ICollectionFixture<TestDbContainerPostgreSql>
15+
{
16+
public const string Name = "PostgreSql";
17+
}
18+
19+
public class TestDbContainerPostgreSql : TestDbContainer
1420
{
1521
protected override IDatabaseContainer? GetDbContainer()
1622
{
@@ -20,17 +26,24 @@ public abstract class TestDbContainerPostgreSql<TDbContext>(string reuseId) : Te
2026
.WithDatabase("testdb")
2127
.WithUsername("testuser")
2228
.WithPassword("testpassword")
23-
.WithLabel("reuse-id", reuseId)
2429
.Build();
2530
}
2631

27-
protected override void Configure(DbContextOptionsBuilder optionsBuilder)
32+
protected override void Configure(DbContextOptionsBuilder optionsBuilder, string databaseName)
2833
{
2934
optionsBuilder
30-
.UseNpgsql(GetConnectionString(), o =>
35+
.UseNpgsql(GetConnectionString(databaseName), o =>
3136
{
3237
o.UseNetTopologySuite();
3338
})
3439
.UseBulkInsertPostgreSql();
3540
}
41+
42+
protected override async Task EnsureConnectedAsync<TDbContext>(TDbContext context, string databaseName)
43+
{
44+
var container = (PostgreSqlContainer)DbContainer!;
45+
46+
await container.ExecScriptAsync($"CREATE DATABASE \"{databaseName}\"");
47+
await base.EnsureConnectedAsync(context, databaseName);
48+
}
3649
}

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContainer/TestDbContainerSqlServer.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,44 @@
33
using Microsoft.EntityFrameworkCore;
44

55
using PhenX.EntityFrameworkCore.BulkInsert.SqlServer;
6-
using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext;
76

87
using Testcontainers.MsSql;
98

9+
using Xunit;
10+
1011
namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer;
1112

12-
public abstract class TestDbContainerSqlServer<TDbContext>(string reuseId) : TestDbContainer<TDbContext>
13-
where TDbContext : TestDbContextBase, new()
13+
[CollectionDefinition(Name)]
14+
public class TestDbContainerSqlServerCollection : ICollectionFixture<TestDbContainerSqlServer>
15+
{
16+
public const string Name = "SqlServer";
17+
}
18+
19+
public class TestDbContainerSqlServer : TestDbContainer
1420
{
1521
protected override IDatabaseContainer? GetDbContainer()
1622
{
1723
return new MsSqlBuilder()
1824
.WithImage("vibs2006/sql_server_fts") // Geo Geospatial support
1925
.WithReuse(true)
20-
.WithLabel("reuse-id", reuseId)
2126
.Build();
2227
}
2328

24-
protected override void Configure(DbContextOptionsBuilder optionsBuilder)
29+
protected override void Configure(DbContextOptionsBuilder optionsBuilder, string databaseName)
2530
{
2631
optionsBuilder
27-
.UseSqlServer(GetConnectionString(), o =>
32+
.UseSqlServer(GetConnectionString(databaseName), o =>
2833
{
2934
o.UseNetTopologySuite();
3035
})
3136
.UseBulkInsertSqlServer();
3237
}
38+
39+
protected override async Task EnsureConnectedAsync<TDbContext>(TDbContext context, string databaseName)
40+
{
41+
var container = (MsSqlContainer)DbContainer!;
42+
43+
await container.ExecScriptAsync($"CREATE DATABASE [{databaseName}]");
44+
await base.EnsureConnectedAsync(context, databaseName);
45+
}
3346
}

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContainer/TestDbContainerSqlite.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,34 @@
33
using Microsoft.EntityFrameworkCore;
44

55
using PhenX.EntityFrameworkCore.BulkInsert.Sqlite;
6-
using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext;
6+
7+
using Xunit;
78

89
namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer;
910

10-
public abstract class TestDbContainerSqlite<TDbContext> : TestDbContainer<TDbContext>
11-
where TDbContext : TestDbContextBase, new()
11+
[CollectionDefinition(Name)]
12+
public class TestDbContainerSqliteCollection : ICollectionFixture<TestDbContainerSqlite>
13+
{
14+
public const string Name = "Sqlite";
15+
}
16+
17+
public class TestDbContainerSqlite : TestDbContainer
1218
{
1319
protected override IDatabaseContainer? GetDbContainer() => null;
1420

15-
protected override string GetConnectionString()
21+
protected override string GetConnectionString(string databaseName)
1622
{
17-
// return "Data Source=:memory:;Mode=Memory;Cache=Shared";
1823
return $"Data Source={Guid.NewGuid()}.db";
1924
}
2025

21-
protected override void Configure(DbContextOptionsBuilder optionsBuilder)
26+
protected override void Configure(DbContextOptionsBuilder optionsBuilder, string databaseName)
2227
{
2328
optionsBuilder
24-
.UseSqlite(GetConnectionString())
29+
.UseSqlite(GetConnectionString(databaseName))
2530
.UseBulkInsertSqlite();
2631
}
2732

28-
protected override Task EnsureConnectedAsync(TDbContext context)
33+
protected override Task EnsureConnectedAsync<TDbContext>(TDbContext context, string databaseName)
2934
{
3035
return Task.CompletedTask;
3136
}

0 commit comments

Comments
 (0)