Skip to content

Commit

Permalink
Simplify handler GC tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hartez authored and PureWeen committed Jan 4, 2024
1 parent f7f3997 commit fe8a2e3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 89 deletions.
20 changes: 4 additions & 16 deletions src/Core/tests/DeviceTests/Memory/MemoryTestFixture.cs
@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;


namespace Microsoft.Maui.Handlers.Memory
{
public class MemoryTestFixture : IDisposable
{
Dictionary<Type, (WeakReference handler, WeakReference view)> _handlers
= new Dictionary<Type, (WeakReference handler, WeakReference view)>();
readonly Dictionary<Type, (WeakReference handler, WeakReference view)> _handlers = new();

public MemoryTestFixture()
{
Expand All @@ -20,24 +18,14 @@ public MemoryTestFixture()

public bool DoReferencesStillExist(Type handlerType)
{
WeakReference weakHandler;
WeakReference weakView;
(weakHandler, weakView) = _handlers[handlerType];


if (weakHandler.Target != null ||
weakHandler.IsAlive ||
weakView.Target != null ||
weakView.IsAlive)
{
return true;
}
(WeakReference weakHandler, WeakReference weakView) = _handlers[handlerType];

return false;
return weakHandler.IsAlive || weakView.IsAlive;
}

public void Dispose()
{
GC.SuppressFinalize(this);
_handlers.Clear();
}
}
Expand Down
31 changes: 0 additions & 31 deletions src/Core/tests/DeviceTests/Memory/MemoryTestOrdering.cs

This file was deleted.

61 changes: 19 additions & 42 deletions src/Core/tests/DeviceTests/Memory/MemoryTests.cs
@@ -1,21 +1,9 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Maui.DeviceTests;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Media;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
using static Microsoft.Maui.DeviceTests.AssertHelpers;


namespace Microsoft.Maui.Handlers.Memory
{
/// <summary>
Expand All @@ -35,52 +23,41 @@ public MemoryTests(MemoryTestFixture fixture)
_fixture = fixture;
}

[Theory]
[ClassData(typeof(MemoryTestTypes))]
public async Task Allocate((Type ViewType, Type HandlerType) data)
async Task Allocate((Type ViewType, Type HandlerType) data)
{

#if ANDROID
if (!OperatingSystem.IsAndroidVersionAtLeast(30))
return;
#endif

var handler = await InvokeOnMainThreadAsync(() => CreateHandler((IElement)Activator.CreateInstance(data.ViewType), data.HandlerType));
WeakReference weakHandler = new WeakReference(handler);
_fixture.AddReferences(data.HandlerType, (weakHandler, new WeakReference(handler.VirtualView)));
handler = null;
var view = handler.VirtualView;

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
WeakReference weakHandlerReference = new WeakReference(handler);
WeakReference weakViewReference = new WeakReference(view);

_fixture.AddReferences(data.HandlerType, (weakHandlerReference, weakViewReference));
}

[Theory]
[ClassData(typeof(MemoryTestTypes))]
public async Task CheckAllocation((Type ViewType, Type HandlerType) data)
{
// Arrange
await Allocate(data);

#if ANDROID
if (!OperatingSystem.IsAndroidVersionAtLeast(30))
return;
#endif

// This is mainly relevant when running inside the visual runner as a single test
if (!_fixture.HasType(data.HandlerType))
await Allocate(data);

bool referencesCollected()
async Task<bool> referencesCollected()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// Act
await Collect();

// Assert
return !_fixture.DoReferencesStillExist(data.HandlerType);
}

await AssertEventually(referencesCollected, timeout: 5000, message: $"{data.HandlerType} failed to collect.");
}

static async Task Collect()
{
await Task.Yield();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
21 changes: 21 additions & 0 deletions src/TestUtils/src/DeviceTests/AssertHelpers.cs
Expand Up @@ -27,6 +27,27 @@ public static async Task AssertEventually(Func<bool> assertion, int timeout = 10
}
}

public static async Task AssertEventually(Func<Task<bool>> assertion, int timeout = 1000, int interval = 100, string message = "Assertion timed out")
{
do
{
if (await assertion())
{
return;
}

await Task.Delay(interval);
timeout -= interval;

}
while (timeout >= 0);

if (! (await assertion()))
{
throw new XunitException(message);
}
}

public static async Task<bool> Wait(Func<bool> predicate, int timeout = 1000, int interval = 100)
{
do
Expand Down

0 comments on commit fe8a2e3

Please sign in to comment.