dotnet / dotnet/aspnetcore

Deeper nested `WebApplicationFactory.WithWebHostBuilder` instances aren't disposed correctly

Open
#32,329 6 comments 8 reactions 0 assignees View on GitHub
area-minimal feature-mvc-testing
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Describe the bug
After creating second (and deeper) levels of derived `WebApplicationFactory` instances with `WithWebHostBuilder` method only the first level will be disposed when root `WebApplicationFactory` instance is disposed.

This creates a memory leak if nested `WithWebHostBuilder` factories are heavily used in tests.

As a possible workaround I keep track of all derived instances and dispose them manually (or with the help `using`), it's still quite unintuitive why only the first level of factories will be disposed when root is disposed.

A simplified example how this could happen:

```c#
public class UserIntegrationTests : IDisposable {
private WebApplicationFactory _root;
private WebApplicationFactory _base;

public UserIntegrationTests() {
_root = new WebApplicationFactory();
// first level of derived factory
_base = _root
.WithWebHostBuilder(builder => {
// common configuration for all test cases in this class
// for example override ConnectionString for test Db
// builder.ConfigureTestServices(services => {
//
// });
});
}

[Fact]
public void LoginTest_Success() {
// Arrange
// second level of derived factory
var app = _base.WithWebHostBuilder(builder => {
// additional overrides to the base that are relevant only to this test case
// builder.ConfigureTestServices(services => {
//
// });
});

var client = app.CreateClient();

// Act
// Assert
}

public void Dispose() {
// dispose root manually
_root.Dispose();
// at this point _base will be disposed too but not the deeper derived app from `LoginTest_Success` test
_base.Dispose();
// _base disposed (obviously) but the derived app still won't be
}
}
```

### To Reproduce
Repro project can be found here: https://github.com/romansp/test-server-derived-factory-memory-leak
I added a failing Xunit test there in `IntegrationTests` project. You can clone project and try `dotnet test` directly from `IntegrationTests` directory.

Test shows that the only singleton service that gets disposed is from first-level derived factory. `Dispose` is not called for singletons from a further derived factory.

### Further technical details

Details

- ASP.NET Core version `.NET 5.0.5`
- Include the output of `dotnet --info`

```
.NET SDK (reflecting any global.json):
Version: 5.0.202
Commit: db7cc87d51

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.202\

Host (useful for support):
Version: 5.0.5
Commit: 2f740adc14

.NET SDKs installed:
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.114 [C:\Program Files\dotnet\sdk]
3.1.300 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
3.1.302 [C:\Program Files\dotnet\sdk]
5.0.103 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
5.0.202 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
```

- The IDE (VS / VS Code/ VS4Mac) you're running on, and its version `VS Version 16.9.4`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.