diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs index 0511b1b..8910242 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs @@ -7,39 +7,45 @@ using Microsoft.EntityFrameworkCore; using Xunit.Abstractions; +#pragma warning disable CS9113 // Parameter is unread. + namespace CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test; [ExcludeFromCodeCoverage] [Collection("LiveTestsCollection")] -public class AzureSqlEntityTableRepository_Tests : RepositoryTests +public class AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IAsyncLifetime { #region Setup - private readonly DatabaseFixture _fixture; private readonly Random random = new(); - private readonly string connectionString; - private readonly List movies; - private readonly Lazy _context; + private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); + private List movies = []; - public AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base() + public async Task InitializeAsync() { - this._fixture = fixture; - this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); if (!string.IsNullOrEmpty(this.connectionString)) { - this._context = new Lazy(() => AzureSqlDbContext.CreateContext(this.connectionString, output)); - this.movies = [.. Context.Movies.AsNoTracking()]; + Context = await AzureSqlDbContext.CreateContextAsync(this.connectionString, output); + this.movies = await Context.Movies.AsNoTracking().ToListAsync(); + } + } + + public async Task DisposeAsync() + { + if (Context is not null) + { + await Context.DisposeAsync(); } } - private AzureSqlDbContext Context { get => this._context.Value; } + private AzureSqlDbContext Context { get; set; } protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); - protected override Task GetEntityAsync(string id) - => Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(m => m.Id == id)); + protected override async Task GetEntityAsync(string id) + => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); - protected override Task GetEntityCountAsync() - => Task.FromResult(Context.Movies.Count()); + protected override async Task GetEntityCountAsync() + => await Context.Movies.CountAsync(); protected override Task> GetPopulatedRepositoryAsync() => Task.FromResult>(new EntityTableRepository(Context)); diff --git a/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs index 5f22df9..c840085 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs @@ -12,24 +12,32 @@ namespace CommunityToolkit.Datasync.Server.Test.Live; [ExcludeFromCodeCoverage] [Collection("LiveTestsCollection")] -public class AzureSQL_Controller_Tests : LiveControllerTests +public class AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IAsyncLifetime { #region Setup - private readonly DatabaseFixture _fixture; private readonly Random random = new(); - private readonly string connectionString; - private readonly List movies; + private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); + private List movies = []; - public AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : base() + public async Task InitializeAsync() { - this._fixture = fixture; - this.connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); if (!string.IsNullOrEmpty(this.connectionString)) { - output.WriteLine($"AzureSqlIsInitialized = {this._fixture.AzureSqlIsInitialized}"); - Context = AzureSqlDbContext.CreateContext(this.connectionString, output, clearEntities: !this._fixture.AzureSqlIsInitialized); - this.movies = [.. Context.Movies.AsNoTracking()]; - this._fixture.AzureSqlIsInitialized = true; + // Note: we don't clear entities on every run to speed up the test runs. This can only be done because + // the tests are read-only (associated with the query and get capabilities). If the test being run writes + // to the database then change clearEntities to true. + output.WriteLine($"CosmosIsInitialized = {fixture.AzureSqlIsInitialized}"); + Context = await AzureSqlDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.AzureSqlIsInitialized); + this.movies = await Context.Movies.AsNoTracking().ToListAsync(); + fixture.AzureSqlIsInitialized = true; + } + } + + public async Task DisposeAsync() + { + if (Context is not null) + { + await Context.DisposeAsync(); } } diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/AzureSql/AzureSqlDbContext.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/AzureSql/AzureSqlDbContext.cs index 6fced11..6e35532 100644 --- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/AzureSql/AzureSqlDbContext.cs +++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/AzureSql/AzureSqlDbContext.cs @@ -11,7 +11,7 @@ namespace CommunityToolkit.Datasync.TestCommon.Databases; [ExcludeFromCodeCoverage] public class AzureSqlDbContext(DbContextOptions options) : BaseDbContext(options) { - public static AzureSqlDbContext CreateContext(string connectionString, ITestOutputHelper output = null, bool clearEntities = true) + public static async Task CreateContextAsync(string connectionString, ITestOutputHelper output = null, bool clearEntities = true) { if (string.IsNullOrEmpty(connectionString)) { @@ -23,12 +23,12 @@ public static AzureSqlDbContext CreateContext(string connectionString, ITestOutp .EnableLogging(output); AzureSqlDbContext context = new(optionsBuilder.Options); - context.InitializeDatabase(clearEntities); - context.PopulateDatabase(); + await context.InitializeDatabaseAsync(clearEntities); + await context.PopulateDatabaseAsync(); return context; } - internal void InitializeDatabase(bool clearEntities) + internal async Task InitializeDatabaseAsync(bool clearEntities) { const string datasyncTrigger = @" CREATE OR ALTER TRIGGER [dbo].[{0}_datasync] ON [dbo].[{0}] AFTER INSERT, UPDATE AS @@ -43,12 +43,12 @@ internal void InitializeDatabase(bool clearEntities) END "; - Database.EnsureCreated(); - ExecuteRawSqlOnEachEntity(datasyncTrigger); + await Database.EnsureCreatedAsync(); + await ExecuteRawSqlOnEachEntityAsync(datasyncTrigger); if (clearEntities) { - ExecuteRawSqlOnEachEntity("DELETE FROM [dbo].[{0}]"); + await ExecuteRawSqlOnEachEntityAsync("DELETE FROM [dbo].[{0}]"); } } diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/Base/BaseDbContext.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/Base/BaseDbContext.cs index 4a036c6..1049874 100644 --- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/Base/BaseDbContext.cs +++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/Base/BaseDbContext.cs @@ -7,6 +7,7 @@ using CommunityToolkit.Datasync.TestCommon.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; +using System.Runtime.CompilerServices; using Xunit.Abstractions; namespace CommunityToolkit.Datasync.TestCommon.Databases; @@ -45,6 +46,19 @@ protected void ExecuteRawSqlOnEachEntity(string format) } } + /// + /// Executes the provided SQL statement for each entity in our set of entities. + /// + /// + protected async Task ExecuteRawSqlOnEachEntityAsync(string format) + { + foreach (IEntityType table in Model.GetEntityTypes()) + { + string sql = string.Format(format, table.GetTableName()); + await Database.ExecuteSqlRawAsync(sql); + } + } + /// /// Populates the database with the core set of movies. Ensures that we have the same data for all tests. ///