diff --git a/Directory.Packages.props b/Directory.Packages.props index 5f844ff..f725fd2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -41,6 +41,7 @@ + diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs index 3552fcd..ae0fc2d 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs @@ -4,6 +4,7 @@ using CommunityToolkit.Datasync.TestCommon; using CommunityToolkit.Datasync.TestCommon.Databases; +using CommunityToolkit.Datasync.TestCommon.Fixtures; using Microsoft.EntityFrameworkCore; using Xunit.Abstractions; @@ -13,7 +14,7 @@ namespace CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test; [ExcludeFromCodeCoverage] [Collection("LiveTestsCollection")] -public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IAsyncLifetime +public class PgEntityTableRepository_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IClassFixture, IAsyncLifetime { #region Setup private readonly Random random = new(); @@ -21,11 +22,8 @@ public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputH public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(ConnectionStrings.PgSql)) - { - Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output); - this.movies = await Context.Movies.AsNoTracking().ToListAsync(); - } + Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output); + this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } public async Task DisposeAsync() @@ -38,7 +36,7 @@ public async Task DisposeAsync() private PgDbContext Context { get; set; } - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql); + protected override bool CanRunLiveTests() => true; protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs index 43ef6cc..431c9b2 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs @@ -5,6 +5,7 @@ using CommunityToolkit.Datasync.Server.EntityFrameworkCore; using CommunityToolkit.Datasync.Server.Test.Helpers; using CommunityToolkit.Datasync.TestCommon.Databases; +using CommunityToolkit.Datasync.TestCommon.Fixtures; using Microsoft.EntityFrameworkCore; using Xunit.Abstractions; @@ -12,7 +13,7 @@ namespace CommunityToolkit.Datasync.Server.Test.Live; [ExcludeFromCodeCoverage] [Collection("LiveTestsCollection")] -public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IAsyncLifetime +public class PgSQL_Controller_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IClassFixture, IAsyncLifetime { #region Setup private readonly Random random = new(); @@ -20,16 +21,8 @@ public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper o public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(ConnectionStrings.PgSql)) - { - // 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($"PgIsInitialized = {fixture.PgIsInitialized}"); - Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output, clearEntities: !fixture.PgIsInitialized); - this.movies = Context.Movies.AsNoTracking().ToList(); - fixture.PgIsInitialized = true; - } + Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output); + this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } public async Task DisposeAsync() @@ -44,7 +37,7 @@ public async Task DisposeAsync() protected override string DriverName { get; } = "PgSQL"; - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql); + protected override bool CanRunLiveTests() => true; protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj b/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj index 7695fb3..7e8f0d9 100644 --- a/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj +++ b/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj @@ -21,6 +21,7 @@ + diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs index dfca137..16c9b4b 100644 --- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs +++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs @@ -11,7 +11,6 @@ public static class ConnectionStrings public static readonly string CosmosDb = Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"); public static readonly string MongoCommunity = Environment.GetEnvironmentVariable("MONGOACI_CONNECTION_STRING"); public static readonly string CosmosMongo = Environment.GetEnvironmentVariable("MONGO_CONNECTION_STRING"); - public static readonly string PgSql = Environment.GetEnvironmentVariable("PGSQL_CONNECTION_STRING"); public static readonly string Service = Environment.GetEnvironmentVariable("SERVICE_ENDPOINT"); public static readonly bool EnableLogging = (Environment.GetEnvironmentVariable("ENABLE_SQL_LOGGING") ?? "false") == "true"; } \ No newline at end of file diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs deleted file mode 100644 index e69de29..0000000 diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs new file mode 100644 index 0000000..d1a21ac --- /dev/null +++ b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using DotNet.Testcontainers.Builders; +using Testcontainers.PostgreSql; +using Xunit; + +namespace CommunityToolkit.Datasync.TestCommon.Fixtures; + +/// +/// A test fixture for implementing a PostgreSQL database using Testcontainers. +/// +[ExcludeFromCodeCoverage] +public class PostgreSqlDatabaseFixture : IAsyncLifetime +{ + private readonly PostgreSqlContainer _container; + + public PostgreSqlDatabaseFixture() + { + this._container = new PostgreSqlBuilder() + .WithImage("postgres:17-alpine") + .WithCleanUp(true) + .WithUsername("testuser") + .WithPassword("testpassword") + .WithDatabase("testdb") + .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(5432)) + .Build(); + } + + /// + public async Task DisposeAsync() + { + if (this._container is not null) + { + await this._container.DisposeAsync(); + } + } + + /// + public async Task InitializeAsync() + { + await this._container.StartAsync(); + ConnectionString = this._container.GetConnectionString(); + } + + /// + /// The connection string for the MySQL database. + /// + public string ConnectionString { get; private set; } = string.Empty; +}