Skip to content

Commit e7634ba

Browse files
authored
Merge pull request #180 from dotnet-maestro-bot/merge/release/2.2-to-master
[automated] Merge branch 'release/2.2' => 'master'
2 parents 2ebc241 + 2516f07 commit e7634ba

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

test/Microsoft.Extensions.Http.Test/DefaultHttpClientFactoryTest.cs

+41-14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Net.Http;
7+
using System.Runtime.CompilerServices;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using Microsoft.Extensions.DependencyInjection;
@@ -356,6 +357,40 @@ public async Task Factory_CleanupCycle_DisposesEligibleHandler()
356357
EnableCleanupTimer = true,
357358
};
358359

360+
var cleanupEntry = await SimulateClientUse_Factory_CleanupCycle_DisposesEligibleHandler(factory);
361+
362+
// Being pretty conservative here because we want this test to be reliable,
363+
// and it depends on the GC and timing.
364+
for (var i = 0; i < 3; i++)
365+
{
366+
GC.Collect();
367+
GC.WaitForPendingFinalizers();
368+
GC.Collect();
369+
370+
if (cleanupEntry.CanDispose)
371+
{
372+
break;
373+
}
374+
375+
await Task.Delay(TimeSpan.FromSeconds(1));
376+
}
377+
378+
Assert.True(cleanupEntry.CanDispose, "Cleanup entry disposable");
379+
380+
// Act
381+
factory.CleanupTimer_Tick();
382+
383+
// Assert
384+
Assert.Empty(factory._expiredHandlers);
385+
Assert.Equal(1, disposeHandler.DisposeCount);
386+
Assert.False(factory.CleanupTimerStarted.IsSet, "Cleanup timer not started");
387+
}
388+
389+
// Seprate to avoid the HttpClient getting its lifetime extended by
390+
// the state machine of the test.
391+
[MethodImpl(MethodImplOptions.NoInlining)]
392+
private async Task<ExpiredHandlerTrackingEntry> SimulateClientUse_Factory_CleanupCycle_DisposesEligibleHandler(TestHttpClientFactory factory)
393+
{
359394
// Create a handler and move it to the expired state
360395
var client1 = factory.CreateClient("github");
361396

@@ -372,19 +407,8 @@ public async Task Factory_CleanupCycle_DisposesEligibleHandler()
372407
// the factory isn't keeping any references.
373408
kvp = default;
374409
client1 = null;
375-
GC.Collect();
376-
GC.WaitForPendingFinalizers();
377-
GC.Collect();
378410

379-
Assert.True(cleanupEntry.CanDispose, "Cleanup entry disposable");
380-
381-
// Act
382-
factory.CleanupTimer_Tick();
383-
384-
// Assert
385-
Assert.Empty(factory._expiredHandlers);
386-
Assert.Equal(1, disposeHandler.DisposeCount);
387-
Assert.False(factory.CleanupTimerStarted.IsSet, "Cleanup timer not started");
411+
return cleanupEntry;
388412
}
389413

390414
[Fact]
@@ -403,7 +427,7 @@ public async Task Factory_CleanupCycle_DisposesLiveHandler()
403427
EnableCleanupTimer = true,
404428
};
405429

406-
var cleanupEntry = await SimulateClientUse(factory, disposeHandler);
430+
var cleanupEntry = await SimulateClientUse_Factory_CleanupCycle_DisposesLiveHandler(factory, disposeHandler);
407431

408432
// Being pretty conservative here because we want this test to be reliable,
409433
// and it depends on the GC and timing.
@@ -432,7 +456,10 @@ public async Task Factory_CleanupCycle_DisposesLiveHandler()
432456
Assert.False(factory.CleanupTimerStarted.IsSet, "Cleanup timer not started");
433457
}
434458

435-
private async Task<ExpiredHandlerTrackingEntry> SimulateClientUse(
459+
// Seprate to avoid the HttpClient getting its lifetime extended by
460+
// the state machine of the test.
461+
[MethodImpl(MethodImplOptions.NoInlining)]
462+
private async Task<ExpiredHandlerTrackingEntry> SimulateClientUse_Factory_CleanupCycle_DisposesLiveHandler(
436463
TestHttpClientFactory factory,
437464
DisposeTrackingHandler disposeHandler)
438465
{

0 commit comments

Comments
 (0)