public override void Execute() { try { if (!this.body().Wait(this.MillisecondsTimeout)) { throw new Xunit.Sdk.TimeoutException(this.MillisecondsTimeout); } } catch (AggregateException ex) { ExceptionUtility.RethrowWithNoStackTraceLoss(ex.InnerException); } finally { foreach (var disposable in this.ExtractDisposables) { CurrentScenario.AddTeardown(() => disposable.Dispose()); } foreach (var teardown in this.Teardowns) { CurrentScenario.AddTeardown(teardown); } } }
// TODO (adamralph): before the SDK goes public, remove the magic Booleans for continueOnFailureStepType and make it generic // TODO (adamralph): provide overload with out continueOnFailureStepType public IEnumerable <ITestCommand> CreateCommands(int contextOrdinal, object continueOnFailureStepType) { var continueOnFailure = continueOnFailureStepType as bool?; var stepOrdinal = 1; foreach (var step in this.steps) { var stepBeginsContinueOnFailure = continueOnFailure ?? (continueOnFailureStepType != null && continueOnFailureStepType.Equals(step.StepType)); yield return(new StepCommand(this.methodCall, contextOrdinal, stepOrdinal++, step, stepBeginsContinueOnFailure)); } FailedStepName = null; ShouldContinueOnFailure = continueOnFailure == true; // NOTE: this relies on the test runner executing each above yielded step command and below yielded disposal command as soon as it is recieved // TD.NET, R# and xunit.console all seem to do this var odd = true; while (true) { var teardowns = CurrentScenario.ExtractTeardowns().ToArray(); if (!teardowns.Any()) { break; } // don't reverse even disposables since their creation order has already been reversed by the previous command yield return(new TeardownCommand(this.methodCall, contextOrdinal, stepOrdinal++, odd ? teardowns.Reverse() : teardowns)); odd = !odd; } }
public override void Execute() { try { Exception exception = null; var @event = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(o => { var oldSyncContext = SynchronizationContext.Current; using (var syncContext = new AsyncTestSyncContext()) { SynchronizationContext.SetSynchronizationContext(syncContext); try { this.body.Invoke(); exception = syncContext.WaitForCompletion(); } catch (Exception ex) { exception = ex; } finally { SynchronizationContext.SetSynchronizationContext(oldSyncContext); @event.Set(); } } }); // NOTE: we do not call the WaitOne(int) overload because it wasn't introduced until .NET 3.5 SP1 and we want to support pre-SP1 if ([email protected](this.MillisecondsTimeout, false)) { throw new Xunit.Sdk.TimeoutException(this.MillisecondsTimeout); } if (exception != null) { ExceptionUtility.RethrowWithNoStackTraceLoss(exception); } } finally { foreach (var disposable in this.ExtractDisposables) { CurrentScenario.AddTeardown(() => disposable.Dispose()); } foreach (var teardown in this.Teardowns) { CurrentScenario.AddTeardown(teardown); } } }