-
Notifications
You must be signed in to change notification settings - Fork 293
perf: use Lock, FrozenDictionary, Span, and throw helpers on NET8+/NET9+ #7977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,29 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <Dependencies> | ||
| <ToolsetDependencies> | ||
| <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="11.0.0-beta.26229.1"> | ||
| <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="11.0.0-beta.26230.2"> | ||
| <Uri>https://github.com/dotnet/arcade</Uri> | ||
| <Sha>3ed6c23fee67b840de0fb5473ea6a95fc667b0a9</Sha> | ||
| <Sha>8a7b2d3d39078db20f33067c7929b88fdff4ee63</Sha> | ||
| </Dependency> | ||
| <Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="11.0.0-beta.26229.1"> | ||
| <Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="11.0.0-beta.26230.2"> | ||
| <Uri>https://github.com/dotnet/arcade</Uri> | ||
| <Sha>3ed6c23fee67b840de0fb5473ea6a95fc667b0a9</Sha> | ||
| <Sha>8a7b2d3d39078db20f33067c7929b88fdff4ee63</Sha> | ||
| </Dependency> | ||
| <Dependency Name="Microsoft.DotNet.XliffTasks" Version="11.0.0-beta.26229.1"> | ||
| <Dependency Name="Microsoft.DotNet.XliffTasks" Version="11.0.0-beta.26230.2"> | ||
| <Uri>https://github.com/dotnet/arcade</Uri> | ||
| <Sha>3ed6c23fee67b840de0fb5473ea6a95fc667b0a9</Sha> | ||
| <Sha>8a7b2d3d39078db20f33067c7929b88fdff4ee63</Sha> | ||
| </Dependency> | ||
| <Dependency Name="Microsoft.Testing.Extensions.CodeCoverage" Version="18.8.0-preview.26229.1"> | ||
| <Uri>https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage</Uri> | ||
| <Sha>6b29c14c934bae1e26c21961b7e5ad1a25c4d3c5</Sha> | ||
| </Dependency> | ||
| <Dependency Name="MSTest" Version="4.3.0-preview.26229.1"> | ||
| <Dependency Name="MSTest" Version="4.3.0-preview.26230.4"> | ||
| <Uri>https://github.com/microsoft/testfx</Uri> | ||
| <Sha>0da10c24091f1ad35610ac05dd5aa7bd3ea79dd5</Sha> | ||
| <Sha>e6af9df44f1c17bcae2798b15388641609add3a3</Sha> | ||
| </Dependency> | ||
| <Dependency Name="Microsoft.Testing.Platform" Version="2.3.0-preview.26229.1"> | ||
| <Dependency Name="Microsoft.Testing.Platform" Version="2.3.0-preview.26230.4"> | ||
| <Uri>https://github.com/microsoft/testfx</Uri> | ||
| <Sha>0da10c24091f1ad35610ac05dd5aa7bd3ea79dd5</Sha> | ||
| <Sha>e6af9df44f1c17bcae2798b15388641609add3a3</Sha> | ||
| </Dependency> | ||
| </ToolsetDependencies> | ||
| </Dependencies> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # `eng/common` | ||
|
|
||
| Files under `eng/common` come from [Arcade](https://github.com/dotnet/arcade). | ||
| Edits in `eng/common` will be overwritten by automation unless the changes are made directly in the Arcade repository. | ||
| For more information, see the [Arcade documentation](https://github.com/dotnet/arcade/tree/main/Documentation). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,28 +5,57 @@ | |
| using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; | ||
| using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
| #if NET8_0_OR_GREATER | ||
| using System.Runtime.CompilerServices; | ||
|
Check failure on line 9 in src/Adapter/MSTestAdapter.PlatformServices/Execution/ClassCleanupManager.cs
|
||
| using System.Runtime.InteropServices; | ||
| #endif | ||
|
|
||
| namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; | ||
|
|
||
| internal sealed class ClassCleanupManager | ||
| { | ||
| private readonly ConcurrentDictionary<string, int> _remainingTestCountsByClass; | ||
| #if NET9_0_OR_GREATER | ||
| private readonly Lock _lock = new(); | ||
| #else | ||
| private readonly object _lock = new(); | ||
| #endif | ||
| private readonly Dictionary<string, int> _remainingTestCountsByClass; | ||
|
|
||
| public ClassCleanupManager(IEnumerable<UnitTestElement> testsToRun) | ||
| { | ||
| _remainingTestCountsByClass = | ||
| new(testsToRun.GroupBy(t => t.TestMethod.FullClassName) | ||
| testsToRun.GroupBy(t => t.TestMethod.FullClassName) | ||
| .ToDictionary( | ||
| g => g.Key, | ||
| g => g.Count())); | ||
| g => g.Count()); | ||
| } | ||
|
|
||
| public bool ShouldRunEndOfAssemblyCleanup => _remainingTestCountsByClass.IsEmpty; | ||
| public bool ShouldRunEndOfAssemblyCleanup | ||
| { | ||
| get | ||
| { | ||
| lock (_lock) | ||
| { | ||
| return _remainingTestCountsByClass.Count == 0; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public void MarkTestComplete(TestMethod testMethod, out bool isLastTestInClass) | ||
| { | ||
| lock (_remainingTestCountsByClass) | ||
| lock (_lock) | ||
| { | ||
| #if NET8_0_OR_GREATER | ||
| ref int remainingCount = ref CollectionsMarshal.GetValueRefOrNullRef( | ||
| _remainingTestCountsByClass, testMethod.FullClassName); | ||
| if (Unsafe.IsNullRef(ref remainingCount)) | ||
| { | ||
| throw ApplicationStateGuard.Unreachable(); | ||
| } | ||
|
|
||
| remainingCount--; | ||
| isLastTestInClass = remainingCount == 0; | ||
| #else | ||
| if (!_remainingTestCountsByClass.TryGetValue(testMethod.FullClassName, out int remainingCount)) | ||
| { | ||
| throw ApplicationStateGuard.Unreachable(); | ||
|
|
@@ -35,20 +64,23 @@ | |
| remainingCount--; | ||
| _remainingTestCountsByClass[testMethod.FullClassName] = remainingCount; | ||
| isLastTestInClass = remainingCount == 0; | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
| public void MarkClassComplete(string fullClassName) | ||
| { | ||
| lock (_remainingTestCountsByClass) | ||
| lock (_lock) | ||
| { | ||
| if (!_remainingTestCountsByClass.TryRemove(fullClassName, out int remainingTests) || | ||
| if (!_remainingTestCountsByClass.TryGetValue(fullClassName, out int remainingTests) || | ||
| remainingTests != 0) | ||
| { | ||
| // We failed to remove the class, or we are incorrectly marking the class as complete while there are remaining tests. | ||
| // We failed to find the class, or we are incorrectly marking the class as complete while there are remaining tests. | ||
| // This should never happen. | ||
| throw ApplicationStateGuard.Unreachable(); | ||
| } | ||
|
|
||
| _remainingTestCountsByClass.Remove(fullClassName); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,11 @@ | |
| internal static class RandomId | ||
| { | ||
| private const string Pool = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
| #if NET9_0_OR_GREATER | ||
| private static readonly Lock s_lock = new(); | ||
| #else | ||
| private static readonly object s_lock = new(); | ||
|
Check failure on line 18 in src/Platform/Microsoft.Testing.Extensions.Retry/RandomId.cs
|
||
| #endif | ||
| private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create(); | ||
|
|
||
| /// <summary> | ||
|
|
@@ -23,7 +28,7 @@ | |
| { | ||
| int poolLength = Pool.Length; | ||
| char[] id = new char[length]; | ||
| lock (Pool) | ||
| lock (s_lock) | ||
| { | ||
| for (int idIndex = 0; idIndex < length; idIndex++) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SupportedNetFrameworksis changed fromnet8.0;net9.0tonet8.0;net10.0, which drops the net9.0 build across projects that use this property (and adds a net10.0 build requirement). If net9.0 support is still intended, consider keeping it here or clarifying/updating the PR description/TFM strategy accordingly.