diff --git a/TUnit.Engine/Helpers/HookTimeoutHelper.cs b/TUnit.Engine/Helpers/HookTimeoutHelper.cs index 155b6c34a1..d252c37f2e 100644 --- a/TUnit.Engine/Helpers/HookTimeoutHelper.cs +++ b/TUnit.Engine/Helpers/HookTimeoutHelper.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using TUnit.Core; using TUnit.Core.Hooks; using TUnit.Core.Interfaces; @@ -12,7 +13,7 @@ internal static class HookTimeoutHelper /// /// Creates a timeout-aware action wrapper for a hook /// - public static Func CreateTimeoutHookAction( + public static Task CreateTimeoutHookAction( StaticHookMethod hook, T context, CancellationToken cancellationToken) @@ -24,13 +25,20 @@ public static Func CreateTimeoutHookAction( if (timeout == null) { // No timeout specified, execute with potential custom executor - return async () => await ExecuteHookWithPotentialCustomExecutor(hook, context, cancellationToken); + return ExecuteHookWithPotentialCustomExecutor(hook, context, cancellationToken).AsTask(); } - return async () => + var timeoutMs = (int)timeout.Value.TotalMilliseconds; + + return CreateTimeoutHookActionAsync(hook, context, timeoutMs, cancellationToken); + + static async Task CreateTimeoutHookActionAsync( + StaticHookMethod hook, + T context, + int timeoutMs, + CancellationToken cancellationToken) { using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var timeoutMs = (int)timeout.Value.TotalMilliseconds; cts.CancelAfter(timeoutMs); try @@ -41,7 +49,7 @@ public static Func CreateTimeoutHookAction( { throw new TimeoutException($"Hook '{hook.Name}' exceeded timeout of {timeoutMs}ms"); } - }; + } } /// @@ -58,19 +66,11 @@ private static ValueTask ExecuteHookWithPotentialCustomExecutor(StaticHookMet // Determine which executor method to call based on hook type if (hook is BeforeTestHookMethod || hook is InstanceHookMethod) { - return customExecutor.ExecuteBeforeTestHook( - hook.MethodInfo, - testContext, - () => hook.Body!.Invoke(context, cancellationToken) - ); + return ExecuteBeforeTestHook(hook, context, cancellationToken, customExecutor, testContext); } else if (hook is AfterTestHookMethod) { - return customExecutor.ExecuteAfterTestHook( - hook.MethodInfo, - testContext, - () => hook.Body!.Invoke(context, cancellationToken) - ); + return ExecuteAfterTestHook(hook, context, cancellationToken, customExecutor, testContext); } } @@ -78,6 +78,22 @@ private static ValueTask ExecuteHookWithPotentialCustomExecutor(StaticHookMet return hook.ExecuteAsync(context, cancellationToken); } + private static ValueTask ExecuteBeforeTestHook(StaticHookMethod hook, [DisallowNull] T context, + CancellationToken cancellationToken, IHookExecutor customExecutor, TestContext testContext) => + customExecutor.ExecuteBeforeTestHook( + hook.MethodInfo, + testContext, + () => hook.Body!.Invoke(context, cancellationToken) + ); + + private static ValueTask ExecuteAfterTestHook(StaticHookMethod hook, [DisallowNull] T context, + CancellationToken cancellationToken, IHookExecutor customExecutor, TestContext testContext) => + customExecutor.ExecuteAfterTestHook( + hook.MethodInfo, + testContext, + () => hook.Body!.Invoke(context, cancellationToken) + ); + /// /// Creates a timeout-aware action wrapper for a hook delegate /// @@ -94,10 +110,11 @@ public static Func CreateTimeoutHookAction( return async () => await hookDelegate(context, cancellationToken); } + var timeoutMs = (int)timeout.Value.TotalMilliseconds; + return async () => { using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var timeoutMs = (int)timeout.Value.TotalMilliseconds; cts.CancelAfter(timeoutMs); try @@ -129,10 +146,11 @@ public static Func CreateTimeoutHookAction( return async () => await hookDelegate(context, cancellationToken); } + var timeoutMs = (int)timeout.Value.TotalMilliseconds; + return async () => { using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var timeoutMs = (int)timeout.Value.TotalMilliseconds; cts.CancelAfter(timeoutMs); try @@ -145,4 +163,4 @@ public static Func CreateTimeoutHookAction( } }; } -} \ No newline at end of file +} diff --git a/TUnit.Engine/Services/HookCollectionService.cs b/TUnit.Engine/Services/HookCollectionService.cs index 559f0bffaa..a43db03478 100644 --- a/TUnit.Engine/Services/HookCollectionService.cs +++ b/TUnit.Engine/Services/HookCollectionService.cs @@ -704,27 +704,20 @@ private async Task> CreateStaticHookD // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => - { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( - hook, - context, - cancellationToken); - - await timeoutAction(); - }; + return (context, cancellationToken) => HookTimeoutHelper.CreateTimeoutHookAction( + hook, + context, + cancellationToken); } private static Func CreateClassHookDelegate(StaticHookMethod hook) { - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } @@ -733,27 +726,23 @@ private async Task> CreateClassH // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } private static Func CreateAssemblyHookDelegate(StaticHookMethod hook) { - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } @@ -762,27 +751,23 @@ private async Task> CreateAss // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } private static Func CreateTestSessionHookDelegate(StaticHookMethod hook) { - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } @@ -791,27 +776,23 @@ private async Task> CreateTest // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } private static Func CreateBeforeTestDiscoveryHookDelegate(StaticHookMethod hook) { - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } @@ -820,27 +801,23 @@ private async Task> Cr // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } private static Func CreateTestDiscoveryHookDelegate(StaticHookMethod hook) { - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; } @@ -849,14 +826,12 @@ private async Task> CreateTe // Process hook registration event receivers await ProcessHookRegistrationAsync(hook); - return async (context, cancellationToken) => + return (context, cancellationToken) => { - var timeoutAction = HookTimeoutHelper.CreateTimeoutHookAction( + return HookTimeoutHelper.CreateTimeoutHookAction( hook, context, cancellationToken); - - await timeoutAction(); }; }