From d1fb4d07b161ebcaf10da06465cb69c0b0aaf3d6 Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Sat, 12 Nov 2022 15:57:05 +0100
Subject: [PATCH 1/5] Turn off constraints for running tests in parallel
---
test/AnnotationTests/AnnotationTests.csproj | 6 ------
test/DiscoveryTests/DiscoveryTests.csproj | 6 ------
test/DiscoveryTests/xunit.runner.json | 4 ----
test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj | 6 ------
test/JsonApiDotNetCoreTests/xunit.runner.json | 5 -----
test/MultiDbContextTests/MultiDbContextTests.csproj | 6 ------
test/MultiDbContextTests/xunit.runner.json | 5 -----
test/UnitTests/UnitTests.csproj | 6 ------
test/UnitTests/xunit.runner.json | 4 ----
9 files changed, 48 deletions(-)
delete mode 100644 test/DiscoveryTests/xunit.runner.json
delete mode 100644 test/JsonApiDotNetCoreTests/xunit.runner.json
delete mode 100644 test/MultiDbContextTests/xunit.runner.json
delete mode 100644 test/UnitTests/xunit.runner.json
diff --git a/test/AnnotationTests/AnnotationTests.csproj b/test/AnnotationTests/AnnotationTests.csproj
index 51df20d735..7b221a9a42 100644
--- a/test/AnnotationTests/AnnotationTests.csproj
+++ b/test/AnnotationTests/AnnotationTests.csproj
@@ -4,12 +4,6 @@
latest
-
-
- PreserveNewest
-
-
-
diff --git a/test/DiscoveryTests/DiscoveryTests.csproj b/test/DiscoveryTests/DiscoveryTests.csproj
index 2f1048de3f..abbec3ed98 100644
--- a/test/DiscoveryTests/DiscoveryTests.csproj
+++ b/test/DiscoveryTests/DiscoveryTests.csproj
@@ -3,12 +3,6 @@
$(TargetFrameworkName)
-
-
- PreserveNewest
-
-
-
diff --git a/test/DiscoveryTests/xunit.runner.json b/test/DiscoveryTests/xunit.runner.json
deleted file mode 100644
index 9db029ba52..0000000000
--- a/test/DiscoveryTests/xunit.runner.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "parallelizeAssembly": false,
- "parallelizeTestCollections": false
-}
diff --git a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
index ddb7550e5e..22d50630ca 100644
--- a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
+++ b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj
@@ -3,12 +3,6 @@
$(TargetFrameworkName)
-
-
- PreserveNewest
-
-
-
$(TargetFrameworkName)
-
-
- PreserveNewest
-
-
-
diff --git a/test/MultiDbContextTests/xunit.runner.json b/test/MultiDbContextTests/xunit.runner.json
deleted file mode 100644
index 8f5f10571b..0000000000
--- a/test/MultiDbContextTests/xunit.runner.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "parallelizeAssembly": false,
- "parallelizeTestCollections": false,
- "maxParallelThreads": 1
-}
diff --git a/test/UnitTests/UnitTests.csproj b/test/UnitTests/UnitTests.csproj
index eb3383fbdf..3166fe27e1 100644
--- a/test/UnitTests/UnitTests.csproj
+++ b/test/UnitTests/UnitTests.csproj
@@ -3,12 +3,6 @@
$(TargetFrameworkName)
-
-
- PreserveNewest
-
-
-
diff --git a/test/UnitTests/xunit.runner.json b/test/UnitTests/xunit.runner.json
deleted file mode 100644
index 9db029ba52..0000000000
--- a/test/UnitTests/xunit.runner.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "parallelizeAssembly": false,
- "parallelizeTestCollections": false
-}
From bfecdebeaa4c5353edfe7deb3bdf22ffc8a11bca Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Sat, 12 Nov 2022 16:37:45 +0100
Subject: [PATCH 2/5] Add throttling on integration tests that are running in
parallel
---
test/TestBuildingBlocks/IntegrationTest.cs | 19 +++++++++++--
.../IntegrationTestContext.cs | 28 +++++++++++--------
2 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/test/TestBuildingBlocks/IntegrationTest.cs b/test/TestBuildingBlocks/IntegrationTest.cs
index 4fb2e5cd26..92f49879fc 100644
--- a/test/TestBuildingBlocks/IntegrationTest.cs
+++ b/test/TestBuildingBlocks/IntegrationTest.cs
@@ -2,14 +2,18 @@
using System.Text;
using System.Text.Json;
using JsonApiDotNetCore.Middleware;
+using Xunit;
namespace TestBuildingBlocks;
///
-/// A base class for tests that conveniently enables to execute HTTP requests against JSON:API endpoints.
+/// A base class for tests that conveniently enables to execute HTTP requests against JSON:API endpoints. It throttles tests that are running in parallel
+/// to avoid exceeding the maximum active database connections.
///
-public abstract class IntegrationTest
+public abstract class IntegrationTest : IAsyncLifetime
{
+ private static readonly SemaphoreSlim ThrottleSemaphore = new(64);
+
protected abstract JsonSerializerOptions SerializerOptions { get; }
public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteHeadAsync(string requestUrl,
@@ -105,4 +109,15 @@ public abstract class IntegrationTest
throw new FormatException($"Failed to deserialize response body to JSON:\n{responseText}", exception);
}
}
+
+ public async Task InitializeAsync()
+ {
+ await ThrottleSemaphore.WaitAsync();
+ }
+
+ public virtual Task DisposeAsync()
+ {
+ _ = ThrottleSemaphore.Release();
+ return Task.CompletedTask;
+ }
}
diff --git a/test/TestBuildingBlocks/IntegrationTestContext.cs b/test/TestBuildingBlocks/IntegrationTestContext.cs
index bccf7d8bf3..7856ba67f9 100644
--- a/test/TestBuildingBlocks/IntegrationTestContext.cs
+++ b/test/TestBuildingBlocks/IntegrationTestContext.cs
@@ -24,7 +24,7 @@ namespace TestBuildingBlocks;
/// The Entity Framework Core database context, which can be defined in the test project or API project.
///
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
-public class IntegrationTestContext : IntegrationTest, IDisposable
+public class IntegrationTestContext : IntegrationTest
where TStartup : class
where TDbContext : TestableDbContext
{
@@ -103,16 +103,6 @@ private WebApplicationFactory CreateFactory()
return factoryWithConfiguredContentRoot;
}
- public void Dispose()
- {
- if (_lazyFactory.IsValueCreated)
- {
- RunOnDatabaseAsync(async dbContext => await dbContext.Database.EnsureDeletedAsync()).Wait();
-
- _lazyFactory.Value.Dispose();
- }
- }
-
public void ConfigureLogging(Action loggingConfiguration)
{
_loggingConfiguration = loggingConfiguration;
@@ -136,6 +126,22 @@ public async Task RunOnDatabaseAsync(Func asyncAction)
await asyncAction(dbContext);
}
+ public override async Task DisposeAsync()
+ {
+ try
+ {
+ if (_lazyFactory.IsValueCreated)
+ {
+ await RunOnDatabaseAsync(async dbContext => await dbContext.Database.EnsureDeletedAsync());
+ await _lazyFactory.Value.DisposeAsync();
+ }
+ }
+ finally
+ {
+ await base.DisposeAsync();
+ }
+ }
+
private sealed class IntegrationTestWebApplicationFactory : WebApplicationFactory
{
private Action? _loggingConfiguration;
From a349fb957acf6e4bdb97fe2c5915ea20fc63aa84 Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Sat, 12 Nov 2022 18:01:18 +0100
Subject: [PATCH 3/5] Fixed: temporary database created by test not deleted
afterwards
---
.../AtomicTransactionConsistencyTests.cs | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs
index 97f0e08ff5..46ef0c4784 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs
@@ -9,7 +9,8 @@
namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Transactions;
-public sealed class AtomicTransactionConsistencyTests : IClassFixture, OperationsDbContext>>
+public sealed class AtomicTransactionConsistencyTests
+ : IClassFixture, OperationsDbContext>>, IAsyncLifetime
{
private readonly IntegrationTestContext, OperationsDbContext> _testContext;
private readonly OperationsFakers _fakers = new();
@@ -27,7 +28,7 @@ public AtomicTransactionConsistencyTests(IntegrationTestContext();
string postgresPassword = Environment.GetEnvironmentVariable("PGPASSWORD") ?? "postgres";
- string dbConnectionString = $"Host=localhost;Port=5432;Database=JsonApiTest-{Guid.NewGuid():N};User ID=postgres;Password={postgresPassword}";
+ string dbConnectionString = $"Host=localhost;Port=5432;Database=JsonApiTest-Extra-{Guid.NewGuid():N};User ID=postgres;Password={postgresPassword}";
services.AddDbContext(options => options.UseNpgsql(dbConnectionString));
});
@@ -158,4 +159,22 @@ public async Task Cannot_use_distributed_transaction()
error.Source.ShouldNotBeNull();
error.Source.Pointer.Should().Be("/atomic:operations[0]");
}
+
+ public Task InitializeAsync()
+ {
+ return Task.CompletedTask;
+ }
+
+ Task IAsyncLifetime.DisposeAsync()
+ {
+ return DeleteExtraDatabaseAsync();
+ }
+
+ private async Task DeleteExtraDatabaseAsync()
+ {
+ await using AsyncServiceScope scope = _testContext.Factory.Services.CreateAsyncScope();
+ var dbContext = scope.ServiceProvider.GetRequiredService();
+
+ await dbContext.Database.EnsureDeletedAsync();
+ }
}
From fd16904f636b0c201bbcf8f899dd32cc7b714539 Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Sat, 12 Nov 2022 18:09:42 +0100
Subject: [PATCH 4/5] Avoid potential database name clashes in tests
---
.../Configuration/DependencyContainerRegistrationTests.cs | 2 +-
test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs
index d0bb39a187..8642461d50 100644
--- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs
+++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs
@@ -74,7 +74,7 @@ private static IHostBuilder CreateValidatingHostBuilder()
IHostBuilder hostBuilder = Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureServices(services =>
- services.AddDbContext(options => options.UseInMemoryDatabase("db")));
+ services.AddDbContext(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString())));
webBuilder.UseStartup>();
diff --git a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs
index a90c3851ee..0cb24d8025 100644
--- a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs
+++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs
@@ -25,7 +25,7 @@ public void RegisterResource_DeviatingDbContextPropertyName_RegistersCorrectly()
// Arrange
var services = new ServiceCollection();
services.AddLogging();
- services.AddDbContext(options => options.UseInMemoryDatabase("UnitTestDb"));
+ services.AddDbContext(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString()));
// Act
services.AddJsonApi();
From 7cdf273076b83bd66658724fc7d006fba7c493f8 Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Sat, 12 Nov 2022 19:32:33 +0100
Subject: [PATCH 5/5] Apply global convention for all integration tests: change
DeleteBehavior.ClientSetNull to DeleteBehavior.SetNull This improves speed
and reduces the number of errors logged by the PostgreSQL server when running
tests, because we no longer need the "truncate table cascade" fallback in
DbContextExtensions.
---
.../AtomicOperations/OperationsDbContext.cs | 2 ++
.../CompositeKeys/CompositeDbContext.cs | 2 ++
.../EagerLoading/EagerLoadingDbContext.cs | 2 ++
.../ModelState/ModelStateDbContext.cs | 2 ++
.../IntegrationTests/Links/LinksDbContext.cs | 2 ++
.../MultiTenancy/MultiTenancyDbContext.cs | 2 ++
.../QueryStrings/Filtering/FilterDbContext.cs | 2 ++
.../QueryStrings/QueryStringDbContext.cs | 2 ++
.../ReadWrite/ReadWriteDbContext.cs | 2 ++
.../DefaultBehaviorDbContext.cs | 2 ++
.../Serialization/SerializationDbContext.cs | 2 ++
.../ResourceInheritanceReadTests.cs | 4 ++--
.../TablePerType/TablePerTypeDbContext.cs | 2 ++
.../SoftDeletion/SoftDeletionDbContext.cs | 2 ++
.../IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs | 2 ++
test/TestBuildingBlocks/DbContextExtensions.cs | 13 +------------
test/TestBuildingBlocks/TestableDbContext.cs | 12 ++++++++++++
17 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs
index 26dd815521..6fd7817ba7 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs
@@ -31,5 +31,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasMany(musicTrack => musicTrack.OccursIn)
.WithMany(playlist => playlist.Tracks);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs
index b745208cae..d4850ad428 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs
@@ -39,5 +39,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasMany(car => car.PreviousDealerships)
.WithMany(dealership => dealership.SoldCars);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs
index 030a1a447b..a31deab9a8 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs
@@ -34,5 +34,7 @@ protected override void OnModelCreating(ModelBuilder builder)
.HasOne(building => building.SecondaryDoor)
.WithOne()
.HasForeignKey("SecondaryDoorId");
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs
index 73f3241f28..1bfdb1a28e 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs
@@ -37,5 +37,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasOne(systemDirectory => systemDirectory.AlsoSelf)
.WithOne();
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/LinksDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/LinksDbContext.cs
index ffd2333fbe..149b29b785 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/LinksDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/LinksDbContext.cs
@@ -24,5 +24,7 @@ protected override void OnModelCreating(ModelBuilder builder)
.HasOne(photo => photo.Location)
.WithOne(location => location.Photo)
.HasForeignKey("LocationId");
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs
index 8e1fcd8350..69a6459303 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs
@@ -31,5 +31,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasQueryFilter(webProduct => webProduct.Shop.TenantId == _tenantProvider.TenantId);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs
index 1b939ee9a1..35e7b4e51e 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs
@@ -21,5 +21,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.Property(resource => resource.SomeDateTimeInLocalZone)
.HasColumnType("timestamp without time zone");
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs
index 131bfe19fe..473a7428ba 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs
@@ -37,5 +37,7 @@ protected override void OnModelCreating(ModelBuilder builder)
.HasOne(man => man.Wife)
.WithOne(woman => woman.Husband)
.HasForeignKey();
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs
index d25acf8a06..4f3d1080cf 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs
@@ -49,5 +49,7 @@ protected override void OnModelCreating(ModelBuilder builder)
left => left
.HasOne(joinEntity => joinEntity.ToItem)
.WithMany());
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs
index 6ed4deaeff..5b0b839c63 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs
@@ -33,5 +33,7 @@ protected override void OnModelCreating(ModelBuilder builder)
.HasOne(order => order.Shipment)
.WithOne(shipment => shipment.Order)
.HasForeignKey("OrderId");
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs
index 7f62a63b73..4bfb7aa709 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs
@@ -22,5 +22,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasMany(scholarship => scholarship.Participants)
.WithOne(student => student.Scholarship!);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs
index 3a7b60e93d..ebca28dac9 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs
@@ -2429,7 +2429,7 @@ public async Task Can_sort_on_derived_attribute_from_resource_definition_using_e
await _testContext.RunOnDatabaseAsync(async dbContext =>
{
- await dbContext.ClearTableAsync();
+ await dbContext.ClearTableAsync();
dbContext.Wheels.AddRange(chromeWheel1, chromeWheel2, chromeWheel3, carbonWheel1, carbonWheel2);
await dbContext.SaveChangesAsync();
});
@@ -2487,7 +2487,7 @@ public async Task Can_sort_on_derived_attribute_from_resource_definition_using_l
await _testContext.RunOnDatabaseAsync(async dbContext =>
{
- await dbContext.ClearTableAsync();
+ await dbContext.ClearTableAsync();
dbContext.Wheels.AddRange(chromeWheel1, chromeWheel2, chromeWheel3, carbonWheel1, carbonWheel2);
await dbContext.SaveChangesAsync();
});
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs
index a1549e6332..7c50ee5573 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs
@@ -32,5 +32,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity().ToTable("GenericProperties");
builder.Entity().ToTable("StringProperties");
builder.Entity().ToTable("NumberProperties");
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs
index 2a19ba74b4..3e98950be0 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs
@@ -24,5 +24,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasQueryFilter(department => department.SoftDeletedAt == null);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs
index 301a7b6d7b..3e93768683 100644
--- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs
+++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs
@@ -27,5 +27,7 @@ protected override void OnModelCreating(ModelBuilder builder)
builder.Entity()
.HasOne(player => player.ActiveGame)
.WithMany(game => game.ActivePlayers);
+
+ base.OnModelCreating(builder);
}
}
diff --git a/test/TestBuildingBlocks/DbContextExtensions.cs b/test/TestBuildingBlocks/DbContextExtensions.cs
index b570cbf655..5bb3f81a14 100644
--- a/test/TestBuildingBlocks/DbContextExtensions.cs
+++ b/test/TestBuildingBlocks/DbContextExtensions.cs
@@ -1,6 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
-using Npgsql;
namespace TestBuildingBlocks;
@@ -36,17 +35,7 @@ private static async Task ClearTablesAsync(this DbContext dbContext, params Type
}
string tableName = entityType.GetTableName()!;
-
- // PERF: We first try to clear the table, which is fast and usually succeeds, unless foreign key constraints are violated.
- // In that case, we recursively delete all related data, which is slow.
- try
- {
- await dbContext.Database.ExecuteSqlRawAsync($"delete from \"{tableName}\"");
- }
- catch (PostgresException)
- {
- await dbContext.Database.ExecuteSqlRawAsync($"truncate table \"{tableName}\" cascade");
- }
+ await dbContext.Database.ExecuteSqlRawAsync($"delete from \"{tableName}\"");
}
}
}
diff --git a/test/TestBuildingBlocks/TestableDbContext.cs b/test/TestBuildingBlocks/TestableDbContext.cs
index d40db11c03..18ef090baa 100644
--- a/test/TestBuildingBlocks/TestableDbContext.cs
+++ b/test/TestBuildingBlocks/TestableDbContext.cs
@@ -1,6 +1,7 @@
using System.Diagnostics;
using JsonApiDotNetCore;
using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging;
namespace TestBuildingBlocks;
@@ -17,4 +18,15 @@ protected override void OnConfiguring(DbContextOptionsBuilder builder)
// Writes SQL statements to the Output Window when debugging.
builder.LogTo(message => Debug.WriteLine(message), DbLoggerCategory.Database.Name.AsArray(), LogLevel.Information);
}
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ foreach (IMutableForeignKey foreignKey in builder.Model.GetEntityTypes().SelectMany(entityType => entityType.GetForeignKeys()))
+ {
+ if (foreignKey.DeleteBehavior == DeleteBehavior.ClientSetNull)
+ {
+ foreignKey.DeleteBehavior = DeleteBehavior.SetNull;
+ }
+ }
+ }
}