public void WhenSinkThrowsMessagesContinueToBeDelivered() { var sink = Substitute.For<IMessageSink>(); var msg1 = Substitute.For<IMessageSinkMessage>(); var msg2 = Substitute.For<IMessageSinkMessage>(); var msg3 = Substitute.For<IMessageSinkMessage>(); var messages = new List<IMessageSinkMessage>(); sink.OnMessage(Arg.Any<IMessageSinkMessage>()) .Returns(callInfo => { var msg = (IMessageSinkMessage)callInfo[0]; if (msg == msg2) throw new Exception("whee!"); else messages.Add(msg); return false; }); using (var bus = new MessageBus(sink)) { bus.QueueMessage(msg1); bus.QueueMessage(msg2); bus.QueueMessage(msg3); } Assert.Collection(messages, message => Assert.Same(message, msg1), message => Assert.Same(message, msg3) ); }
/// <inheritdoc/> public async void Run(IEnumerable <ITestCase> testCases, IMessageSink messageSink) { var cancellationTokenSource = new CancellationTokenSource(); var totalSummary = new RunSummary(); string currentDirectory = Directory.GetCurrentDirectory(); var ordererAttribute = assemblyInfo.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); var orderer = ordererAttribute != null?GetTestCaseOrderer(ordererAttribute) : new DefaultTestCaseOrderer(); using (var messageBus = new MessageBus(messageSink)) { try { Directory.SetCurrentDirectory(Path.GetDirectoryName(assemblyInfo.AssemblyPath)); if (messageBus.QueueMessage(new TestAssemblyStarting(assemblyFileName, AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, DateTime.Now, displayName, XunitTestFrameworkDiscoverer.DisplayName))) { IList <RunSummary> summaries; // TODO: Contract for Run() states that null "testCases" means "run everything". var masterStopwatch = Stopwatch.StartNew(); if (disableParallelization) { summaries = new List <RunSummary>(); foreach (var collectionGroup in testCases.Cast <XunitTestCase>().GroupBy(tc => tc.TestCollection)) { summaries.Add(RunTestCollection(messageBus, collectionGroup.Key, collectionGroup, orderer, cancellationTokenSource)); } } else { var tasks = testCases.Cast <XunitTestCase>() .GroupBy(tc => tc.TestCollection) .Select(collectionGroup => Task.Run(() => RunTestCollection(messageBus, collectionGroup.Key, collectionGroup, orderer, cancellationTokenSource))) .ToArray(); summaries = await Task.WhenAll(tasks); } totalSummary.Time = (decimal)masterStopwatch.Elapsed.TotalSeconds; totalSummary.Total = summaries.Sum(s => s.Total); totalSummary.Failed = summaries.Sum(s => s.Failed); totalSummary.Skipped = summaries.Sum(s => s.Skipped); } } finally { messageBus.QueueMessage(new TestAssemblyFinished(assemblyInfo, totalSummary.Time, totalSummary.Total, totalSummary.Failed, totalSummary.Skipped)); Directory.SetCurrentDirectory(currentDirectory); } } }
/// <summary> /// Runs the tests in the test class. /// </summary> /// <returns>Returns summary information about the tests that were run.</returns> public async Task <RunSummary> RunAsync() { OnTestClassStarting(); var classSummary = new RunSummary(); try { if (!MessageBus.QueueMessage(new TestClassStarting(TestCollection, TestClass.Name))) { CancellationTokenSource.Cancel(); } else { classSummary = await RunTestMethodsAsync(); } } finally { if (!MessageBus.QueueMessage(new TestClassFinished(TestCollection, TestClass.Name, classSummary.Time, classSummary.Total, classSummary.Failed, classSummary.Skipped))) { CancellationTokenSource.Cancel(); } OnTestClassFinished(); } return(classSummary); }
void DisposeTestClass(object testClass) { var disposable = testClass as IDisposable; if (disposable == null) { return; } if (!MessageBus.QueueMessage(new TestClassDisposeStarting(TestCase, DisplayName))) { CancellationTokenSource.Cancel(); } try { Timer.Aggregate(disposable.Dispose); } finally { if (!MessageBus.QueueMessage(new TestClassDisposeFinished(TestCase, DisplayName))) { CancellationTokenSource.Cancel(); } } }
object CreateTestClass() { object testClass = null; if (!TestMethod.IsStatic && !Aggregator.HasExceptions) { if (!MessageBus.QueueMessage(new TestClassConstructionStarting(TestCase, DisplayName))) { CancellationTokenSource.Cancel(); } try { if (!CancellationTokenSource.IsCancellationRequested) { Timer.Aggregate(() => testClass = Activator.CreateInstance(TestClass, ConstructorArguments)); } } finally { if (!MessageBus.QueueMessage(new TestClassConstructionFinished(TestCase, DisplayName))) { CancellationTokenSource.Cancel(); } } } return(testClass); }
public async Task <RunSummary> RunAsync() { OnTestCollectionStarting(); var collectionSummary = new RunSummary(); if (MessageBus.QueueMessage(new TestCollectionStarting(TestCollection))) { foreach (var testCasesByClass in TestCases.GroupBy(tc => tc.Class)) { var classSummary = await RunTestClassAsync((IReflectionTypeInfo)testCasesByClass.Key, testCasesByClass); collectionSummary.Aggregate(classSummary); if (CancellationTokenSource.IsCancellationRequested) { break; } } } if (!MessageBus.QueueMessage(new TestCollectionFinished(TestCollection, collectionSummary.Time, collectionSummary.Total, collectionSummary.Failed, collectionSummary.Skipped))) { CancellationTokenSource.Cancel(); } OnTestCollectionFinished(); return(collectionSummary); }
/// <inheritdoc/> protected override Task <RunSummary> RunTestAsync() { var test = new XunitTest(TestCase, TestCase.DisplayName); var summary = new RunSummary { Total = 1 }; if (!MessageBus.QueueMessage(new TestStarting(test))) { CancellationTokenSource.Cancel(); } else { summary.Failed = 1; var testFailed = new TestFailed(test, 0, null, new[] { typeof(InvalidOperationException).FullName }, new[] { TestCase.ErrorMessage }, new[] { "" }, new[] { -1 }); if (!MessageBus.QueueMessage(testFailed)) { CancellationTokenSource.Cancel(); } } if (!MessageBus.QueueMessage(new TestFinished(test, 0, null))) { CancellationTokenSource.Cancel(); } return(Task.FromResult(summary)); }
/// <summary> /// Runs the tests in the test method. /// </summary> /// <returns>Returns summary information about the tests that were run.</returns> public async Task <RunSummary> RunAsync() { OnTestMethodStarting(); var methodSummary = new RunSummary(); try { if (!MessageBus.QueueMessage(new TestMethodStarting(TestCollection, TestClass.Name, TestMethod.Name))) { CancellationTokenSource.Cancel(); } else { methodSummary = await RunTestCasesAsync(); } } finally { if (!MessageBus.QueueMessage(new TestMethodFinished(TestCollection, TestClass.Name, TestMethod.Name))) { CancellationTokenSource.Cancel(); } OnTestMethodFinished(); } return(methodSummary); }
public async Task <RunSummary> RunTestMethodAsync() { OnTestMethodStarting(); var methodSummary = new RunSummary(); if (!MessageBus.QueueMessage(new TestMethodStarting(TestCollection, TestClass.Name, TestMethod.Name))) { CancellationTokenSource.Cancel(); } else { foreach (var testCase in TestCases) { var testCaseSummary = await RunTestCaseAsync(testCase); methodSummary.Aggregate(testCaseSummary); if (CancellationTokenSource.IsCancellationRequested) { break; } } } if (!MessageBus.QueueMessage(new TestMethodFinished(TestCollection, TestClass.Name, TestMethod.Name))) { CancellationTokenSource.Cancel(); } OnTestMethodFinished(); return(methodSummary); }
public void TryingToQueueMessageAfterDisposingThrows() { var bus = new MessageBus(SpyMessageSink.Create()); bus.Dispose(); var exception = Record.Exception( () => bus.QueueMessage(Substitute.For<IMessageSinkMessage>()) ); Assert.IsType<ObjectDisposedException>(exception); }
public void QueuedMessageShowUpInMessageSink() { var messages = new List<IMessageSinkMessage>(); var sink = SpyMessageSink.Create(messages: messages); var msg1 = Substitute.For<IMessageSinkMessage>(); var msg2 = Substitute.For<IMessageSinkMessage>(); var msg3 = Substitute.For<IMessageSinkMessage>(); using (var bus = new MessageBus(sink)) { bus.QueueMessage(msg1); bus.QueueMessage(msg2); bus.QueueMessage(msg3); } Assert.Collection(messages, message => Assert.Same(msg1, message), message => Assert.Same(msg2, message), message => Assert.Same(msg3, message) ); }
public static void WhenSinkThrowsMessagesContinueToBeDelivered() { var sink = Substitute.For<IMessageSink>(); var msg1 = Substitute.For<IMessageSinkMessage>(); var msg2 = Substitute.For<IMessageSinkMessage>(); var msg3 = Substitute.For<IMessageSinkMessage>(); var messages = new List<IMessageSinkMessage>(); sink.OnMessage(Arg.Any<IMessageSinkMessage>()) .Returns(callInfo => { var msg = (IMessageSinkMessage)callInfo[0]; if (msg == msg2) throw new DivideByZeroException("whee!"); else messages.Add(msg); return false; }); using (var bus = new MessageBus(sink)) { bus.QueueMessage(msg1); bus.QueueMessage(msg2); bus.QueueMessage(msg3); } Assert.Collection(messages, message => Assert.Same(message, msg1), message => { var errorMessage = Assert.IsAssignableFrom<IErrorMessage>(message); Assert.Equal("System.DivideByZeroException", errorMessage.ExceptionTypes.Single()); Assert.Equal("whee!", errorMessage.Messages.Single()); }, message => Assert.Same(message, msg3) ); }
protected override void OnTestCollectionFinished() { foreach (var fixture in collectionFixtureMappings.Values.OfType <IDisposable>()) { try { fixture.Dispose(); } catch (Exception ex) { if (!MessageBus.QueueMessage(new ErrorMessage(ex.Unwrap()))) { CancellationTokenSource.Cancel(); } } } }
/// <inheritdoc/> protected override void AfterTestMethodInvoked() { foreach (var beforeAfterAttribute in beforeAfterAttributesRun) { var attributeName = beforeAfterAttribute.GetType().Name; if (!MessageBus.QueueMessage(new AfterTestStarting(TestCase, DisplayName, attributeName))) { CancellationTokenSource.Cancel(); } Aggregator.Run(() => Timer.Aggregate(() => beforeAfterAttribute.After(TestMethod))); if (!MessageBus.QueueMessage(new AfterTestFinished(TestCase, DisplayName, attributeName))) { CancellationTokenSource.Cancel(); } } }
/// <inheritdoc/> public void Find(bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) using (new PreserveWorkingFolder(AssemblyInfo)) { foreach (var type in AssemblyInfo.GetTypes(includePrivateTypes: false).Where(IsValidTestClass)) if (!FindTestsForTypeAndWrapExceptions(type, includeSourceInformation, messageBus)) break; var warnings = Aggregator.GetAndClear<EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <inheritdoc/> protected override Task <RunSummary> RunTestAsync() { var test = new XunitTest(TestCase, TestCase.DisplayName); var summary = new RunSummary { Total = 1 }; var timer = new ExecutionTimer(); if (!MessageBus.QueueMessage(new TestStarting(test))) { CancellationTokenSource.Cancel(); } else { try { timer.Aggregate(TestCase.Lambda); if (!MessageBus.QueueMessage(new TestPassed(test, timer.Total, null))) { CancellationTokenSource.Cancel(); } } catch (Exception ex) { summary.Failed++; if (!MessageBus.QueueMessage(new TestFailed(test, timer.Total, null, ex))) { CancellationTokenSource.Cancel(); } } } if (!MessageBus.QueueMessage(new TestFinished(test, timer.Total, null))) { CancellationTokenSource.Cancel(); } summary.Time = timer.Total; return(Task.FromResult(summary)); }
/// <inheritdoc/> public void Find(string typeName, bool includeSourceInformation, IMessageSink messageSink) { Guard.ArgumentNotNullOrEmpty("typeName", typeName); Guard.ArgumentNotNull("messageSink", messageSink); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) { ITypeInfo typeInfo = assemblyInfo.GetType(typeName); if (typeInfo != null && (!typeInfo.IsAbstract || typeInfo.IsSealed)) { FindImpl(typeInfo, includeSourceInformation, messageBus); } var warnings = messageAggregator.GetAndClear <EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <inheritdoc/> protected override Task AfterTestMethodInvokedAsync() { foreach (var beforeAfterAttribute in beforeAfterAttributesRun) { var attributeName = beforeAfterAttribute.GetType().Name; if (!MessageBus.QueueMessage(new AfterTestStarting(Test, attributeName))) { CancellationTokenSource.Cancel(); } Aggregator.Run(() => Timer.Aggregate(() => beforeAfterAttribute.After(TestMethod))); if (!MessageBus.QueueMessage(new AfterTestFinished(Test, attributeName))) { CancellationTokenSource.Cancel(); } } return(CommonTasks.Completed); }
RunSummary RunTest_DataDiscoveryException() { var test = new XunitTest(TestCase, DisplayName); if (!MessageBus.QueueMessage(new TestStarting(test))) { CancellationTokenSource.Cancel(); } else if (!MessageBus.QueueMessage(new TestFailed(test, 0, null, dataDiscoveryException.Unwrap()))) { CancellationTokenSource.Cancel(); } if (!MessageBus.QueueMessage(new TestFinished(test, 0, null))) { CancellationTokenSource.Cancel(); } return(new RunSummary { Total = 1, Failed = 1 }); }
/// <inheritdoc/> public void Find(bool includeSourceInformation, IMessageSink messageSink) { Guard.ArgumentNotNull("messageSink", messageSink); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) { foreach (var type in assemblyInfo.GetTypes(includePrivateTypes: false).Where(type => !type.IsAbstract || type.IsSealed)) { if (!FindImpl(type, includeSourceInformation, messageBus)) { break; } } var warnings = messageAggregator.GetAndClear <EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <inheritdoc/> public void Find(string typeName, bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNullOrEmpty("typeName", typeName); Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) using (new PreserveWorkingFolder(AssemblyInfo)) { var typeInfo = AssemblyInfo.GetType(typeName); if (typeInfo != null && IsValidTestClass(typeInfo)) { FindTestsForTypeAndWrapExceptions(typeInfo, includeSourceInformation, messageBus); } var warnings = Aggregator.GetAndClear <EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
public async Task <RunSummary> RunAsync() { OnTestClassStarting(); var classSummary = new RunSummary(); if (!MessageBus.QueueMessage(new TestClassStarting(TestCollection, TestClass.Name))) { CancellationTokenSource.Cancel(); } else { var orderedTestCases = TestCaseOrderer.OrderTestCases(TestCases); var methodGroups = orderedTestCases.GroupBy(tc => tc.Method); var constructorArguments = CreateTestClassConstructorArguments(); foreach (var method in methodGroups) { var methodSummary = await RunTestMethodAsync(constructorArguments, (IReflectionMethodInfo)method.Key, method); classSummary.Aggregate(methodSummary); if (CancellationTokenSource.IsCancellationRequested) { break; } } } if (!MessageBus.QueueMessage(new TestClassFinished(TestCollection, TestClass.Name, classSummary.Time, classSummary.Total, classSummary.Failed, classSummary.Skipped))) { CancellationTokenSource.Cancel(); } OnTestClassFinished(); return(classSummary); }
/// <inheritdoc/> protected override Task BeforeTestMethodInvokedAsync() { foreach (var beforeAfterAttribute in beforeAfterAttributes) { var attributeName = beforeAfterAttribute.GetType().Name; if (!MessageBus.QueueMessage(new BeforeTestStarting(Test, attributeName))) { CancellationTokenSource.Cancel(); } else { try { Timer.Aggregate(() => beforeAfterAttribute.Before(TestMethod)); beforeAfterAttributesRun.Push(beforeAfterAttribute); } catch (Exception ex) { Aggregator.Add(ex); break; } finally { if (!MessageBus.QueueMessage(new BeforeTestFinished(Test, attributeName))) { CancellationTokenSource.Cancel(); } } } if (CancellationTokenSource.IsCancellationRequested) { break; } } return(CommonTasks.Completed); }
/// <summary> /// Runs the tests in the test collection. /// </summary> /// <returns>Returns summary information about the tests that were run.</returns> public async Task <RunSummary> RunAsync() { var collectionSummary = new RunSummary(); if (!MessageBus.QueueMessage(new TestCollectionStarting(TestCases.Cast <ITestCase>(), TestCollection))) { CancellationTokenSource.Cancel(); } else { try { await AfterTestCollectionStartingAsync(); collectionSummary = await RunTestClassesAsync(); Aggregator.Clear(); await BeforeTestCollectionFinishedAsync(); if (Aggregator.HasExceptions) { if (!MessageBus.QueueMessage(new TestCollectionCleanupFailure(TestCases.Cast <ITestCase>(), TestCollection, Aggregator.ToException()))) { CancellationTokenSource.Cancel(); } } } finally { if (!MessageBus.QueueMessage(new TestCollectionFinished(TestCases.Cast <ITestCase>(), TestCollection, collectionSummary.Time, collectionSummary.Total, collectionSummary.Failed, collectionSummary.Skipped))) { CancellationTokenSource.Cancel(); } } } return(collectionSummary); }
/// <summary> /// Runs the tests in the test case. /// </summary> /// <returns>Returns summary information about the tests that were run.</returns> public async Task <RunSummary> RunAsync() { var summary = new RunSummary(); if (!MessageBus.QueueMessage(new TestCaseStarting(TestCase))) { CancellationTokenSource.Cancel(); } else { try { await AfterTestCaseStartingAsync(); summary = await RunTestAsync(); Aggregator.Clear(); await BeforeTestCaseFinishedAsync(); if (Aggregator.HasExceptions) { if (!MessageBus.QueueMessage(new TestCaseCleanupFailure(TestCase, Aggregator.ToException()))) { CancellationTokenSource.Cancel(); } } } finally { if (!MessageBus.QueueMessage(new TestCaseFinished(TestCase, summary.Time, summary.Total, summary.Failed, summary.Skipped))) { CancellationTokenSource.Cancel(); } } } return(summary); }
/// <inheritdoc/> public void Find(bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) using (new PreserveWorkingFolder(AssemblyInfo)) { foreach (var type in AssemblyInfo.GetTypes(includePrivateTypes: false).Where(IsValidTestClass)) { if (!FindTestsForTypeAndWrapExceptions(type, includeSourceInformation, messageBus)) { break; } } var warnings = Aggregator.GetAndClear <EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <summary> /// Runs the tests in the test method. /// </summary> /// <returns>Returns summary information about the tests that were run.</returns> public async Task <RunSummary> RunAsync() { var methodSummary = new RunSummary(); if (!MessageBus.QueueMessage(new TestMethodStarting(TestCases.Cast <ITestCase>(), TestMethod))) { CancellationTokenSource.Cancel(); } else { try { AfterTestMethodStarting(); methodSummary = await RunTestCasesAsync(); Aggregator.Clear(); BeforeTestMethodFinished(); if (Aggregator.HasExceptions) { if (!MessageBus.QueueMessage(new TestMethodCleanupFailure(TestCases.Cast <ITestCase>(), TestMethod, Aggregator.ToException()))) { CancellationTokenSource.Cancel(); } } } finally { if (!MessageBus.QueueMessage(new TestMethodFinished(TestCases.Cast <ITestCase>(), TestMethod, methodSummary.Time, methodSummary.Total, methodSummary.Failed, methodSummary.Skipped))) { CancellationTokenSource.Cancel(); } } } return(methodSummary); }
/// <inheritdoc/> protected override async Task <RunSummary> RunTestAsync() { var testRunners = new List <XunitTestRunner>(); var toDispose = new List <IDisposable>(); try { var dataAttributes = TestCase.TestMethod.Method.GetCustomAttributes(typeof(DataAttribute)); foreach (var dataAttribute in dataAttributes) { var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First(); var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList(); var discovererType = Reflector.GetType(args[1], args[0]); var discoverer = ExtensibilityPointFactory.GetDataDiscoverer(discovererType); foreach (var dataRow in discoverer.GetData(dataAttribute, TestCase.TestMethod.Method)) { toDispose.AddRange(dataRow.OfType <IDisposable>()); ITypeInfo[] resolvedTypes = null; var methodToRun = TestMethod; if (methodToRun.IsGenericMethodDefinition) { resolvedTypes = TypeUtility.ResolveGenericTypes(TestCase.TestMethod.Method, dataRow); methodToRun = methodToRun.MakeGenericMethod(resolvedTypes.Select(t => ((IReflectionTypeInfo)t).Type).ToArray()); } var parameterTypes = methodToRun.GetParameters().Select(p => p.ParameterType).ToArray(); var convertedDataRow = Reflector.ConvertArguments(dataRow, parameterTypes); var theoryDisplayName = TypeUtility.GetDisplayNameWithArguments(TestCase.TestMethod.Method, DisplayName, convertedDataRow, resolvedTypes); testRunners.Add(new XunitTestRunner(TestCase, MessageBus, TestClass, ConstructorArguments, methodToRun, convertedDataRow, theoryDisplayName, SkipReason, BeforeAfterAttributes, Aggregator, CancellationTokenSource)); } } } catch (Exception ex) { if (!MessageBus.QueueMessage(new TestStarting(TestCase, DisplayName))) { CancellationTokenSource.Cancel(); } else { if (!MessageBus.QueueMessage(new TestFailed(TestCase, DisplayName, 0, null, ex.Unwrap()))) { CancellationTokenSource.Cancel(); } } if (!MessageBus.QueueMessage(new TestFinished(TestCase, DisplayName, 0, null))) { CancellationTokenSource.Cancel(); } return(new RunSummary { Total = 1, Failed = 1 }); } var runSummary = new RunSummary(); foreach (var testRunner in testRunners) { runSummary.Aggregate(await testRunner.RunAsync()); } var timer = new ExecutionTimer(); var aggregator = new ExceptionAggregator(); // REVIEW: What should be done with these leftover errors? foreach (var disposable in toDispose) { timer.Aggregate(() => aggregator.Run(() => disposable.Dispose())); } runSummary.Time += timer.Total; return(runSummary); }
/// <summary> /// Runs the test. /// </summary> /// <returns>Returns summary information about the test that was run.</returns> public async Task <RunSummary> RunAsync() { var runSummary = new RunSummary { Total = 1 }; var output = string.Empty; if (!MessageBus.QueueMessage(new TestStarting(Test))) { CancellationTokenSource.Cancel(); } else { AfterTestStarting(); if (!string.IsNullOrEmpty(SkipReason)) { runSummary.Skipped++; if (!MessageBus.QueueMessage(new TestSkipped(Test, SkipReason))) { CancellationTokenSource.Cancel(); } } else { var aggregator = new ExceptionAggregator(Aggregator); if (!aggregator.HasExceptions) { var tuple = await aggregator.RunAsync(() => InvokeTestAsync(aggregator)); runSummary.Time = tuple.Item1; output = tuple.Item2; } var exception = aggregator.ToException(); TestResultMessage testResult; if (exception == null) { testResult = new TestPassed(Test, runSummary.Time, output); } else { testResult = new TestFailed(Test, runSummary.Time, output, exception); runSummary.Failed++; } if (!CancellationTokenSource.IsCancellationRequested) { if (!MessageBus.QueueMessage(testResult)) { CancellationTokenSource.Cancel(); } } } Aggregator.Clear(); BeforeTestFinished(); if (Aggregator.HasExceptions) { if (!MessageBus.QueueMessage(new TestCleanupFailure(Test, Aggregator.ToException()))) { CancellationTokenSource.Cancel(); } } } if (!MessageBus.QueueMessage(new TestFinished(Test, runSummary.Time, output))) { CancellationTokenSource.Cancel(); } return(runSummary); }
/// <inheritdoc/> public async void Run(IEnumerable<ITestCase> testCases, IMessageSink messageSink, ITestFrameworkOptions executionOptions) { Guard.ArgumentNotNull("testCases", testCases); Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("executionOptions", executionOptions); var disableParallelization = false; var maxParallelThreads = 0; var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); if (collectionBehaviorAttribute != null) { disableParallelization = collectionBehaviorAttribute.GetNamedArgument<bool>("DisableTestParallelization"); maxParallelThreads = collectionBehaviorAttribute.GetNamedArgument<int>("MaxParallelThreads"); } disableParallelization = executionOptions.GetValue<bool>(TestOptionsNames.Execution.DisableParallelization, disableParallelization); var maxParallelThreadsOption = executionOptions.GetValue<int>(TestOptionsNames.Execution.MaxParallelThreads, 0); if (maxParallelThreadsOption > 0) maxParallelThreads = maxParallelThreadsOption; var displayName = GetDisplayName(collectionBehaviorAttribute, disableParallelization, maxParallelThreads); var cancellationTokenSource = new CancellationTokenSource(); var totalSummary = new RunSummary(); var scheduler = maxParallelThreads > 0 ? new MaxConcurrencyTaskScheduler(maxParallelThreads) : TaskScheduler.Current; string currentDirectory = Directory.GetCurrentDirectory(); var ordererAttribute = assemblyInfo.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); var orderer = ordererAttribute != null ? GetTestCaseOrderer(ordererAttribute) : new DefaultTestCaseOrderer(); using (var messageBus = new MessageBus(messageSink)) { try { Directory.SetCurrentDirectory(Path.GetDirectoryName(assemblyInfo.AssemblyPath)); if (messageBus.QueueMessage(new TestAssemblyStarting(assemblyFileName, AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, DateTime.Now, displayName, XunitTestFrameworkDiscoverer.DisplayName))) { IList<RunSummary> summaries; // TODO: Contract for Run() states that null "testCases" means "run everything". var masterStopwatch = Stopwatch.StartNew(); if (disableParallelization) { summaries = new List<RunSummary>(); foreach (var collectionGroup in testCases.Cast<XunitTestCase>().GroupBy(tc => tc.TestCollection)) summaries.Add(await RunTestCollectionAsync(messageBus, collectionGroup.Key, collectionGroup, orderer, cancellationTokenSource)); } else { var tasks = testCases.Cast<XunitTestCase>() .GroupBy(tc => tc.TestCollection) .Select(collectionGroup => Task.Factory.StartNew(() => RunTestCollectionAsync(messageBus, collectionGroup.Key, collectionGroup, orderer, cancellationTokenSource), cancellationTokenSource.Token, TaskCreationOptions.None, scheduler)) .ToArray(); summaries = await Task.WhenAll(tasks.Select(t => t.Unwrap())); } totalSummary.Time = (decimal)masterStopwatch.Elapsed.TotalSeconds; totalSummary.Total = summaries.Sum(s => s.Total); totalSummary.Failed = summaries.Sum(s => s.Failed); totalSummary.Skipped = summaries.Sum(s => s.Skipped); } } finally { messageBus.QueueMessage(new TestAssemblyFinished(assemblyInfo, totalSummary.Time, totalSummary.Total, totalSummary.Failed, totalSummary.Skipped)); Directory.SetCurrentDirectory(currentDirectory); } } }
/// <inheritdoc/> public void Find(bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) { foreach (var type in assemblyInfo.GetTypes(includePrivateTypes: false).Where(type => !type.IsAbstract || type.IsSealed)) if (!FindImpl(type, includeSourceInformation, messageBus)) break; var warnings = messageAggregator.GetAndClear<EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <inheritdoc/> public void Find(string typeName, bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNullOrEmpty("typeName", typeName); Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); Task.Run(() => { using (var messageBus = new MessageBus(messageSink)) using (new PreserveWorkingFolder(AssemblyInfo)) { var typeInfo = AssemblyInfo.GetType(typeName); if (typeInfo != null && IsValidTestClass(typeInfo)) { var testClass = CreateTestClass(typeInfo); FindTestsForTypeAndWrapExceptions(testClass, includeSourceInformation, messageBus); } var warnings = Aggregator.GetAndClear<EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }
/// <inheritdoc/> public void Find(string typeName, bool includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options) { Guard.ArgumentNotNullOrEmpty("typeName", typeName); Guard.ArgumentNotNull("messageSink", messageSink); Guard.ArgumentNotNull("options", options); ThreadPool.QueueUserWorkItem(_ => { using (var messageBus = new MessageBus(messageSink)) { ITypeInfo typeInfo = assemblyInfo.GetType(typeName); if (typeInfo != null && (!typeInfo.IsAbstract || typeInfo.IsSealed)) FindImpl(typeInfo, includeSourceInformation, messageBus); var warnings = messageAggregator.GetAndClear<EnvironmentalWarning>().Select(w => w.Message).ToList(); messageBus.QueueMessage(new DiscoveryCompleteMessage(warnings)); } }); }