diff --git a/Directory.Packages.props b/Directory.Packages.props
index f725fd27..aef0ebec 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -40,6 +40,7 @@
+
diff --git a/infra/modules/postgresql.bicep b/infra/modules/postgresql.bicep
deleted file mode 100644
index eb1ab6aa..00000000
--- a/infra/modules/postgresql.bicep
+++ /dev/null
@@ -1,89 +0,0 @@
-targetScope = 'resourceGroup'
-
-@description('The list of firewall rules to install')
-param firewallRules FirewallRule[] = [
- { startIpAddress: '0.0.0.0', endIpAddress: '0.0.0.0' }
-]
-
-@minLength(1)
-@description('The name of the test database to create')
-param databaseName string = 'unittests'
-
-@minLength(1)
-@description('Primary location for all resources')
-param location string = resourceGroup().location
-
-@description('The name of the SQL Server to create.')
-param sqlServerName string
-
-@description('Optional - the SQL Server administrator password. If not provided, the username will be \'appadmin\'.')
-param sqlAdminUsername string = 'appadmin'
-
-@secure()
-@description('Optional - SQL Server administrator password. If not provided, a random password will be generated.')
-param sqlAdminPassword string = newGuid()
-
-@description('The list of tags to apply to all resources.')
-param tags object = {}
-
-/*********************************************************************************/
-
-resource pgsql_server 'Microsoft.DBforPostgreSQL/flexibleServers@2023-06-01-preview' = {
- name: sqlServerName
- location: location
- tags: tags
- sku: {
- name: 'Standard_B1ms'
- tier: 'Burstable'
- }
- properties: {
- administratorLogin: sqlAdminUsername
- administratorLoginPassword: sqlAdminPassword
- createMode: 'Default'
- authConfig: {
- activeDirectoryAuth: 'Disabled'
- passwordAuth: 'Enabled'
- }
- backup: {
- backupRetentionDays: 7
- geoRedundantBackup: 'Disabled'
- }
- highAvailability: {
- mode: 'Disabled'
- }
- storage: {
- storageSizeGB: 32
- autoGrow: 'Disabled'
- }
- version: '15'
- }
-
- resource fw 'firewallRules' = [ for (fwRule, idx) in firewallRules : {
- name: 'fw${idx}'
- properties: {
- startIpAddress: fwRule.startIpAddress
- endIpAddress: fwRule.endIpAddress
- }
- }]
-}
-
-resource pgsql_database 'Microsoft.DBforPostgreSQL/flexibleServers/databases@2023-03-01-preview' = {
- name: databaseName
- parent: pgsql_server
- properties: {
- charset: 'UTF8'
- collation: 'en_US.utf8'
- }
-}
-
-/*********************************************************************************/
-
-#disable-next-line outputs-should-not-contain-secrets
-output PGSQL_CONNECTIONSTRING string = 'Host=${pgsql_server.properties.fullyQualifiedDomainName};Database=${pgsql_database.name};Username=${pgsql_server.properties.administratorLogin};Password=${sqlAdminPassword}'
-
-/*********************************************************************************/
-
-type FirewallRule = {
- startIpAddress: string
- endIpAddress: string
-}
diff --git a/infra/resources.bicep b/infra/resources.bicep
index 42b2501c..6457e00d 100644
--- a/infra/resources.bicep
+++ b/infra/resources.bicep
@@ -33,7 +33,6 @@ var appServicePlanName = 'asp-${resourceToken}'
var appServiceName = 'web-${resourceToken}'
var azsqlServerName = 'sql-${resourceToken}'
var cosmosServerName = 'cosmos-${resourceToken}'
-var pgsqlServerName = 'pgsql-${resourceToken}'
var mongoServerName = 'mongo-${resourceToken}'
var mongoaciServerName = 'mongoaci-${resourceToken}'
@@ -67,19 +66,6 @@ module azuresql './modules/azuresql.bicep' = {
}
}
-module pgsql './modules/postgresql.bicep' = {
- name: 'pgsql-deployment-${resourceToken}'
- params: {
- location: location
- tags: tags
- databaseName: testDatabaseName
- firewallRules: clientIpFirewallRules
- sqlServerName: pgsqlServerName
- sqlAdminUsername: sqlAdminUsername
- sqlAdminPassword: sqlAdminPassword
- }
-}
-
module cosmos './modules/cosmos.bicep' = {
name: 'cosmos-deployment-${resourceToken}'
params: {
@@ -136,5 +122,4 @@ output AZSQL_CONNECTIONSTRING string = azuresql.outputs.AZSQL_CONNECTIONSTRING
output COSMOS_CONNECTIONSTRING string = cosmos.outputs.COSMOS_CONNECTIONSTRING
output MONGO_CONNECTIONSTRING string = mongodb.outputs.MONGO_CONNECTIONSTRING
output MONGOACI_CONNECTIONSTRING string = mongoaci.outputs.MONGO_CONNECTIONSTRING
-output PGSQL_CONNECTIONSTRING string = pgsql.outputs.PGSQL_CONNECTIONSTRING
output SERVICE_ENDPOINT string = app_service.outputs.SERVICE_ENDPOINT
diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs
index a3c0e3bc..dadd5d81 100644
--- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs
+++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_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 AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IAsyncLifetime
+public class AzureSqlEntityTableRepository_Tests(MsSqlDatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IClassFixture, IAsyncLifetime
{
#region Setup
private readonly Random random = new();
@@ -21,11 +22,8 @@ public class AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestO
public async Task InitializeAsync()
{
- if (!string.IsNullOrEmpty(ConnectionStrings.AzureSql))
- {
- Context = await AzureSqlDbContext.CreateContextAsync(ConnectionStrings.AzureSql, output);
- this.movies = await Context.Movies.AsNoTracking().ToListAsync();
- }
+ Context = await AzureSqlDbContext.CreateContextAsync(fixture.ConnectionString, output);
+ this.movies = await Context.Movies.AsNoTracking().ToListAsync();
}
public async Task DisposeAsync()
@@ -38,7 +36,7 @@ public async Task DisposeAsync()
private AzureSqlDbContext Context { get; set; }
- protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.AzureSql);
+ 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/AzureSQL_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs
index bbfbdd6a..5e5abc9e 100644
--- a/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs
+++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_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 AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IAsyncLifetime
+public class AzureSQL_Controller_Tests(MsSqlDatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IClassFixture, IAsyncLifetime
{
#region Setup
private readonly Random random = new();
@@ -20,16 +21,8 @@ public class AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelpe
public async Task InitializeAsync()
{
- if (!string.IsNullOrEmpty(ConnectionStrings.AzureSql))
- {
- // 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($"AzureSqlIsInitialized = {fixture.AzureSqlIsInitialized}");
- Context = await AzureSqlDbContext.CreateContextAsync(ConnectionStrings.AzureSql, output, clearEntities: !fixture.AzureSqlIsInitialized);
- this.movies = await Context.Movies.AsNoTracking().ToListAsync();
- fixture.AzureSqlIsInitialized = true;
- }
+ Context = await AzureSqlDbContext.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; } = "AzureSQL";
- protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.AzureSql);
+ protected override bool CanRunLiveTests() => true;
protected override Task GetEntityAsync(string id)
=> Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(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 7e8f0d9a..89d1186c 100644
--- a/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj
+++ b/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj
@@ -20,6 +20,7 @@
+
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
index 16c9b4b6..4c0c324d 100644
--- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
+++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
@@ -7,7 +7,6 @@ namespace CommunityToolkit.Datasync.TestCommon.Databases;
[ExcludeFromCodeCoverage]
public static class ConnectionStrings
{
- public static readonly string AzureSql = Environment.GetEnvironmentVariable("AZSQL_CONNECTION_STRING");
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");
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MsSqlDatabaseFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MsSqlDatabaseFixture.cs
new file mode 100644
index 00000000..2988a9e0
--- /dev/null
+++ b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MsSqlDatabaseFixture.cs
@@ -0,0 +1,41 @@
+// 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 Testcontainers.MsSql;
+using Xunit;
+
+namespace CommunityToolkit.Datasync.TestCommon.Fixtures;
+
+[ExcludeFromCodeCoverage]
+public class MsSqlDatabaseFixture : IAsyncLifetime
+{
+ private readonly MsSqlContainer _container;
+
+ public MsSqlDatabaseFixture()
+ {
+ this._container = new MsSqlBuilder()
+ .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;
+}
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs
new file mode 100644
index 00000000..e69de29b