Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions TUnit.Core/Tracking/ObjectTracker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using TUnit.Core.Helpers;

Expand Down Expand Up @@ -48,12 +49,17 @@ private static Counter GetOrCreateCounter(object obj) =>
s_trackedObjects.GetOrAdd(obj, static _ => new Counter());

/// <summary>
/// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single HashSet.
/// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single ISet.
/// Thread-safe: locks each HashSet while copying.
/// Pre-calculates capacity to avoid HashSet resizing during population.
/// </summary>
private static HashSet<object> FlattenTrackedObjects(ConcurrentDictionary<int, HashSet<object>> trackedObjects)
private static ISet<object> FlattenTrackedObjects(ConcurrentDictionary<int, HashSet<object>> trackedObjects)
{
if (trackedObjects.IsEmpty)
{
return ImmutableHashSet<object>.Empty;
}

#if NETSTANDARD2_0
// .NET Standard 2.0 doesn't support HashSet capacity constructor
var result = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
Expand Down Expand Up @@ -91,8 +97,13 @@ public void TrackObjects(TestContext testContext)
var alreadyTracked = FlattenTrackedObjects(testContext.TrackedObjects);

// Get new trackable objects
var newTrackableObjects = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
var trackableDict = trackableObjectGraphProvider.GetTrackableObjects(testContext);
if (trackableDict.IsEmpty && alreadyTracked.Count == 0)
{
return;
}

var newTrackableObjects = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
foreach (var kvp in trackableDict)
{
lock (kvp.Value)
Expand All @@ -113,11 +124,20 @@ public void TrackObjects(TestContext testContext)
}
}

public async ValueTask UntrackObjects(TestContext testContext, List<Exception> cleanupExceptions)
public ValueTask UntrackObjects(TestContext testContext, List<Exception> cleanupExceptions)
{
// Get all objects to untrack (DRY: use helper method)
var objectsToUntrack = FlattenTrackedObjects(testContext.TrackedObjects);
if (objectsToUntrack.Count == 0)
{
return ValueTask.CompletedTask;
}

return UntrackObjectsAsync(cleanupExceptions, objectsToUntrack);
}

private async ValueTask UntrackObjectsAsync(List<Exception> cleanupExceptions, ISet<object> objectsToUntrack)
{
foreach (var obj in objectsToUntrack)
{
try
Expand Down
Loading