Skip to content

Commit e418536

Browse files
authored
(#239) IAsyncLifetime support for PgSQL live tests (#242)
1 parent f30aa6c commit e418536

File tree

5 files changed

+58
-43
lines changed

5 files changed

+58
-43
lines changed

tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs

+21-15
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,45 @@
77
using Microsoft.EntityFrameworkCore;
88
using Xunit.Abstractions;
99

10+
#pragma warning disable CS9113 // Parameter is unread.
11+
1012
namespace CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test;
1113

1214
[ExcludeFromCodeCoverage]
1315
[Collection("LiveTestsCollection")]
14-
public class PgEntityTableRepository_Tests : RepositoryTests<PgEntityMovie>
16+
public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests<PgEntityMovie>, IAsyncLifetime
1517
{
1618
#region Setup
17-
private readonly DatabaseFixture _fixture;
1819
private readonly Random random = new();
19-
private readonly string connectionString;
20-
private readonly List<PgEntityMovie> movies;
21-
private readonly Lazy<PgDbContext> _context;
20+
private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING");
21+
private List<PgEntityMovie> movies = [];
2222

23-
public PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base()
23+
public async Task InitializeAsync()
2424
{
25-
this._fixture = fixture;
26-
this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING");
2725
if (!string.IsNullOrEmpty(this.connectionString))
2826
{
29-
this._context = new Lazy<PgDbContext>(() => PgDbContext.CreateContext(this.connectionString, output));
30-
this.movies = Context.Movies.AsNoTracking().ToList();
27+
Context = await PgDbContext.CreateContextAsync(this.connectionString, output);
28+
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
29+
}
30+
}
31+
32+
public async Task DisposeAsync()
33+
{
34+
if (Context is not null)
35+
{
36+
await Context.DisposeAsync();
3137
}
3238
}
3339

34-
private PgDbContext Context { get => this._context.Value; }
40+
private PgDbContext Context { get; set; }
3541

3642
protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString);
3743

38-
protected override Task<PgEntityMovie> GetEntityAsync(string id)
39-
=> Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(m => m.Id == id));
44+
protected override async Task<PgEntityMovie> GetEntityAsync(string id)
45+
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
4046

41-
protected override Task<int> GetEntityCountAsync()
42-
=> Task.FromResult(Context.Movies.Count());
47+
protected override async Task<int> GetEntityCountAsync()
48+
=> await Context.Movies.CountAsync();
4349

4450
protected override Task<IRepository<PgEntityMovie>> GetPopulatedRepositoryAsync()
4551
=> Task.FromResult<IRepository<PgEntityMovie>>(new EntityTableRepository<PgEntityMovie>(Context));

tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public async Task InitializeAsync()
2626
// Note: we don't clear entities on every run to speed up the test runs. This can only be done because
2727
// the tests are read-only (associated with the query and get capabilities). If the test being run writes
2828
// to the database then change clearEntities to true.
29-
output.WriteLine($"CosmosIsInitialized = {fixture.AzureSqlIsInitialized}");
29+
output.WriteLine($"AzureSqlIsInitialized = {fixture.AzureSqlIsInitialized}");
3030
Context = await AzureSqlDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.AzureSqlIsInitialized);
3131
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
3232
fixture.AzureSqlIsInitialized = true;

tests/CommunityToolkit.Datasync.Server.Test/Live/MySQL_Controller_Tests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public async Task InitializeAsync()
2727
// Note: we don't clear entities on every run to speed up the test runs. This can only be done because
2828
// the tests are read-only (associated with the query and get capabilities). If the test being run writes
2929
// to the database then change clearEntities to true.
30-
output.WriteLine($"CosmosIsInitialized = {fixture.MysqlIsInitialized}");
30+
output.WriteLine($"MysqlIsInitialized = {fixture.MysqlIsInitialized}");
3131
Context = await MysqlDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.MysqlIsInitialized);
3232
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
3333
fixture.MysqlIsInitialized = true;

tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs

+22-14
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,32 @@ namespace CommunityToolkit.Datasync.Server.Test.Live;
1212

