diff --git a/infra/main.bicep b/infra/main.bicep index 6f5979c..3cac643 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -50,6 +50,8 @@ module resources './resources.bicep' = { output AZSQL_CONNECTION_STRING string = resources.outputs.AZSQL_CONNECTIONSTRING output COSMOS_CONNECTION_STRING string = resources.outputs.COSMOS_CONNECTIONSTRING +output MONGO_CONNECTION_STRING string = resources.outputs.MONGO_CONNECTIONSTRING +output MONGOACI_CONNECTION_STRING string = resources.outputs.MONGOACI_CONNECTIONSTRING output MYSQL_CONNECTION_STRING string = resources.outputs.MYSQL_CONNECTIONSTRING output PGSQL_CONNECTION_STRING string = resources.outputs.PGSQL_CONNECTIONSTRING output SERVICE_ENDPOINT string = resources.outputs.SERVICE_ENDPOINT diff --git a/infra/modules/aci-mongodb.bicep b/infra/modules/aci-mongodb.bicep new file mode 100644 index 0000000..fb6c954 --- /dev/null +++ b/infra/modules/aci-mongodb.bicep @@ -0,0 +1,74 @@ +targetScope = 'resourceGroup' + +@secure() +@description('The password for the administrator') +param administratorPassword string + +@description('The username for the administrator') +param administratorUsername string = 'tester' + +@description('The image URI to use.') +param image string = 'mongo' + +@minLength(1) +@description('Primary location for all resources') +param location string = resourceGroup().location + +@description('The port # to expose in the Docker image') +param port int = 27017 + +@description('The name of the Mongo Server to create.') +param serverName string + +@description('The list of tags to apply to all resources.') +param tags object = {} + +/*********************************************************************************/ + +resource containerGroup 'Microsoft.ContainerInstance/containerGroups@2023-05-01' = { + name: toLower(serverName) + location: location + tags: tags + properties: { + containers: [ + { + name: toLower(serverName) + properties: { + image: image + environmentVariables: [ + { name: 'MONGO_INITDB_ROOT_USERNAME', value: administratorUsername } + { name: 'MONGO_INITDB_ROOT_PASSWORD', secureValue: administratorPassword } + ] + ports: [ + { + port: port + protocol: 'TCP' + } + ] + resources: { + requests: { + cpu: 2 + memoryInGB: 2 + } + } + } + } + ] + osType: 'Linux' + restartPolicy: 'Always' + ipAddress: { + type: 'Public' + ports: [ + { + port: port + protocol: 'TCP' + } + ] + } + } +} + +/*********************************************************************************/ + +#disable-next-line outputs-should-not-contain-secrets +output MONGO_CONNECTIONSTRING string = 'mongodb://${administratorUsername}:${administratorPassword}@${containerGroup.properties.ipAddress.ip}:27017/' diff --git a/infra/modules/cosmos-mongodb.bicep b/infra/modules/cosmos-mongodb.bicep new file mode 100644 index 0000000..fa44521 --- /dev/null +++ b/infra/modules/cosmos-mongodb.bicep @@ -0,0 +1,182 @@ +targetScope = 'resourceGroup' + +@minLength(1) +@description('The name of the test container to create') +param containerName string = 'Movies' + +@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 + +@allowed(['3.2', '3.6', '4.0', '4.2']) +@description('Specifies the MongoDB server version to use.') +param mongoVersion string = '4.2' + +@description('The name of the Mongo Server to create.') +param serverName string + +@description('The list of tags to apply to all resources.') +param tags object = {} + +/*********************************************************************************/ + +var compositeIndices = [ + [ + { path: '/BestPictureWinner', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/BestPictureWinner', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Duration', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Duration', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Rating', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Rating', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/ReleaseDate', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/ReleaseDate', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Title', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Title', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/UpdatedAt', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/UpdatedAt', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'ascending' } + { path: '/Title', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'descending' } + { path: '/Title', order: 'ascending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'ascending' } + { path: '/Title', order: 'descending' } + { path: '/id', order: 'ascending' } + ] + [ + { path: '/Year', order: 'descending' } + { path: '/Title', order: 'descending' } + { path: '/id', order: 'ascending' } + ] +] + +/*********************************************************************************/ + +resource account 'Microsoft.DocumentDB/databaseAccounts@2022-05-15' = { + name: toLower(serverName) + location: location + kind: 'MongoDB' + tags: tags + properties: { + apiProperties: { + serverVersion: mongoVersion + } + capabilities: [ + { + name: 'DisableRateLimitingResponses' + } + ] + consistencyPolicy: { + defaultConsistencyLevel: 'Session' + } + databaseAccountOfferType: 'Standard' + disableLocalAuth: false + locations: [ + { + locationName: location + isZoneRedundant: false + } + ] + } +} + +resource database 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases@2022-05-15' = { + parent: account + name: databaseName + tags: tags + properties: { + resource: { + id: databaseName + } + options: { + throughput: 400 + } + } +} + +resource collection 'Microsoft.DocumentDb/databaseAccounts/mongodbDatabases/collections@2022-05-15' = { + parent: database + name: containerName + tags: tags + properties: { + resource: { + id: containerName + shardKey: { + _id: 'Hash' + } + indexes: [ + { + key: { + keys: [ + '_id' + ] + } + } + { + key: { + keys: [ + '$**' + ] + } + } + ] + } + } +} +/*********************************************************************************/ + +#disable-next-line outputs-should-not-contain-secrets +output MONGODB_CONNECTIONSTRING string = account.listConnectionStrings().connectionStrings[1].connectionString diff --git a/infra/resources.bicep b/infra/resources.bicep index f42f39e..7aa8242 100644 --- a/infra/resources.bicep +++ b/infra/resources.bicep @@ -35,6 +35,8 @@ var azsqlServerName = 'sql-${resourceToken}' var cosmosServerName = 'cosmos-${resourceToken}' var pgsqlServerName = 'pgsql-${resourceToken}' var mysqlServerName = 'mysql-${resourceToken}' +var mongoServerName = 'mongo-${resourceToken}' +var mongoaciServerName = 'mongoaci-${resourceToken}' var testDatabaseName = 'unittests' var cosmosContainerName = 'Movies' @@ -103,6 +105,28 @@ module cosmos './modules/cosmos.bicep' = { } } +module mongodb './modules/cosmos-mongodb.bicep' = { + name: 'mongo-deployment-${resourceToken}' + params: { + location: location + tags: tags + databaseName: testDatabaseName + containerName: cosmosContainerName + serverName: mongoServerName + } +} + +module mongoaci './modules/aci-mongodb.bicep' = { + name: 'mongoaci-deployment-${resourceToken}' + params: { + location: location + tags: tags + serverName: mongoaciServerName + administratorPassword: sqlAdminPassword + + } +} + module app_service './modules/appservice.bicep' = { name: 'appsvc-deployment-${resourceToken}' params: { @@ -124,6 +148,8 @@ module app_service './modules/appservice.bicep' = { output AZSQL_CONNECTIONSTRING string = azuresql.outputs.AZSQL_CONNECTIONSTRING output COSMOS_CONNECTIONSTRING string = cosmos.outputs.COSMOS_CONNECTIONSTRING +output MONGO_CONNECTIONSTRING string = mongodb.outputs.MONGODB_CONNECTIONSTRING +output MONGOACI_CONNECTIONSTRING string = mongoaci.outputs.MONGO_CONNECTIONSTRING output MYSQL_CONNECTIONSTRING string = mysql.outputs.MYSQL_CONNECTIONSTRING output PGSQL_CONNECTIONSTRING string = pgsql.outputs.PGSQL_CONNECTIONSTRING output SERVICE_ENDPOINT string = app_service.outputs.SERVICE_ENDPOINT diff --git a/infra/scripts/write-runsettings.ps1 b/infra/scripts/write-runsettings.ps1 index cd288ae..d40f43f 100644 --- a/infra/scripts/write-runsettings.ps1 +++ b/infra/scripts/write-runsettings.ps1 @@ -6,20 +6,26 @@ $outputs = (azd env get-values --output json | ConvertFrom-Json) $outputFile = "tests\.runsettings" -$fileContents = @" +$prefix = @" - $($outputs.AZSQL_CONNECTION_STRING) - $($outputs.COSMOS_CONNECTION_STRING) - $($outputs.MYSQL_CONNECTION_STRING) - $($outputs.PGSQL_CONNECTION_STRING) - $($outputs.SERVICE_ENDPOINT) + +"@ + +$postfix = @" true "@ -$fileContents | Out-File -FilePath $outputFile +$sb = New-Object System.Text.StringBuilder +$outputs | Get-Member -MemberType Properties | Foreach-Object { + $propertyName = $_.Name + $propertyValue = [System.Security.SecurityElement]::Escape($outputs.$propertyName) + $sb.AppendLine(" <$($propertyName)>$($propertyValue)") | Out-Null +} + +$prefix + $sb.ToString() + $postfix | Out-File -FilePath $outputFile diff --git a/tests/CommunityToolkit.Datasync.Client.Test/Live/SampleServerTests.cs b/tests/CommunityToolkit.Datasync.Client.Test/Live/SampleServerTests.cs index a0ac1b2..92a827a 100644 --- a/tests/CommunityToolkit.Datasync.Client.Test/Live/SampleServerTests.cs +++ b/tests/CommunityToolkit.Datasync.Client.Test/Live/SampleServerTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using CommunityToolkit.Datasync.TestCommon.Databases; using System.Net; using System.Net.Http.Json; @@ -10,8 +11,8 @@ namespace CommunityToolkit.Datasync.Client.Test.Live; [ExcludeFromCodeCoverage] public class SampleServerTests { - private readonly bool liveTestsAreEnabled = Environment.GetEnvironmentVariable("DATASYNC_SERVICE_ENDPOINT") is not null; - private readonly string serviceEndpoint = Environment.GetEnvironmentVariable("DATASYNC_SERVICE_ENDPOINT"); + private readonly bool liveTestsAreEnabled = ConnectionStrings.Service is not null; + private readonly string serviceEndpoint = ConnectionStrings.Service; [SkippableFact] public async Task Metadata_GetsSetByServer() diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs index 8910242..a3c0e3b 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/AzureSqlEntityTableRepository_Tests.cs @@ -17,14 +17,13 @@ public class AzureSqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestO { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.AzureSql)) { - Context = await AzureSqlDbContext.CreateContextAsync(this.connectionString, output); + Context = await AzureSqlDbContext.CreateContextAsync(ConnectionStrings.AzureSql, output); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } } @@ -39,7 +38,7 @@ public async Task DisposeAsync() private AzureSqlDbContext Context { get; set; } - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.AzureSql); protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/CosmosEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/CosmosEntityTableRepository_Tests.cs index 0afc3cc..19ee62c 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/CosmosEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/CosmosEntityTableRepository_Tests.cs @@ -17,14 +17,13 @@ public class CosmosEntityTableRepository_Tests(DatabaseFixture fixture, ITestOut { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_COSMOS_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.CosmosDb)) { - Context = await CosmosDbContext.CreateContextAsync(this.connectionString, output); + Context = await CosmosDbContext.CreateContextAsync(ConnectionStrings.CosmosDb, output); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } } @@ -39,7 +38,7 @@ public async Task DisposeAsync() private CosmosDbContext Context { get; set; } - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.CosmosDb); protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/MySqlEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/MySqlEntityTableRepository_Tests.cs index 2e53932..3e23300 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/MySqlEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/MySqlEntityTableRepository_Tests.cs @@ -17,14 +17,13 @@ public class MysqlEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutp { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_MYSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.MySql)) { - Context = await MysqlDbContext.CreateContextAsync(this.connectionString, output); + Context = await MysqlDbContext.CreateContextAsync(ConnectionStrings.MySql, output); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } } @@ -39,7 +38,7 @@ public async Task DisposeAsync() private MysqlDbContext Context { get; set; } - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.MySql); protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs index 924ed30..3552fcd 100644 --- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs @@ -17,14 +17,13 @@ public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputH { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.PgSql)) { - Context = await PgDbContext.CreateContextAsync(this.connectionString, output); + Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); } } @@ -39,7 +38,7 @@ public async Task DisposeAsync() private PgDbContext Context { get; set; } - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql); 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 8827b5a..bbfbdd6 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/AzureSQL_Controller_Tests.cs @@ -16,18 +16,17 @@ public class AzureSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelpe { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_AZSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + 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(this.connectionString, output, clearEntities: !fixture.AzureSqlIsInitialized); + Context = await AzureSqlDbContext.CreateContextAsync(ConnectionStrings.AzureSql, output, clearEntities: !fixture.AzureSqlIsInitialized); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); fixture.AzureSqlIsInitialized = true; } @@ -45,7 +44,7 @@ public async Task DisposeAsync() protected override string DriverName { get; } = "AzureSQL"; - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.AzureSql); protected override Task GetEntityAsync(string id) => Task.FromResult(Context.Movies.AsNoTracking().SingleOrDefault(m => m.Id == id)); diff --git a/tests/CommunityToolkit.Datasync.Server.Test/Live/Cosmos_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/Cosmos_Controller_Tests.cs index 39161d4..c068602 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/Cosmos_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/Cosmos_Controller_Tests.cs @@ -7,7 +7,6 @@ using CommunityToolkit.Datasync.TestCommon; using CommunityToolkit.Datasync.TestCommon.Databases; using Microsoft.EntityFrameworkCore; -using System; using Xunit.Abstractions; namespace CommunityToolkit.Datasync.Server.Test.Live; @@ -18,18 +17,17 @@ public class Cosmos_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_COSMOS_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.CosmosDb)) { // 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.CosmosIsInitialized}"); - Context = await CosmosDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.CosmosIsInitialized); + Context = await CosmosDbContext.CreateContextAsync(ConnectionStrings.CosmosDb, output, clearEntities: !fixture.CosmosIsInitialized); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); fixture.CosmosIsInitialized = true; } @@ -47,7 +45,7 @@ public async Task DisposeAsync() protected override string DriverName { get; } = "Cosmos"; - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.CosmosDb); 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/LiteDb_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/LiteDb_Controller_Tests.cs index 0f5198b..7838f3c 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/LiteDb_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/LiteDb_Controller_Tests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using CommunityToolkit.Datasync.Server.Abstractions.Http; -using CommunityToolkit.Datasync.Server.InMemory; using CommunityToolkit.Datasync.Server.LiteDb; using CommunityToolkit.Datasync.Server.Test.Helpers; using CommunityToolkit.Datasync.TestCommon.Databases; diff --git a/tests/CommunityToolkit.Datasync.Server.Test/Live/MySQL_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/MySQL_Controller_Tests.cs index 5b0b78c..d0f03e2 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/MySQL_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/MySQL_Controller_Tests.cs @@ -17,18 +17,17 @@ public class MySQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper o { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_MYSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + if (!string.IsNullOrEmpty(ConnectionStrings.MySql)) { // 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($"MysqlIsInitialized = {fixture.MysqlIsInitialized}"); - Context = await MysqlDbContext.CreateContextAsync(this.connectionString, output, clearEntities: !fixture.MysqlIsInitialized); + Context = await MysqlDbContext.CreateContextAsync(ConnectionStrings.MySql, output, clearEntities: !fixture.MysqlIsInitialized); this.movies = await Context.Movies.AsNoTracking().ToListAsync(); fixture.MysqlIsInitialized = true; } @@ -46,7 +45,7 @@ public async Task DisposeAsync() protected override string DriverName { get; } = "MySQL"; - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.MySql); 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 eb85340..43ef6cc 100644 --- a/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs @@ -16,18 +16,17 @@ public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper o { #region Setup private readonly Random random = new(); - private readonly string connectionString = Environment.GetEnvironmentVariable("DATASYNC_PGSQL_CONNECTIONSTRING"); private List movies = []; public async Task InitializeAsync() { - if (!string.IsNullOrEmpty(this.connectionString)) + 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(this.connectionString, output, clearEntities: !fixture.PgIsInitialized); + Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output, clearEntities: !fixture.PgIsInitialized); this.movies = Context.Movies.AsNoTracking().ToList(); fixture.PgIsInitialized = true; } @@ -45,7 +44,7 @@ public async Task DisposeAsync() protected override string DriverName { get; } = "PgSQL"; - protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(this.connectionString); + protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql); protected override async Task GetEntityAsync(string id) => await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id); diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs new file mode 100644 index 0000000..47113a2 --- /dev/null +++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs @@ -0,0 +1,19 @@ +// 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. + +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"); + public static readonly string MySql = Environment.GetEnvironmentVariable("MYSQL_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/Databases/LoggingExtensions.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/LoggingExtensions.cs index 2d479d3..4144919 100644 --- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/LoggingExtensions.cs +++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/LoggingExtensions.cs @@ -22,8 +22,7 @@ public static class LoggingExtensions /// The database context (for chaining). public static DbContextOptionsBuilder EnableLogging(this DbContextOptionsBuilder current, ITestOutputHelper output) where TContext : DbContext { - bool enableLogging = (Environment.GetEnvironmentVariable("ENABLE_SQL_LOGGING") ?? "false") == "true"; - if (output != null && enableLogging) + if (output != null && ConnectionStrings.EnableLogging) { current .UseLoggerFactory(new TestLoggerFactory(output, categories))