private static async Task <RunSummary> RunTestAsyncCore(XunitTestRunner runner,
                                                                IMessageBus messageBus,
                                                                ExceptionAggregator aggregator,
                                                                bool disableRetry)
        {
            try
            {
                DelayedMessageBus delayedMessageBus = null;
                RunSummary        summary           = null;

                // First run
                if (!disableRetry)
                {
                    // This is really the only tricky bit: we need to capture and delay messages (since those will
                    // contain run status) until we know we've decided to accept the final result;
                    delayedMessageBus = new DelayedMessageBus(messageBus);

                    runner.SetMessageBus(delayedMessageBus);
                    summary = await RunTestInternalAsync(runner);

                    // if succeeded
                    if (summary.Failed == 0 || aggregator.HasExceptions)
                    {
                        delayedMessageBus.Flush(false);
                        return(summary);
                    }
                }

                // Final run
                runner.SetMessageBus(new KuduTraceMessageBus(messageBus));
                summary = await RunTestInternalAsync(runner);

                // flush delay messages
                if (delayedMessageBus != null)
                {
                    delayedMessageBus.Flush(summary.Failed == 0 && !aggregator.HasExceptions);
                }

                return(summary);
            }
            catch (Exception ex)
            {
                // this is catastrophic
                messageBus.QueueMessage(new TestFailed(runner.GetTest(), 0, null, ex));

                return(new RunSummary {
                    Failed = 1, Total = 1
                });
            }
            finally
            {
                // set to original
                runner.SetMessageBus(messageBus);
            }
        }
        private static async Task<RunSummary> RunTestAsyncCore(XunitTestRunner runner,
                                                               IMessageBus messageBus,
                                                               ExceptionAggregator aggregator,
                                                               bool disableRetry)
        {
            try
            {
                DelayedMessageBus delayedMessageBus = null;
                RunSummary summary = null;

                // First run
                if (!disableRetry)
                {
                    // This is really the only tricky bit: we need to capture and delay messages (since those will
                    // contain run status) until we know we've decided to accept the final result;
                    delayedMessageBus = new DelayedMessageBus(messageBus);

                    runner.SetMessageBus(delayedMessageBus);
                    summary = await RunTestInternalAsync(runner);

                    // if succeeded
                    if (summary.Failed == 0 || aggregator.HasExceptions)
                    {
                        delayedMessageBus.Flush(false);
                        return summary;
                    }
                }

                // Final run
                runner.SetMessageBus(new KuduTraceMessageBus(messageBus));
                summary = await RunTestInternalAsync(runner);

                // flush delay messages
                if (delayedMessageBus != null)
                {
                    delayedMessageBus.Flush(summary.Failed == 0 && !aggregator.HasExceptions);
                }

                return summary;
            }
            catch (Exception ex)
            {
                // this is catastrophic
                messageBus.QueueMessage(new TestFailed(runner.GetTest(), 0, null, ex));

                return new RunSummary { Failed = 1, Total = 1 };
            }
            finally
            {
                // set to original
                runner.SetMessageBus(messageBus);
            }
        }
        public static async Task <RunSummary> RunTestAsync(XunitTestRunner runner,
                                                           IMessageBus messageBus,
                                                           ExceptionAggregator aggregator,
                                                           bool disableRetry)
        {
            // defense in depth to avoid forever lock
            bool acquired = await _semaphore.WaitAsync(TimeSpan.FromHours(2));

            try
            {
                DelayedMessageBus delayedMessageBus = null;
                RunSummary        summary           = null;

                if (!acquired)
                {
                    throw new TimeoutException("Wait for thread to run the test timeout!");
                }

                // First run
                if (!disableRetry)
                {
                    // This is really the only tricky bit: we need to capture and delay messages (since those will
                    // contain run status) until we know we've decided to accept the final result;
                    delayedMessageBus = new DelayedMessageBus(messageBus);

                    runner.SetMessageBus(delayedMessageBus);
                    summary = await RunTestInternalAsync(runner);

                    // if succeeded
                    if (summary.Failed == 0 || aggregator.HasExceptions)
                    {
                        delayedMessageBus.Flush(false);
                        return(summary);
                    }
                }

                // Final run
                runner.SetMessageBus(new KuduTraceMessageBus(messageBus));
                summary = await RunTestInternalAsync(runner);

                // flush delay messages
                if (delayedMessageBus != null)
                {
                    delayedMessageBus.Flush(summary.Failed == 0 && !aggregator.HasExceptions);
                }

                return(summary);
            }
            catch (Exception ex)
            {
                // this is catastrophic
                messageBus.QueueMessage(new TestFailed(runner.GetTest(), 0, null, ex));

                return(new RunSummary {
                    Failed = 1, Total = 1
                });
            }
            finally
            {
                if (acquired)
                {
                    _semaphore.Release();
                }

                // set to original
                runner.SetMessageBus(messageBus);
            }
        }
        public static async Task<RunSummary> RunTestAsync(XunitTestRunner runner,
                                                          IMessageBus messageBus,
                                                          ExceptionAggregator aggregator,
                                                          bool disableRetry)
        {
            // defense in depth to avoid forever lock
            bool acquired = await _semaphore.WaitAsync(TimeSpan.FromHours(2));

            try
            {
                DelayedMessageBus delayedMessageBus = null;
                RunSummary summary = null;

                if (!acquired)
                {
                    throw new TimeoutException("Wait for thread to run the test timeout!");
                }

                // First run
                if (!disableRetry)
                {
                    // This is really the only tricky bit: we need to capture and delay messages (since those will
                    // contain run status) until we know we've decided to accept the final result;
                    delayedMessageBus = new DelayedMessageBus(messageBus);

                    runner.SetMessageBus(delayedMessageBus);
                    summary = await RunTestInternalAsync(runner);

                    // if succeeded
                    if (summary.Failed == 0 || aggregator.HasExceptions)
                    {
                        delayedMessageBus.Flush(false);
                        return summary;
                    }
                }

                // Final run
                runner.SetMessageBus(new KuduTraceMessageBus(messageBus));
                summary = await RunTestInternalAsync(runner);

                // flush delay messages
                if (delayedMessageBus != null)
                {
                    delayedMessageBus.Flush(summary.Failed == 0 && !aggregator.HasExceptions);
                }

                return summary;
            }
            catch (Exception ex)
            {
                // this is catastrophic
                messageBus.QueueMessage(new TestFailed(runner.GetTest(), 0, null, ex));

                return new RunSummary { Failed = 1, Total = 1 };
            }
            finally
            {
                if (acquired)
                {
                    _semaphore.Release();
                }

                // set to original
                runner.SetMessageBus(messageBus);
            }
        }