22// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33
44using System ;
5+ using System . Collections . Concurrent ;
56using System . Collections . Generic ;
67using System . Diagnostics . CodeAnalysis ;
78using System . Globalization ;
@@ -288,33 +289,40 @@ private class ClassCleanupManager
288289 private readonly ClassCleanupBehavior ? _lifecycleFromMsTest ;
289290 private readonly ClassCleanupBehavior _lifecycleFromAssembly ;
290291 private readonly ReflectHelper _reflectHelper ;
291- private readonly Dictionary < string , HashSet < string > > _remainingTestsByClass ;
292+ private readonly ConcurrentDictionary < string , HashSet < string > > _remainingTestsByClass ;
292293
293294 public ClassCleanupManager (
294295 IEnumerable < UnitTestElement > testsToRun ,
295296 ClassCleanupBehavior ? lifecycleFromMsTest ,
296297 ClassCleanupBehavior lifecycleFromAssembly ,
297298 ReflectHelper ? reflectHelper = null )
298299 {
299- _remainingTestsByClass = testsToRun . GroupBy ( t => t . TestMethod . FullClassName )
300- . ToDictionary (
301- g => g . Key ,
302- g => new HashSet < string > ( g . Select ( t => t . TestMethod . UniqueName ) ) ) ;
300+ _remainingTestsByClass =
301+ new ( testsToRun . GroupBy ( t => t . TestMethod . FullClassName )
302+ . ToDictionary (
303+ g => g . Key ,
304+ g => new HashSet < string > ( g . Select ( t => t . TestMethod . UniqueName ) ) ) ) ;
303305 _lifecycleFromMsTest = lifecycleFromMsTest ;
304306 _lifecycleFromAssembly = lifecycleFromAssembly ;
305307 _reflectHelper = reflectHelper ?? new ReflectHelper ( ) ;
306308 }
307309
308- public void MarkTestComplete ( TestMethodInfo testMethodInfo , TestMethod testMethod , out bool shouldRunEndOfClassCleanup , out bool shouldRunEndOfAssemblyCleanup )
310+ public void MarkTestComplete ( TestMethodInfo testMethodInfo , TestMethod testMethod , out bool shouldRunEndOfClassCleanup ,
311+ out bool shouldRunEndOfAssemblyCleanup )
309312 {
310313 shouldRunEndOfClassCleanup = false ;
311- var testsByClass = _remainingTestsByClass [ testMethodInfo . TestClassName ] ;
314+ shouldRunEndOfAssemblyCleanup = false ;
315+ if ( ! _remainingTestsByClass . TryGetValue ( testMethodInfo . TestClassName , out var testsByClass ) )
316+ {
317+ return ;
318+ }
319+
312320 lock ( testsByClass )
313321 {
314322 testsByClass . Remove ( testMethod . UniqueName ) ;
315323 if ( testsByClass . Count == 0 )
316324 {
317- _remainingTestsByClass . Remove ( testMethodInfo . TestClassName ) ;
325+ _remainingTestsByClass . TryRemove ( testMethodInfo . TestClassName , out _ ) ;
318326 if ( testMethodInfo . Parent . HasExecutableCleanupMethod )
319327 {
320328 var cleanupLifecycle = _reflectHelper . GetClassCleanupBehavior ( testMethodInfo . Parent )
@@ -325,7 +333,7 @@ public void MarkTestComplete(TestMethodInfo testMethodInfo, TestMethod testMetho
325333 }
326334 }
327335
328- shouldRunEndOfAssemblyCleanup = _remainingTestsByClass . Count == 0 ;
336+ shouldRunEndOfAssemblyCleanup = _remainingTestsByClass . IsEmpty ;
329337 }
330338 }
331339 }
0 commit comments