Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeoutCommand"/> class.
        /// </summary>
        /// <param name="innerCommand">The inner command</param>
        /// <param name="timeout">Timeout value</param>
        /// <param name="debugger">An <see cref="IDebugger" /> instance</param>
        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", nameof(innerCommand));
            Guard.ArgumentValid(timeout > 0, "Timeout value must be greater than zero", nameof(timeout));
            Guard.ArgumentNotNull(debugger, nameof(debugger));

#if THREAD_ABORT
            BeforeTest = (context) =>
            {
                var testThread     = Thread.CurrentThread;
                var nativeThreadId = ThreadUtility.GetCurrentThreadNativeId();

                // Create a timer to cancel the current thread
                _commandTimer = new Timer(
                    (o) =>
                {
                    if (_debugger.IsAttached)
                    {
                        return;
                    }

                    _commandTimedOut = true;
                    ThreadUtility.Abort(testThread, nativeThreadId);
                    // No join here, since the thread doesn't really terminate
                },
                    null,
                    timeout,
                    Timeout.Infinite);
            };

            AfterTest = (context) =>
            {
                _commandTimer.Dispose();

                // If the timer cancelled the current thread, change the result
                if (_commandTimedOut)
                {
                    string message = $"Test exceeded Timeout value of {timeout}ms";

                    context.CurrentResult.SetResult(
                        new ResultState(TestStatus.Failed, message),
                        message);
                }
            };
#else
            BeforeTest = _ => { };
            AfterTest  = _ => { };
#endif
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeoutCommand"/> class.
        /// </summary>
        /// <param name="innerCommand">The inner command</param>
        /// <param name="timeout">Timeout value</param>
        public TimeoutCommand(TestCommand innerCommand, int timeout) : base(innerCommand)
        {
            _timeout = timeout;
            Guard.ArgumentValid(innerCommand.Test is TestMethod, "TimeoutCommand may only apply to a TestMethod", nameof(innerCommand));
            Guard.ArgumentValid(timeout > 0, "Timeout value must be greater than zero", nameof(timeout));

#if THREAD_ABORT
            BeforeTest = (context) =>
            {
                var testThread     = Thread.CurrentThread;
                var nativeThreadId = ThreadUtility.GetCurrentThreadNativeId();

                // Create a timer to cancel the current thread
                _commandTimer = new Timer(
                    (o) =>
                {
                    _commandTimedOut = true;
                    ThreadUtility.Abort(testThread, nativeThreadId);
                    // No join here, since the thread doesn't really terminate
                },
                    null,
                    timeout,
                    Timeout.Infinite);
            };

            AfterTest = (context) =>
            {
                _commandTimer.Dispose();

                // If the timer cancelled the current thread, change the result
                if (_commandTimedOut)
                {
                    context.CurrentResult.SetResult(ResultState.Failure, $"Test exceeded Timeout value of {timeout}ms");
                }
            };
#else
            BeforeTest = _ => { };
            AfterTest  = _ => { };
#endif
        }