1313
[ExcludeFromCodeCoverage]
1414
[Collection("LiveTestsCollection")]
15-
public class PgSQL_Controller_Tests : LiveControllerTests<PgEntityMovie>
15+
public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests<PgEntityMovie>, IAsyncLifetime
1616
{
1717
#region Setup
18-
private readonly DatabaseFixture _fixture;
1918
private readonly Random random = new();
20-
private readonly string connectionString;
21-
private readonly List<PgEntityMovie> movies;
19+
private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING");
20+
private List<PgEntityMovie> movies = [];
2221

23-
public PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base()
22+
public async Task InitializeAsync()
2423
{
25-
this._fixture = fixture;
26-
this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING");
2724
if (!string.IsNullOrEmpty(this.connectionString))
2825
{
29-
output.WriteLine($"PgIsInitialized = {this._fixture.PgIsInitialized}");
30-
Context = PgDbContext.CreateContext(this.connectionString, output, clearEntities: !this._fixture.PgIsInitialized);
26+
// Note: we don't clear entities on every run to speed up the test runs. This can only be done because
27+
// the tests are read-only (associated with the query and get capabilities). If the test being run writes
28+
// to the database then change clearEntities to true.
29+
output.WriteLine($"PgIsInitialized = {fixture.PgIsInitialized}");
30+
Context = await PgDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.PgIsInitialized);
3131
this.movies = Context.Movies.AsNoTracking().ToList();
32-
this._fixture.PgIsInitialized = true;
32+
fixture.PgIsInitialized = true;
33+
}
34+
}
35+
36+
public async Task DisposeAsync()
37+
{
38+
if (Context is not null)
39+
{
40+
await Context.DisposeAsync();
3341
}
3442
}
3543

@@ -39,11 +47,11 @@ public PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output)
3947

4048
protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString);
4149

42-
protected override Task<PgEntityMovie> GetEntityAsync(string id)
43-
=> Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(m => m.Id == id));
50+
protected override async Task<PgEntityMovie> GetEntityAsync(string id)
51+
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
4452

45-
protected override Task<int> GetEntityCountAsync()
46-
=> Task.FromResult(Context.Movies.Count());
53+
protected override async Task<int> GetEntityCountAsync()
54+
=> await Context.Movies.CountAsync();
4755

4856
protected override Task<IRepository<PgEntityMovie>> GetPopulatedRepositoryAsync()
4957
=> Task.FromResult<IRepository<PgEntityMovie>>(new EntityTableRepository<PgEntityMovie>(Context));

tests/CommunityToolkit.Datasync.TestCommon/Databases/Postgresql/PgDbContext.cs

+13-12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace CommunityToolkit.Datasync.TestCommon.Databases;
1010
[ExcludeFromCodeCoverage]
1111
public class PgDbContext(DbContextOptions<PgDbContext> options) : BaseDbContext<PgDbContext, PgEntityMovie>(options)
1212
{
13-
public static PgDbContext CreateContext(string connectionString, ITestOutputHelper output = null, bool clearEntities = true)
13+
public static async Task<PgDbContext> CreateContextAsync(string connectionString, ITestOutputHelper output = null, bool clearEntities = true)
1414
{
1515
if (string.IsNullOrEmpty(connectionString))
1616
{
@@ -22,36 +22,37 @@ public static PgDbContext CreateContext(string connectionString, ITestOutputHelp
2222
.EnableLogging(output);
2323
PgDbContext context = new(optionsBuilder.Options);
2424

25-
context.InitializeDatabase(clearEntities);
26-
context.PopulateDatabase();
25+
await context.InitializeDatabaseAsync(clearEntities);
26+
await context.PopulateDatabaseAsync();
2727
return context;
2828
}
2929

30-
internal void InitializeDatabase(bool clearEntities)
30+
internal async Task InitializeDatabaseAsync(bool clearEntities)
3131
{
32-
const string datasyncTrigger = @"
32+
const string datasyncTrigger = """
33+
3334
CREATE OR REPLACE FUNCTION {0}_datasync() RETURNS trigger AS $$
3435
BEGIN
35-
NEW.""UpdatedAt"" = NOW() AT TIME ZONE 'UTC';
36-
NEW.""Version"" = convert_to(gen_random_uuid()::text, 'UTF8');
36+
NEW."UpdatedAt" = NOW() AT TIME ZONE 'UTC';
37+
NEW."Version" = convert_to(gen_random_uuid()::text, 'UTF8');
3738
RETURN NEW;
3839
END;
3940
$$ LANGUAGE plpgsql;
4041
4142
CREATE OR REPLACE TRIGGER
4243
{0}_datasync
4344
BEFORE INSERT OR UPDATE ON
44-
""{0}""
45+
"{0}"
4546
FOR EACH ROW EXECUTE PROCEDURE
4647
{0}_datasync();
47-
";
48+
""";
4849

49-
Database.EnsureCreated();
50-
ExecuteRawSqlOnEachEntity(datasyncTrigger);
50+
await Database.EnsureCreatedAsync();
51+
await ExecuteRawSqlOnEachEntityAsync(datasyncTrigger);
5152

5253
if (clearEntities)
5354
{
54-
ExecuteRawSqlOnEachEntity(@"DELETE FROM ""{0}""");
55+
await ExecuteRawSqlOnEachEntityAsync(@"DELETE FROM ""{0}""");
5556
}
5657
}
5758

0 commit comments

Comments
 (0)