TimeoutCommand
TimeoutCommand creates a timer in order to cancel
a test if it exceeds a specified time and adjusts
the test result if it did time out.
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Abstractions;
using System.Runtime.CompilerServices;
using System.Threading;
namespace NUnit.Framework.Internal.Commands
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class TimeoutCommand : BeforeAndAfterTestCommand
{
private readonly int _timeout;
private readonly IDebugger _debugger;
[System.Runtime.CompilerServices.Nullable(2)]
private Timer _commandTimer;
private bool _commandTimedOut;
internal TimeoutCommand(TestCommand innerCommand, int timeout, IDebugger debugger)
: base(innerCommand)
{
_timeout = timeout;
_debugger = debugger;
Guard.ArgumentValid(innerCommand.Test is TestMethod, "TimeoutCommand may only apply to a TestMethod", "innerCommand");
Guard.ArgumentValid(timeout > 0, "Timeout value must be greater than zero", "timeout");
Guard.ArgumentNotNull(debugger, "debugger");
BeforeTest = delegate {
Thread testThread = Thread.CurrentThread;
int nativeThreadId = ThreadUtility.GetCurrentThreadNativeId();
_commandTimer = new Timer(delegate {
if (!_debugger.IsAttached) {
_commandTimedOut = true;
ThreadUtility.Abort(testThread, nativeThreadId);
}
}, null, timeout, -1);
};
AfterTest = delegate(TestExecutionContext context) {
_commandTimer?.Dispose();
if (_commandTimedOut) {
string message = $"""{timeout}""";
context.CurrentResult.SetResult(ResultState.Failure, message);
}
};
}
}
}