From 8e95fc5ca7bf6b90233fcd8249af7d274c62a8de Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 04:38:15 +0000 Subject: [PATCH 1/3] perf: eliminate yield-iterator state machine in PropertyBag.OfType() Replace the yield-based iterator from Property.OfType() with a direct linked-list walk inside PropertyBag.OfType(). Before: _property.OfType() (yield return) allocates one state- machine heap object per call, even when no matching property is found. After: direct while-loop walk; no state-machine allocated; returns [] for the common case (no matching property) with zero heap allocations beyond the empty array constant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Messages/PropertyBag.cs | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs index 36f3a940d0..01c98c6b0f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs @@ -274,9 +274,38 @@ public TProperty[] OfType() } // We don't want to allocate an array if we know that we're looking for a TestNodeStateProperty - return typeof(TestNodeStateProperty).IsAssignableFrom(typeof(TProperty)) + if (typeof(TestNodeStateProperty).IsAssignableFrom(typeof(TProperty)) || _property is null) + { + return []; + } + + // Direct linked-list walk: avoids allocating a yield-iterator state machine + // (the original code called _property.OfType() which uses yield return). + TProperty? first = default; + bool foundAny = false; + List? overflow = null; + Property? current = _property; + while (current is not null) + { + if (current.Current is TProperty match) + { + if (!foundAny) + { + first = match; + foundAny = true; + } + else + { + (overflow ??= [first!]).Add(match); + } + } + + current = current.Next; + } + + return !foundAny ? [] - : _property is null ? [] : [.. _property.OfType()]; + : overflow is not null ? [.. overflow] : [first!]; } /// From 911b697f5962362862b988d70dc2d71cbf1dcb91 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:15:16 +0000 Subject: [PATCH 2/3] test: add coverage tests for OfType() edge cases in PropertyBagTests Agent-Logs-Url: https://github.com/microsoft/testfx/sessions/7ea4b52b-3b29-47b2-a116-5af4cdd3b156 Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../Messages/PropertyBagTests.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs index 9f9a42a4de..d38ecffcbe 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs @@ -121,6 +121,33 @@ public void OfType_Should_Return_CorrectObject() Assert.AreEqual(PassedTestNodeStateProperty.CachedInstance, property.OfType().Single()); Assert.HasCount(2, property.OfType()); + + // No DummyProperty2 in the bag — exercises the "no match found" path in the while-loop + Assert.IsEmpty(property.OfType()); + } + + [TestMethod] + public void OfType_WithSingleMatch_ReturnsSingleItemArray() + { + PropertyBag bag = new(); + DummyProperty single = new(); + bag.Add(single); + bag.Add(PassedTestNodeStateProperty.CachedInstance); + + DummyProperty[] result = bag.OfType(); + + Assert.HasCount(1, result); + Assert.AreSame(single, result[0]); + } + + [TestMethod] + public void OfType_WithOnlyTestNodeStateProperty_ReturnsEmpty() + { + PropertyBag property = new(); + property.Add(PassedTestNodeStateProperty.CachedInstance); + + // _property is null; _testNodeStateProperty is set — exercises the new early-return path + Assert.IsEmpty(property.OfType()); } [TestMethod] From 813c70531831587465e341acbeaa815351efe7e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:16:03 +0000 Subject: [PATCH 3/3] test: fix variable naming in PropertyBagTests for consistency Agent-Logs-Url: https://github.com/microsoft/testfx/sessions/7ea4b52b-3b29-47b2-a116-5af4cdd3b156 Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../Messages/PropertyBagTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs index d38ecffcbe..8c6aed9105 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs @@ -129,15 +129,15 @@ public void OfType_Should_Return_CorrectObject() [TestMethod] public void OfType_WithSingleMatch_ReturnsSingleItemArray() { - PropertyBag bag = new(); - DummyProperty single = new(); - bag.Add(single); - bag.Add(PassedTestNodeStateProperty.CachedInstance); + PropertyBag property = new(); + DummyProperty singleProperty = new(); + property.Add(singleProperty); + property.Add(PassedTestNodeStateProperty.CachedInstance); - DummyProperty[] result = bag.OfType(); + DummyProperty[] result = property.OfType(); Assert.HasCount(1, result); - Assert.AreSame(single, result[0]); + Assert.AreSame(singleProperty, result[0]); } [TestMethod]