Permalink
Browse files

Made the whole test execution synchronous

  • Loading branch information...
pawelpabich committed May 13, 2014
1 parent 77d79aa commit 6a0965c9e4c371405a95b5f6c66ab9c044e609b8
Showing with 103 additions and 88 deletions.
  1. +103 −88 src/xunit.execution/Sdk/Frameworks/XunitTestCase.cs
@@ -426,141 +426,120 @@ protected virtual Task RunTestsAsync(IMessageBus messageBus, object[] constructo
var aggregator = new ExceptionAggregator(parentAggregator);
var output = String.Empty; // TODO: Add output facilities for v2
if (!messageBus.QueueMessage(new TestStarting(this, displayName)))
cancellationTokenSource.Cancel();
if (!messageBus.QueueMessage(new TestStarting(this, displayName))) cancellationTokenSource.Cancel();
else
{
if (!String.IsNullOrEmpty(SkipReason))
{
if (!messageBus.QueueMessage(new TestSkipped(this, displayName, SkipReason)))
cancellationTokenSource.Cancel();
if (!messageBus.QueueMessage(new TestSkipped(this, displayName, SkipReason))) cancellationTokenSource.Cancel();
}
else
{
var beforeAttributesRun = new Stack<BeforeAfterTestAttribute>();
if (!aggregator.HasExceptions)
await aggregator.RunAsync(async () =>
aggregator.Run(() =>
{
object testClass = null;
if (!methodUnderTest.IsStatic)
{
if (!messageBus.QueueMessage(new TestClassConstructionStarting(this, displayName)))
cancellationTokenSource.Cancel();
try
{
if (!cancellationTokenSource.IsCancellationRequested)
{
executionTime.MeassureStep(() => testClass = Activator.CreateInstance(classUnderTest, constructorArguments));
}
}
finally
{
if (!messageBus.QueueMessage(new TestClassConstructionFinished(this, displayName)))
cancellationTokenSource.Cancel();
}
}
testClass = CreateTest(messageBus, classUnderTest, constructorArguments, methodUnderTest, displayName, cancellationTokenSource, executionTime);
if (!cancellationTokenSource.IsCancellationRequested)
{
await aggregator.RunAsync(async () =>
foreach (var beforeAfterAttribute in beforeAfterAttributes)
{
foreach (var beforeAfterAttribute in beforeAfterAttributes)
var attributeName = beforeAfterAttribute.GetType().Name;
if (!messageBus.QueueMessage(new BeforeTestStarting(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
else
{
var attributeName = beforeAfterAttribute.GetType().Name;
if (!messageBus.QueueMessage(new BeforeTestStarting(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
else
try
{
try
{
executionTime.MeassureStep(() => beforeAfterAttribute.Before(methodUnderTest));
beforeAttributesRun.Push(beforeAfterAttribute);
}
finally
{
if (!messageBus.QueueMessage(new BeforeTestFinished(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
}
executionTime.MeassureStep(() => beforeAfterAttribute.Before(methodUnderTest));
beforeAttributesRun.Push(beforeAfterAttribute);
}
finally
{
if (!messageBus.QueueMessage(new BeforeTestFinished(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
}
if (cancellationTokenSource.IsCancellationRequested)
return;
}
if (!cancellationTokenSource.IsCancellationRequested)
if (cancellationTokenSource.IsCancellationRequested)
return;
}
if (!cancellationTokenSource.IsCancellationRequested)
{
var parameterTypes = methodUnderTest.GetParameters().Select(p => p.ParameterType).ToArray();
var oldSyncContext = SynchronizationContext.Current;
try
{
var parameterTypes = methodUnderTest.GetParameters().Select(p => p.ParameterType).ToArray();
var oldSyncContext = SynchronizationContext.Current;
var asyncSyncContext = new AsyncTestSyncContext();
SetSynchronizationContext(asyncSyncContext);
try
aggregator.Run(() =>
{
var asyncSyncContext = new AsyncTestSyncContext();
SetSynchronizationContext(asyncSyncContext);
var result = executionTime.MeassureStep(() => methodUnderTest.Invoke(testClass, Reflector.ConvertArguments(testMethodArguments, parameterTypes)));
await aggregator.RunAsync(async () =>
var task = result as Task;
executionTime.MeassureStep(() =>
{
await executionTime.MeassureStepAsync(async () =>
//Hack: Calling wait to make sure the whole test is executed on the same thread from the beginning to the end
// There must a better way of doing this ...
if (task != null) task.Wait();
else
{
var result = methodUnderTest.Invoke(testClass, Reflector.ConvertArguments(testMethodArguments, parameterTypes));
var task = result as Task;
if (task != null)
await task;
else
{
var ex = await asyncSyncContext.WaitForCompletionAsync();
if (ex != null)
aggregator.Add(ex);
}
});
var waitForCompletion = asyncSyncContext.WaitForCompletionAsync();
waitForCompletion.Wait();
var ex = waitForCompletion.Result;
if (ex != null) aggregator.Add(ex);
}
});
}
finally
{
SetSynchronizationContext(oldSyncContext);
}
});
}
finally
{
SetSynchronizationContext(oldSyncContext);
}
});
}
foreach (var beforeAfterAttribute in beforeAttributesRun)
{
var attributeName = beforeAfterAttribute.GetType().Name;
if (!messageBus.QueueMessage(new AfterTestStarting(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
aggregator.Run(() => executionTime.MeassureStep(() => beforeAfterAttribute.After(methodUnderTest)));
executionTime.MeassureStep(() => beforeAfterAttribute.After(methodUnderTest));
if (!messageBus.QueueMessage(new AfterTestFinished(this, displayName, attributeName)))
cancellationTokenSource.Cancel();
}
}
aggregator.Run(() =>
var disposable = testClass as IDisposable;
if (disposable != null)
{
var disposable = testClass as IDisposable;
if (disposable != null)
{
if (!messageBus.QueueMessage(new TestClassDisposeStarting(this, displayName)))
cancellationTokenSource.Cancel();
if (!messageBus.QueueMessage(new TestClassDisposeStarting(this, displayName)))
cancellationTokenSource.Cancel();
try
{
executionTime.MeassureStep(() =>
{
NotifyTestIfRequired(displayName, disposable, executionTime, aggregator, output);
disposable.Dispose();
});
}
finally
try
{
executionTime.MeassureStep(() =>
{
if (!messageBus.QueueMessage(new TestClassDisposeFinished(this, displayName)))
cancellationTokenSource.Cancel();
}
NotifyTestIfRequired(displayName, disposable, executionTime, aggregator, output);
disposable.Dispose();
});
}
finally
{
if (!messageBus.QueueMessage(new TestClassDisposeFinished(this, displayName)))
cancellationTokenSource.Cancel();
}
});
}
});
if (!cancellationTokenSource.IsCancellationRequested)
@@ -578,6 +557,32 @@ protected virtual Task RunTestsAsync(IMessageBus messageBus, object[] constructo
return executionTime.TotalSeconds;
}
private object CreateTest(IMessageBus messageBus, Type classUnderTest, object[] constructorArguments,
MethodInfo methodUnderTest, string displayName, CancellationTokenSource cancellationTokenSource,
ExecutionTime executionTime)
{
object testClass = null;
if (!methodUnderTest.IsStatic)
{
if (!messageBus.QueueMessage(new TestClassConstructionStarting(this, displayName)))
cancellationTokenSource.Cancel();
try
{
if (!cancellationTokenSource.IsCancellationRequested)
{
executionTime.MeassureStep(() => testClass = Activator.CreateInstance(classUnderTest, constructorArguments));
}
}
finally
{
if (!messageBus.QueueMessage(new TestClassConstructionFinished(this, displayName)))
cancellationTokenSource.Cancel();
}
}
return testClass;
}
private void NotifyTestIfRequired(string displayName, object test, ExecutionTime executionTime,
ExceptionAggregator aggregator, string output)
{
@@ -664,6 +669,16 @@ public void MeassureStep(Action step)
total = total + stopwatch.Elapsed;
}
public TResult MeassureStep<TResult>(Func<TResult> step)
{
var stopwatch = Stopwatch.StartNew();
var result = step();
stopwatch.Stop();
total = total + stopwatch.Elapsed;
return result;
}
public TimeSpan Total
{
get { return total; }

0 comments on commit 6a0965c

Please sign in to comment.