Skip to content

Commit f906f3d

Browse files
authored
(#237) Updated AzureSQL tests to use async (#240)
* (#237) Switched AzureSQL tests over to IAsyncLifetime to take advantage of async.
1 parent a738891 commit f906f3d

File tree

4 files changed

+61
-33
lines changed

4 files changed

+61
-33
lines changed

tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_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 AzureSqlEntityTableRepository_Tests : RepositoryTests<AzureSqlEntityMovie>
16+
public class AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests<AzureSqlEntityMovie>, 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<AzureSqlEntityMovie> movies;
21-
private readonly Lazy<AzureSqlDbContext> _context;
20+
private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING");
21+
private List<AzureSqlEntityMovie> movies = [];
2222

23-
public AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base()
23+
public async Task InitializeAsync()
2424
{
25-
this._fixture = fixture;
26-
this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING");
2725
if (!string.IsNullOrEmpty(this.connectionString))
2826
{
29-
this._context = new Lazy<AzureSqlDbContext>(() => AzureSqlDbContext.CreateContext(this.connectionString, output));
30-
this.movies = [.. Context.Movies.AsNoTracking()];
27+
Context = await AzureSqlDbContext.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 AzureSqlDbContext Context { get => this._context.Value; }
40+
private AzureSqlDbContext Context { get; set; }
3541

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

38-
protected override Task<AzureSqlEntityMovie> GetEntityAsync(string id)
39-
=> Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(m => m.Id == id));
44+
protected override async Task<AzureSqlEntityMovie> 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<AzureSqlEntityMovie>> GetPopulatedRepositoryAsync()
4551
=> Task.FromResult<IRepository<AzureSqlEntityMovie>>(new EntityTableRepository<AzureSqlEntityMovie>(Context));

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

+19-11
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 AzureSQL_Controller_Tests : LiveControllerTests<AzureSqlEntityMovie>
15+
public class AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests<AzureSqlEntityMovie>, 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<AzureSqlEntityMovie> movies;
19+
private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING");
20+
private List<AzureSqlEntityMovie> movies = [];
2221

23-
public AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base()
22+
public async Task InitializeAsync()
2423
{
25-
this._fixture = fixture;
26-
this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING");
2724
if (!string.IsNullOrEmpty(this.connectionString))
2825
{
29-
output.WriteLine($"AzureSqlIsInitialized = {this._fixture.AzureSqlIsInitialized}");
30-
Context = AzureSqlDbContext.CreateContext(this.connectionString, output, clearEntities: !this._fixture.AzureSqlIsInitialized);
31-
this.movies = [.. Context.Movies.AsNoTracking()];
32-
this._fixture.AzureSqlIsInitialized = true;
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($"CosmosIsInitialized = {fixture.AzureSqlIsInitialized}");
30+
Context = await AzureSqlDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.AzureSqlIsInitialized);
31+
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
32+
fixture.AzureSqlIsInitialized = true;
33+
}
34+
}
35+
36+
public async Task DisposeAsync()
37+
{
38+
if (Context is not null)
39+
{
40+
await Context.DisposeAsync();
3341
}
3442
}
3543

tests/CommunityToolkit.Datasync.TestCommon/Databases/AzureSql/AzureSqlDbContext.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace CommunityToolkit.Datasync.TestCommon.Databases;
1111
[ExcludeFromCodeCoverage]
1212
public class AzureSqlDbContext(DbContextOptions<AzureSqlDbContext> options) : BaseDbContext<AzureSqlDbContext, AzureSqlEntityMovie>(options)
1313
{
14-
public static AzureSqlDbContext CreateContext(string connectionString, ITestOutputHelper output = null, bool clearEntities = true)
14+
public static async Task<AzureSqlDbContext> CreateContextAsync(string connectionString, ITestOutputHelper output = null, bool clearEntities = true)
1515
{
1616
if (string.IsNullOrEmpty(connectionString))
1717
{
@@ -23,12 +23,12 @@ public static AzureSqlDbContext CreateContext(string connectionString, ITestOutp
2323
.EnableLogging(output);
2424
AzureSqlDbContext context = new(optionsBuilder.Options);
2525

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

31-
internal void InitializeDatabase(bool clearEntities)
31+
internal async Task InitializeDatabaseAsync(bool clearEntities)
3232
{
3333
const string datasyncTrigger = @"
3434
CREATE OR ALTER TRIGGER [dbo].[{0}_datasync] ON [dbo].[{0}] AFTER INSERT, UPDATE AS
@@ -43,12 +43,12 @@ internal void InitializeDatabase(bool clearEntities)
4343
END
4444
";
4545

46-
Database.EnsureCreated();
47-
ExecuteRawSqlOnEachEntity(datasyncTrigger);
46+
await Database.EnsureCreatedAsync();
47+
await ExecuteRawSqlOnEachEntityAsync(datasyncTrigger);
4848

4949
if (clearEntities)
5050
{
51-
ExecuteRawSqlOnEachEntity("DELETE FROM [dbo].[{0}]");
51+
await ExecuteRawSqlOnEachEntityAsync("DELETE FROM [dbo].[{0}]");
5252
}
5353
}
5454

tests/CommunityToolkit.Datasync.TestCommon/Databases/Base/BaseDbContext.cs

+14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using CommunityToolkit.Datasync.TestCommon.Models;
88
using Microsoft.EntityFrameworkCore;
99
using Microsoft.EntityFrameworkCore.Metadata;
10+
using System.Runtime.CompilerServices;
1011
using Xunit.Abstractions;
1112

1213
namespace CommunityToolkit.Datasync.TestCommon.Databases;
@@ -45,6 +46,19 @@ protected void ExecuteRawSqlOnEachEntity(string format)
4546
}
4647
}
4748

49+
/// <summary>
50+
/// Executes the provided SQL statement for each entity in our set of entities.
51+
/// </summary>
52+
/// <param name="format"></param>
53+
protected async Task ExecuteRawSqlOnEachEntityAsync(string format)
54+
{
55+
foreach (IEntityType table in Model.GetEntityTypes())
56+
{
57+
string sql = string.Format(format, table.GetTableName());
58+
await Database.ExecuteSqlRawAsync(sql);
59+
}
60+
}
61+
4862
/// <summary>
4963
/// Populates the database with the core set of movies. Ensures that we have the same data for all tests.
5064
/// </summary>

0 commit comments

Comments
 (0)