/// <summary> /// Starts the process of running selected tests in the assembly. /// </summary> /// <param name="executor">The executor.</param> /// <param name="testCases">The test cases to run.</param> /// <param name="executionMessageSink">The message sink to report results back to.</param> /// <param name="executionOptions">The options to be used during test execution.</param> public static void RunTests(this ITestFrameworkExecutor executor, IEnumerable<ITestCase> testCases, IMessageSinkWithTypes executionMessageSink, ITestFrameworkExecutionOptions executionOptions) { executor.RunTests(testCases, MessageSinkAdapter.Wrap(executionMessageSink), executionOptions); }
/// <summary> /// Starts the process of running selected tests in the assembly. /// </summary> /// <param name="executor">The executor.</param> /// <param name="testCases">The test cases to run.</param> /// <param name="executionMessageSink">The message sink to report results back to.</param> /// <param name="executionOptions">The options to be used during test execution.</param> public static void RunTests(this ITestFrameworkExecutor executor, IEnumerable <ITestCase> testCases, IMessageSinkWithTypes executionMessageSink, ITestFrameworkExecutionOptions executionOptions) { executor.RunTests(testCases, MessageSinkAdapter.Wrap(executionMessageSink), executionOptions); }
/// <summary> /// Starts the process of finding all tests in an assembly. /// </summary> /// <param name="discoverer">The discoverer.</param> /// <param name="includeSourceInformation">Whether to include source file information, if possible.</param> /// <param name="discoveryMessageSink">The message sink to report results back to.</param> /// <param name="discoveryOptions">The options used by the test framework during discovery.</param> public static void Find(this ITestFrameworkDiscoverer discoverer, bool includeSourceInformation, IMessageSinkWithTypes discoveryMessageSink, ITestFrameworkDiscoveryOptions discoveryOptions) { discoverer.Find(includeSourceInformation, MessageSinkAdapter.Wrap(discoveryMessageSink), discoveryOptions); }
public DelegatingExecutionSummarySinkTests() { innerSink = Substitute.For <IMessageSinkWithTypes>(); innerSink.OnMessageWithTypes(null, null).ReturnsForAnyArgs(true); testMessage = Substitute.For <IMessageSinkMessage>(); }
/// <summary> /// Initializes a new instance of the <see cref="DelegatingLongRunningTestDetectionSink"/> class, with /// long running test messages being delivered as <see cref="IDiagnosticMessage"/> instances to the /// provided diagnostic message sink. /// </summary> /// <param name="innerSink">The inner sink to delegate to.</param> /// <param name="longRunningTestTime">The minimum amount of time a test runs to be considered long running.</param> /// <param name="diagnosticMessageSink">The message sink to send messages to.</param> public DelegatingLongRunningTestDetectionSink(IExecutionSink innerSink, TimeSpan longRunningTestTime, IMessageSinkWithTypes diagnosticMessageSink) : this(innerSink, longRunningTestTime, summary => DispatchLongRunningTestsSummaryAsDiagnosticMessage(summary, diagnosticMessageSink)) { Guard.ArgumentNotNull(nameof(diagnosticMessageSink), diagnosticMessageSink); }
public VsExecutionSink(IMessageSinkWithTypes innerSink, ITestExecutionRecorder recorder, LoggerHelper logger, Dictionary <string, TestCase> testCasesMap, ITestFrameworkExecutionOptions executionOptions, Func <bool> cancelledThunk) { this.innerSink = innerSink; this.recorder = recorder; this.logger = logger; this.testCasesMap = testCasesMap; this.executionOptions = executionOptions; this.cancelledThunk = cancelledThunk; ExecutionSummary = new ExecutionSummary(); Diagnostics.ErrorMessageEvent += HandleErrorMessage; Execution.TestAssemblyCleanupFailureEvent += HandleTestAssemblyCleanupFailure; Execution.TestAssemblyFinishedEvent += HandleTestAssemblyFinished; Execution.TestCaseCleanupFailureEvent += HandleTestCaseCleanupFailure; Execution.TestCaseFinishedEvent += HandleTestCaseFinished; Execution.TestCaseStartingEvent += HandleTestCaseStarting; Execution.TestClassCleanupFailureEvent += HandleTestClassCleanupFailure; Execution.TestCleanupFailureEvent += HandleTestCleanupFailure; Execution.TestCollectionCleanupFailureEvent += HandleTestCollectionCleanupFailure; Execution.TestFailedEvent += HandleTestFailed; Execution.TestMethodCleanupFailureEvent += HandleTestMethodCleanupFailure; Execution.TestPassedEvent += HandleTestPassed; Execution.TestSkippedEvent += HandleTestSkipped; }
/// <summary> /// Initializes a new instance of <see cref="XmlTestExecutionSink"/>. /// </summary> /// <param name="assemblyElement">The root XML assembly element to collect the result XML.</param> /// <param name="diagnosticMessageSink">The message sink to report diagnostic messages to.</param> /// <param name="cancelThunk">The callback used to determine when to cancel execution.</param> /// <param name="completionMessages">The dictionary which collects execution summaries for all assemblies.</param> /// <param name="longRunningSeconds">Timeout value for a test to be considered "long running"</param> public XmlTestExecutionSink(XElement assemblyElement, IMessageSinkWithTypes diagnosticMessageSink, ConcurrentDictionary <string, ExecutionSummary> completionMessages, Func <bool> cancelThunk, int longRunningSeconds) : base(diagnosticMessageSink, completionMessages, cancelThunk, longRunningSeconds) { this.assemblyElement = assemblyElement; if (this.assemblyElement != null) { testCollectionElements = new ConcurrentDictionary <Guid, XElement>(); errorsElement = new XElement("errors"); assemblyElement.Add(errorsElement); TestAssemblyStartingEvent += HandleTestAssemblyStarting; TestCollectionFinishedEvent += HandleTestCollectionFinished; TestFailedEvent += HandleTestFailed; TestPassedEvent += HandleTestPassed; TestSkippedEvent += HandleTestSkipped; ErrorMessageEvent += HandleErrorMessage; TestAssemblyCleanupFailureEvent += HandleTestAssemblyCollection; TestCaseCleanupFailureEvent += HandleTestCaseCleanupFailure; TestClassCleanupFailureEvent += HandleTestClassCleanupFailure; TestCollectionCleanupFailureEvent += HandleTestCollectionCleanupFailure; TestCleanupFailureEvent += HandleTestCleanupFailure; TestMethodCleanupFailureEvent += HandleTestMethodCleanupFailure; } }
/// <summary> /// Starts the process of running all the tests in the assembly. /// </summary> /// <param name="executor">The executor.</param> /// <param name="executionMessageSink">The message sink to report results back to.</param> /// <param name="discoveryOptions">The options to be used during test discovery.</param> /// <param name="executionOptions">The options to be used during test execution.</param> public static void RunAll(this ITestFrameworkExecutor executor, IMessageSinkWithTypes executionMessageSink, ITestFrameworkDiscoveryOptions discoveryOptions, ITestFrameworkExecutionOptions executionOptions) { executor.RunAll(MessageSinkAdapter.Wrap(executionMessageSink), discoveryOptions, executionOptions); }
static void DispatchLongRunningTestsSummaryAsDiagnosticMessage(LongRunningTestsSummary summary, IMessageSinkWithTypes diagnosticMessageSink) { var messages = summary.TestCases.Select(pair => $"[Long Running Test] '{pair.Key.DisplayName}', Elapsed: {pair.Value:hh\\:mm\\:ss}"); var message = string.Join(Environment.NewLine, messages.ToArray()); diagnosticMessageSink.OnMessage(new DiagnosticMessage(message)); }
public TestableTestExecutionSink(IMessageSinkWithTypes diagnosticMessageSink = null, ConcurrentDictionary <string, ExecutionSummary> competionMessages = null, Func <bool> cancelThunk = null, int longRunningSeconds = -1) : base(diagnosticMessageSink, competionMessages, cancelThunk, longRunningSeconds) { }
public DelegatingExecutionSummarySinkTests() { innerSink = Substitute.For<IMessageSinkWithTypes>(); innerSink.OnMessageWithTypes(null, null).ReturnsForAnyArgs(true); testMessage = Substitute.For<IMessageSinkMessage>(); }
ManualResetEvent RunTestsInAssemblyAsync(IRunContext runContext, IFrameworkHandle frameworkHandle, LoggerHelper logger, TestPlatformContext testPlatformContext, IMessageSinkWithTypes reporterMessageHandler, AssemblyRunInfo runInfo) { var @event = new ManualResetEvent(initialState: false); Action handler = () => { try { RunTestsInAssembly(runContext, frameworkHandle, logger, testPlatformContext, reporterMessageHandler, runInfo); } finally { @event.Set(); } }; #if WINDOWS_UAP var fireAndForget = Windows.System.Threading.ThreadPool.RunAsync(_ => handler()); #else ThreadPool.QueueUserWorkItem(_ => handler()); #endif return(@event); }
public TestableXmlTestExecutionSink(XElement assemblyElement = null, IMessageSinkWithTypes diagnosticMessageSink = null, ConcurrentDictionary <string, ExecutionSummary> completionMessages = null, Func <bool> cancelThunk = null, int longRunningSeconds = -1) : base(assemblyElement, diagnosticMessageSink, completionMessages, cancelThunk, longRunningSeconds) { }
/// <summary> /// Initializes a new instance of the <see cref="TestExecutionSink"/> class. /// </summary> /// <param name="diagnosticMessageSink">The message sink to report diagnostic messages to.</param> /// <param name="completionMessages">The dictionary which collects execution summaries for all assemblies.</param> /// <param name="cancelThunk">The callback used to determine when to cancel execution.</param> /// <param name="longRunningSeconds">Timeout value for a test to be considered "long running".</param> public TestExecutionSink(IMessageSinkWithTypes diagnosticMessageSink, ConcurrentDictionary <string, ExecutionSummary> completionMessages, Func <bool> cancelThunk, int longRunningSeconds) { this.diagnosticMessageSink = diagnosticMessageSink; this.completionMessages = completionMessages; this.cancelThunk = cancelThunk ?? (() => false); TestAssemblyFinishedEvent += args => { // We fill in ExecutionSummary here before we call the extensibility point, because // we want anybody who derives from this to be able to count on the values being // there when running the message handler; we also want them to be able to run // their code before delegating to our implementation, since we're the ones who // are responsible for triggering the Finished event. var assemblyFinished = args.Message; ExecutionSummary.Total = assemblyFinished.TestsRun; ExecutionSummary.Failed = assemblyFinished.TestsFailed; ExecutionSummary.Skipped = assemblyFinished.TestsSkipped; ExecutionSummary.Time = assemblyFinished.ExecutionTime; ExecutionSummary.Errors = errors; if (completionMessages != null) { var assemblyDisplayName = Path.GetFileNameWithoutExtension(assemblyFinished.TestAssembly.Assembly.AssemblyPath); completionMessages.TryAdd(assemblyDisplayName, ExecutionSummary); } if (longRunningTime != default(TimeSpan)) { cancellationTokenSource.Cancel(); } HandleTestAssemblyFinished(args); }; TestAssemblyCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; TestCaseCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; TestClassCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; TestCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; TestCollectionCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; TestMethodCleanupFailureEvent += delegate { Interlocked.Increment(ref errors); }; ErrorMessageEvent += delegate { Interlocked.Increment(ref errors); }; if (longRunningSeconds > 0) { longRunningTime = TimeSpan.FromSeconds(longRunningSeconds); executingTestCases = new ConcurrentDictionary <ITestCase, DateTime>(); // Only need to subscribe these when tracking long-running tests TestAssemblyStartingEvent += HandleTestAssemblyStarting; TestCaseStartingEvent += HandleTestCaseStarting; TestCaseFinishedEvent += HandleTestCaseFinished; } }
/// <summary> /// Initializes a new instance of the <see cref="DelegatingExecutionSummarySink"/> class. /// </summary> /// <param name="innerSink">The inner sink to pass messages to.</param> /// <param name="cancelThunk"></param> /// <param name="completionCallback"></param> public DelegatingExecutionSummarySink(IMessageSinkWithTypes innerSink, Func <bool> cancelThunk = null, Action <string, ExecutionSummary> completionCallback = null) { Guard.ArgumentNotNull(nameof(innerSink), innerSink); this.innerSink = innerSink; this.cancelThunk = cancelThunk ?? (() => false); this.completionCallback = completionCallback; }
/// <summary> /// Initializes a new instance of the <see cref="DelegatingExecutionSummarySink"/> class. /// </summary> /// <param name="innerSink">The inner sink to pass messages to.</param> /// <param name="cancelThunk"></param> /// <param name="completionCallback"></param> public DelegatingExecutionSummarySink(IMessageSinkWithTypes innerSink, Func<bool> cancelThunk = null, Action<string, ExecutionSummary> completionCallback = null) { Guard.ArgumentNotNull(nameof(innerSink), innerSink); this.innerSink = innerSink; this.cancelThunk = cancelThunk ?? (() => false); this.completionCallback = completionCallback; }
/// <summary> /// Initializes a new instance of <see cref="XmlAggregateVisitor"/>. /// </summary> /// <param name="innerMessageSink">The inner message sink to pass messages to.</param> /// <param name="assemblyElement">The root XML assembly element to collect the result XML.</param> /// <param name="diagnosticMessageSink">The message sink to report diagnostic messages to.</param> /// <param name="completionMessages">The dictionary which collects execution summaries for all assemblies.</param> /// <param name="cancelThunk">The callback used to determine when to cancel execution.</param> /// <param name="longRunningSeconds">Timeout value for a test to be considered "long running"</param> public XmlAggregateSink(IMessageSinkWithTypes innerMessageSink, XElement assemblyElement, IMessageSinkWithTypes diagnosticMessageSink, ConcurrentDictionary <string, ExecutionSummary> completionMessages, Func <bool> cancelThunk, int longRunningSeconds) : base(assemblyElement, diagnosticMessageSink, completionMessages, cancelThunk, longRunningSeconds) { Guard.ArgumentNotNull(nameof(innerMessageSink), innerMessageSink); this.innerMessageSink = innerMessageSink; }
public static IRunnerReporter RunnerReporter(string runnerSwitch = null, string description = null, bool isEnvironmentallyEnabled = false, IMessageSinkWithTypes messageSink = null) { var result = Substitute.For <IRunnerReporter, InterfaceProxy <IRunnerReporter> >(); result.Description.Returns(description ?? "The runner reporter description"); result.IsEnvironmentallyEnabled.ReturnsForAnyArgs(isEnvironmentallyEnabled); result.RunnerSwitch.Returns(runnerSwitch); result.CreateMessageHandler(null).ReturnsForAnyArgs(messageSink ?? Substitute.For <IMessageSinkWithTypes, InterfaceProxy <IMessageSinkWithTypes> >()); return(result); }
/// <summary> /// Runs the tests with the given options /// </summary> /// <param name="options">The test run options</param> /// <returns>The number of failed tests, or -1 if cancelled</returns> public int EntryPoint([NotNull] TestRunOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } try { AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; var defaultDirectory = Directory.GetCurrentDirectory(); if (!defaultDirectory.EndsWith(new string(new[] { Path.DirectorySeparatorChar }), StringComparison.Ordinal)) { } /* * if (options.Debug) * { * Debugger.Launch(); * }*/ _reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(options.Reporter.CreateMessageHandler(_logger)); if (!options.NoLogo) { PrintHeader(); } var failCount = RunProject(options); if (_cancel) { return(-1); } return(failCount); } catch (ArgumentException ex) { Console.WriteLine($"error: {ex.Message}"); Console.WriteLine(ex.StackTrace); throw; } catch (BadImageFormatException ex) { Console.WriteLine(ex.Message); throw; } }
public DesignTimeExecutionSink(ITestExecutionSink sink, IDictionary <ITestCase, VsTestCase> conversions, IMessageSinkWithTypes next) { this.sink = sink; this.conversions = conversions; this.next = next; ExecutionSummary = new ExecutionSummary(); TestAssemblyFinishedEvent += HandleTestAssemblyFinished; TestFailedEvent += HandleTestFailed; TestPassedEvent += HandleTestPassed; TestStartingEvent += HandleTestStarting; TestSkippedEvent += HandleTestSkipped; }
public int EntryPoint(string[] args) { commandLine = CommandLine.Parse(args); try { var reporters = GetAvailableRunnerReporters(); if (args.Length == 0 || args[0] == "-?" || args[0] == "/?" || args[0] == "-h" || args[0] == "--help") { PrintHeader(); PrintUsage(reporters); return(2); } if (commandLine.Project.Assemblies.Count == 0) { throw new ArgumentException("must specify at least one assembly"); } #if NET452 AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; #endif Console.CancelKeyPress += (sender, e) => { if (!cancel) { Console.WriteLine("Canceling... (Press Ctrl+C again to terminate)"); cancel = true; e.Cancel = true; } }; var defaultDirectory = Directory.GetCurrentDirectory(); if (!defaultDirectory.EndsWith(new string(new[] { Path.DirectorySeparatorChar }), StringComparison.Ordinal)) { defaultDirectory += Path.DirectorySeparatorChar; } var reporter = commandLine.ChooseReporter(reporters); #if DEBUG if (commandLine.Pause) { Console.Write("Press any key to start execution..."); Console.ReadKey(true); Console.WriteLine(); } #endif if (commandLine.Debug) { Debugger.Launch(); } logger = new ConsoleRunnerLogger(!commandLine.NoColor, consoleLock); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!commandLine.NoLogo) { PrintHeader(); } var failCount = RunProject(commandLine.Project, commandLine.Serialize, commandLine.ParallelizeAssemblies, commandLine.ParallelizeTestCollections, commandLine.MaxParallelThreads, commandLine.DiagnosticMessages, commandLine.NoColor, commandLine.AppDomains, commandLine.FailSkips, commandLine.StopOnFail, commandLine.InternalDiagnosticMessages); if (cancel) { return(-1073741510); // 0xC000013A: The application terminated as a result of a CTRL+C } if (commandLine.Wait) { Console.WriteLine(); Console.Write("Press any key to continue..."); Console.ReadKey(); Console.WriteLine(); } return(failCount > 0 ? 1 : 0); } catch (Exception ex) { if (!commandLine.NoColor) { ConsoleHelper.SetForegroundColor(ConsoleColor.Red); } Console.WriteLine($"error: {ex.Message}"); if (commandLine.InternalDiagnosticMessages) { if (!commandLine.NoColor) { ConsoleHelper.SetForegroundColor(ConsoleColor.DarkGray); } Console.WriteLine(ex.StackTrace); } return(ex is ArgumentException ? 3 : 4); } finally { if (!commandLine.NoColor) { ConsoleHelper.ResetColor(); } } }
/// <summary> /// Determines whether the given sink is already an implementation of <see cref="IMessageSink"/>, /// and if not, creates a wrapper to adapt it. /// </summary> /// <param name="sink">The sink to test, and potentially adapt.</param> public static IMessageSink Wrap(IMessageSinkWithTypes sink) => sink == null ? null : (sink as IMessageSink ?? new MessageSinkAdapter(sink));
MessageSinkAdapter(IMessageSinkWithTypes inner) { this.inner = inner; }
void RunTestsInAssembly(IRunContext runContext, IFrameworkHandle frameworkHandle, LoggerHelper logger, TestPlatformContext testPlatformContext, IMessageSinkWithTypes reporterMessageHandler, AssemblyRunInfo runInfo) { if (cancelled) { return; } var assemblyDisplayName = "(unknown assembly)"; try { var assembly = new XunitProjectAssembly { AssemblyFilename = runInfo.AssemblyFileName }; var assemblyFileName = runInfo.AssemblyFileName; assemblyDisplayName = Path.GetFileNameWithoutExtension(assemblyFileName); var configuration = runInfo.Configuration; var shadowCopy = configuration.ShadowCopyOrDefault; var appDomain = assembly.Configuration.AppDomain ?? AppDomainDefaultBehavior; var longRunningSeconds = assembly.Configuration.LongRunningTestSecondsOrDefault; if (RunSettingsHelper.DisableAppDomain) { appDomain = AppDomainSupport.Denied; } #if WINDOWS_UAP // For AppX Apps, use the package location assemblyFileName = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, Path.GetFileName(assemblyFileName)); #endif var diagnosticSink = new DiagnosticMessageSink(logger, assemblyDisplayName, runInfo.Configuration.DiagnosticMessagesOrDefault); var diagnosticMessageSink = MessageSinkAdapter.Wrap(diagnosticSink); using (var controller = new XunitFrontController(appDomain, assemblyFileName, shadowCopy: shadowCopy, diagnosticMessageSink: diagnosticMessageSink)) { var testCasesMap = new Dictionary <string, TestCase>(); var testCases = new List <ITestCase>(); if (runInfo.TestCases == null || !runInfo.TestCases.Any()) { // Discover tests AssemblyDiscoveredInfo assemblyDiscoveredInfo = new AssemblyDiscoveredInfo(); DiscoverTestsInSource(controller, logger, testPlatformContext, (source, discoverer, discoveryOptions) => new VsExecutionDiscoverySink(() => cancelled), (source, discoverer, discoveryOptions, visitor) => { if (discoveryOptions.GetInternalDiagnosticMessagesOrDefault()) { foreach (var testCase in visitor.TestCases) { logger.Log(testCase, "Discovered [execution] test case '{0}' (ID = '{1}')", testCase.DisplayName, testCase.UniqueID); } } assemblyDiscoveredInfo = new AssemblyDiscoveredInfo { AssemblyFileName = source, DiscoveredTestCases = GetVsTestCases(source, discoverer, visitor, logger, testPlatformContext) }; }, assemblyFileName, shadowCopy, configuration ); if (assemblyDiscoveredInfo.DiscoveredTestCases == null || !assemblyDiscoveredInfo.DiscoveredTestCases.Any()) { if (configuration.InternalDiagnosticMessagesOrDefault) { logger.LogWarning("Skipping '{0}' since no tests were found during discovery [execution].", assemblyDiscoveredInfo.AssemblyFileName); } return; } // Filter tests var traitNames = new HashSet <string>(assemblyDiscoveredInfo.DiscoveredTestCases.SelectMany(testCase => testCase.TraitNames)); // Apply any filtering var filter = new TestCaseFilter(runContext, logger, assemblyDiscoveredInfo.AssemblyFileName, traitNames); var filteredTestCases = assemblyDiscoveredInfo.DiscoveredTestCases.Where(dtc => filter.MatchTestCase(dtc.VSTestCase)).ToList(); foreach (var filteredTestCase in filteredTestCases) { var uniqueID = filteredTestCase.UniqueID; if (testCasesMap.ContainsKey(uniqueID)) { logger.LogWarning(filteredTestCase.TestCase, "Skipping test case with duplicate ID '{0}' ('{1}' and '{2}')", uniqueID, testCasesMap[uniqueID].DisplayName, filteredTestCase.VSTestCase.DisplayName); } else { testCasesMap.Add(uniqueID, filteredTestCase.VSTestCase); testCases.Add(filteredTestCase.TestCase); } } } else { // We are in Run Specific tests scenario, the `TestCase` objects are available. // Query the `TestCase` objects to find XunitTestCase objects. foreach (var vstestCase in runInfo.TestCases) { var xunitTestCase = Deserialize(logger, controller, vstestCase); if (xunitTestCase != null) { testCasesMap.Add(xunitTestCase.UniqueID, vstestCase); testCases.Add(xunitTestCase); } } } // Execute tests var executionOptions = TestFrameworkOptions.ForExecution(runInfo.Configuration); if (RunSettingsHelper.DisableParallelization) { executionOptions.SetSynchronousMessageReporting(true); executionOptions.SetDisableParallelization(true); } reporterMessageHandler.OnMessage(new TestAssemblyExecutionStarting(assembly, executionOptions)); using (var vsExecutionSink = new VsExecutionSink(reporterMessageHandler, frameworkHandle, logger, testCasesMap, executionOptions, () => cancelled)) { IExecutionSink resultsSink = vsExecutionSink; if (longRunningSeconds > 0) { resultsSink = new DelegatingLongRunningTestDetectionSink(resultsSink, TimeSpan.FromSeconds(longRunningSeconds), diagnosticSink); } controller.RunTests(testCases, resultsSink, executionOptions); resultsSink.Finished.WaitOne(); reporterMessageHandler.OnMessage(new TestAssemblyExecutionFinished(assembly, executionOptions, resultsSink.ExecutionSummary)); } } } catch (Exception ex) { logger.LogError("{0}: Catastrophic failure: {1}", assemblyDisplayName, ex); } }
public static int Main(string[] args) { try { var reporters = GetAvailableRunnerReporters(); if (args.Length == 0 || args[0] == "-?" || args[0] == "/?" || args[0] == "-h" || args[0] == "--help") { PrintHeader(); PrintUsage(reporters); return(2); } AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; Console.CancelKeyPress += (sender, e) => { if (!cancel) { Console.WriteLine("Canceling... (Press Ctrl+C again to terminate)"); cancel = true; e.Cancel = true; } }; var defaultDirectory = Directory.GetCurrentDirectory(); if (!defaultDirectory.EndsWith(new string(new[] { Path.DirectorySeparatorChar }), StringComparison.Ordinal)) { defaultDirectory += Path.DirectorySeparatorChar; } var commandLine = CommandLine.Parse(reporters, args); if (commandLine.Debug) { Debugger.Launch(); } logger = new ConsoleRunnerLogger(!commandLine.NoColor); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(commandLine.Reporter.CreateMessageHandler(logger)); if (!commandLine.NoLogo) { PrintHeader(); } var failCount = RunProject(commandLine.Project, commandLine.Serialize, commandLine.ParallelizeAssemblies, commandLine.ParallelizeTestCollections, commandLine.MaxParallelThreads, commandLine.DiagnosticMessages, commandLine.NoColor, commandLine.NoAppDomain, commandLine.FailSkips, commandLine.InternalDiagnosticMessages); if (commandLine.Wait) { Console.WriteLine(); Console.Write("Press any key to continue..."); Console.ReadKey(); Console.WriteLine(); } return(failCount > 0 ? 1 : 0); } catch (ArgumentException ex) { Console.WriteLine($"error: {ex.Message}"); return(3); } catch (BadImageFormatException ex) { Console.WriteLine(ex.Message); return(4); } finally { Console.ResetColor(); } }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit .NET {Environment.Version}"; if (NeedsXml) { assembliesElement = new XElement("assemblies"); } switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return(false); } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporter = GetReporter(); if (reporter == null) { return(false); } logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) { Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); } var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) { configFileName = null; } var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) { projectAssembly.Configuration.ShadowCopy = shadowCopy; } project.Add(projectAssembly); } if (WorkingFolder != null) { Directory.SetCurrentDirectory(WorkingFolder); } var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (assembliesElement != null) { assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); } if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) { assembliesElement.Save(Xml.GetMetadata("FullPath")); } if (XmlV1 != null) { Transform("xUnit1.xslt", assembliesElement, XmlV1); } if (Html != null) { Transform("HTML.xslt", assembliesElement, Html); } if (NUnit != null) { Transform("NUnitXml.xslt", assembliesElement, NUnit); } } // ExitCode is set to 1 for test failures and -1 for Exceptions. return(ExitCode == 0 || (ExitCode == 1 && IgnoreFailures)); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit .NET {Environment.Version}"; if (NeedsXml) assembliesElement = new XElement("assemblies"); switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return false; } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporter = GetReporter(); if (reporter == null) return false; logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) configFileName = null; var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) projectAssembly.Configuration.ShadowCopy = shadowCopy; project.Add(projectAssembly); } if (WorkingFolder != null) Directory.SetCurrentDirectory(WorkingFolder); var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } clockTime.Stop(); if (assembliesElement != null) assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); if (completionMessages.Count > 0) reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) assembliesElement.Save(Xml.GetMetadata("FullPath")); if (XmlV1 != null) Transform("xUnit1.xslt", assembliesElement, XmlV1); if (Html != null) Transform("HTML.xslt", assembliesElement, Html); if (NUnit != null) Transform("NUnitXml.xslt", assembliesElement, NUnit); } // ExitCode is set to 1 for test failures and -1 for Exceptions. return ExitCode == 0 || (ExitCode == 1 && IgnoreFailures); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); if (TeamCity) { Log.LogError("The 'TeamCity' property is deprecated. Please set the 'Reporter' property to 'teamcity' instead."); return(false); } if (Verbose) { Log.LogError("The 'Verbose' property is deprecated. Please set the 'Reporter' property to 'verbose' instead."); return(false); } XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit .NET {Environment.Version}"; if (NeedsXml) { assembliesElement = new XElement("assemblies"); } switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return(false); } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporters = GetAvailableRunnerReporters(); var reporter = reporters.FirstOrDefault(r => r.IsEnvironmentallyEnabled); if (reporter == null && !string.IsNullOrWhiteSpace(Reporter)) { reporter = reporters.FirstOrDefault(r => string.Equals(r.RunnerSwitch, Reporter, StringComparison.OrdinalIgnoreCase)); if (reporter == null) { var switchableReporters = reporters.Where(r => !string.IsNullOrWhiteSpace(r.RunnerSwitch)).Select(r => r.RunnerSwitch.ToLowerInvariant()).OrderBy(x => x).ToList(); if (switchableReporters.Count == 0) { Log.LogError("Reporter value '{0}' is invalid. There are no available reporters.", Reporter); } else { Log.LogError("Reporter value '{0}' is invalid. Available reporters: {1}", Reporter, string.Join(", ", switchableReporters)); } return(false); } } if (reporter == null) { reporter = new DefaultRunnerReporterWithTypes(); } logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) { Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); } var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) { configFileName = null; } var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) { projectAssembly.Configuration.ShadowCopy = shadowCopy; } project.Add(projectAssembly); } if (WorkingFolder != null) { Directory.SetCurrentDirectory(WorkingFolder); } var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) { assembliesElement.Save(Xml.GetMetadata("FullPath")); } if (XmlV1 != null) { Transform("xUnit1.xslt", assembliesElement, XmlV1); } if (Html != null) { Transform("HTML.xslt", assembliesElement, Html); } if (NUnit != null) { Transform("NUnitXml.xslt", assembliesElement, NUnit); } } // ExitCode is set to 1 for test failures and -1 for Exceptions. return(ExitCode == 0 || (ExitCode == 1 && IgnoreFailures)); }
public OptimizedRemoteMessageSink(IMessageSinkWithTypes runnerSink) { this.runnerSink = runnerSink; }
void RunTestsInAssembly(IRunContext runContext, IFrameworkHandle frameworkHandle, LoggerHelper logger, IMessageSinkWithTypes reporterMessageHandler, AssemblyRunInfo runInfo) { if (cancelled) { return; } var assembly = new XunitProjectAssembly { AssemblyFilename = runInfo.AssemblyFileName }; var assemblyFileName = runInfo.AssemblyFileName; var assemblyDisplayName = Path.GetFileNameWithoutExtension(assemblyFileName); var shadowCopy = assembly.Configuration.ShadowCopyOrDefault; var appDomain = assembly.Configuration.AppDomain ?? AppDomainDefaultBehavior; var longRunningSeconds = assembly.Configuration.LongRunningTestSecondsOrDefault; if (RunSettingsHelper.DisableAppDomain) { appDomain = AppDomainSupport.Denied; } try { #if WINDOWS_UAP // For AppX Apps, use the package location assemblyFileName = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, Path.GetFileName(assemblyFileName)); #endif var diagnosticSink = new DiagnosticMessageSink(logger, assemblyDisplayName, runInfo.Configuration.DiagnosticMessagesOrDefault); using (var controller = new XunitFrontController(appDomain, assemblyFileName: assemblyFileName, configFileName: null, shadowCopy: shadowCopy, diagnosticMessageSink: MessageSinkAdapter.Wrap(diagnosticSink))) { var xunitTestCases = runInfo.TestCases.Select(tc => new { vs = tc, xunit = Deserialize(logger, controller, tc) }) .Where(tc => tc.xunit != null) .ToDictionary(tc => tc.xunit, tc => tc.vs); var executionOptions = TestFrameworkOptions.ForExecution(runInfo.Configuration); if (RunSettingsHelper.DisableParallelization) { executionOptions.SetSynchronousMessageReporting(true); executionOptions.SetDisableParallelization(true); } reporterMessageHandler.OnMessage(new TestAssemblyExecutionStarting(assembly, executionOptions)); using (var vsExecutionSink = new VsExecutionSink(reporterMessageHandler, frameworkHandle, logger, xunitTestCases, executionOptions, () => cancelled)) { IExecutionSink resultsSink = vsExecutionSink; if (longRunningSeconds > 0) { resultsSink = new DelegatingLongRunningTestDetectionSink(resultsSink, TimeSpan.FromSeconds(longRunningSeconds), diagnosticSink); } controller.RunTests(xunitTestCases.Keys.ToList(), resultsSink, executionOptions); resultsSink.Finished.WaitOne(); reporterMessageHandler.OnMessage(new TestAssemblyExecutionFinished(assembly, executionOptions, resultsSink.ExecutionSummary)); } } } catch (Exception ex) { logger.LogError("{0}: Catastrophic failure: {1}", assemblyDisplayName, ex); } }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit {CrossPlatform.Version}"; if (NeedsXml) { assembliesElement = new XElement("assemblies"); } var appDomains = default(AppDomainSupport?); switch (AppDomains?.ToLowerInvariant()) // Using ToLowerInvariant() here for back compat for when this was a boolean { case null: break; case "ifavailable": appDomains = AppDomainSupport.IfAvailable; break; case "true": case "required": appDomains = AppDomainSupport.Required; break; case "false": case "denied": appDomains = AppDomainSupport.Denied; break; default: Log.LogError("AppDomains value '{0}' is invalid: must be 'ifavailable', 'required', or 'denied'", AppDomains); return(false); } switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return(false); } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); var internalDiagnosticsMessageSink = DiagnosticMessageSink.ForInternalDiagnostics(Log, InternalDiagnosticMessages); using (AssemblyHelper.SubscribeResolveForAssembly(typeof(xunit), internalDiagnosticsMessageSink)) { var reporter = GetReporter(); if (reporter == null) { return(false); } logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) { var versionAttribute = typeof(xunit).GetTypeInfo().Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>(); Log.LogMessage(MessageImportance.High, $"xUnit.net MSBuild Runner v{versionAttribute.InformationalVersion} ({environment})"); } var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) { configFileName = null; } var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) { projectAssembly.Configuration.ShadowCopy = shadowCopy; } project.Add(projectAssembly); } if (WorkingFolder != null) { Directory.SetCurrentDirectory(WorkingFolder); } var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly, appDomains))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly, appDomains); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (assembliesElement != null) { assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); } if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) { using (var xmlStream = new FileStream(Xml.GetMetadata("FullPath"), FileMode.OpenOrCreate, FileAccess.Write)) assembliesElement.Save(xmlStream); } if (XmlV1 != null) { CrossPlatform.Transform(logger, "XmlV1", "xUnit1.xslt", assembliesElement, XmlV1); } if (Html != null) { CrossPlatform.Transform(logger, "Html", "HTML.xslt", assembliesElement, Html); } if (NUnit != null) { CrossPlatform.Transform(logger, "NUnit", "NUnitXml.xslt", assembliesElement, NUnit); } if (JUnit != null) { CrossPlatform.Transform(logger, "JUnit", "JUnitXml.xslt", assembliesElement, JUnit); } } // ExitCode is set to 1 for test failures and -1 for Exceptions. return(ExitCode == 0 || (ExitCode == 1 && IgnoreFailures)); }
public int EntryPoint(string[] args) { var assemblyUnderTest = Assembly.GetEntryAssembly(); commandLine = CommandLine.Parse(assemblyUnderTest.GetLocalCodeBase(), args); try { var reporters = GetAvailableRunnerReporters(); if (args.Length > 0 && (args[0] == "-?" || args[0] == "/?" || args[0] == "-h" || args[0] == "--help")) { PrintHeader(); PrintUsage(reporters); return(2); } // TODO: What is the portable version of this? #if NETFRAMEWORK AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; #endif Console.CancelKeyPress += (sender, e) => { if (!cancel) { Console.WriteLine("Canceling... (Press Ctrl+C again to terminate)"); cancel = true; e.Cancel = true; } }; var defaultDirectory = Directory.GetCurrentDirectory(); if (!defaultDirectory.EndsWith(new string(new[] { Path.DirectorySeparatorChar }), StringComparison.Ordinal)) { defaultDirectory += Path.DirectorySeparatorChar; } var reporter = commandLine.ChooseReporter(reporters); if (commandLine.Pause) { Console.Write("Press any key to start execution..."); Console.ReadKey(true); Console.WriteLine(); } if (commandLine.Debug) { Debugger.Launch(); } logger = new ConsoleRunnerLogger(!commandLine.NoColor, consoleLock); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!commandLine.NoLogo) { PrintHeader(); } // TODO: Will need more things here, like filters and output transform, when they're back var failCount = RunProject(commandLine.Project, commandLine.ParallelizeTestCollections, commandLine.MaxParallelThreads, commandLine.DiagnosticMessages, commandLine.NoColor, commandLine.FailSkips, commandLine.StopOnFail, commandLine.InternalDiagnosticMessages); if (cancel) { return(-1073741510); // 0xC000013A: The application terminated as a result of a CTRL+C } if (commandLine.Wait) { Console.WriteLine(); Console.Write("Press any key to continue..."); Console.ReadKey(); Console.WriteLine(); } return(failCount > 0 ? 1 : 0); } catch (Exception ex) { if (!commandLine.NoColor) { ConsoleHelper.SetForegroundColor(ConsoleColor.Red); } Console.WriteLine($"error: {ex.Message}"); if (commandLine.InternalDiagnosticMessages) { if (!commandLine.NoColor) { ConsoleHelper.SetForegroundColor(ConsoleColor.DarkGray); } Console.WriteLine(ex.StackTrace); } return(ex is ArgumentException ? 3 : 4); } finally { if (!commandLine.NoColor) { ConsoleHelper.ResetColor(); } } }
public int Run(string[] args) { try { var reporters = GetAvailableRunnerReporters(); if (args.Length == 0 || args.Any(arg => arg == "-?" || arg == "-help")) { PrintHeader(); PrintUsage(reporters); return(2); } #if !NETCOREAPP1_0 AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; #endif var commandLine = CommandLine.Parse(reporters, args); #if !NETCOREAPP1_0 if (commandLine.Debug) { Debugger.Launch(); } #else if (commandLine.Debug) { Console.WriteLine("Debug support is not available in .NET Core."); return(2); } #endif logger = new ConsoleRunnerLogger(!commandLine.NoColor); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(commandLine.Reporter.CreateMessageHandler(logger)); if (!commandLine.NoLogo) { PrintHeader(); } var testsToRun = commandLine.DesignTimeTestUniqueNames; if (commandLine.Port.HasValue) { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); var ipEndPoint = new IPEndPoint(IPAddress.Loopback, commandLine.Port.Value); socket.Connect(ipEndPoint); var networkStream = new NetworkStream(socket); UseTestSinksWithSockets(networkStream); if (commandLine.WaitCommand) { var reader = new BinaryReader(networkStream); testExecutionSink.SendWaitingCommand(); var rawMessage = reader.ReadString(); var message = JsonConvert.DeserializeObject <Message>(rawMessage); testsToRun = message.Payload.ToObject <RunTestsMessage>().Tests; } } else { UseTestSinksWithStandardOutputStreams(); } var failCount = RunProject(commandLine.Project, commandLine.ParallelizeAssemblies, commandLine.ParallelizeTestCollections, commandLine.MaxParallelThreads, commandLine.DiagnosticMessages, commandLine.NoColor, commandLine.AppDomains, commandLine.FailSkips, commandLine.DesignTime, commandLine.List, testsToRun); if (commandLine.Wait) { WaitForInput(); } return(failCount > 0 ? 1 : 0); } catch (ArgumentException ex) { Console.WriteLine("error: {0}", ex.Message); return(3); } catch (BadImageFormatException ex) { Console.WriteLine("{0}", ex.Message); return(4); } finally { Console.ResetColor(); } }
/// <summary> /// Provides a simulation of <see cref="IMessageSink.OnMessage"/> for <see cref="IMessageSinkWithTypes"/>, /// to make it easier to directly dispatch messages from the runner. /// </summary> /// <param name="messageSink">The message sink</param> /// <param name="message">The message to be dispatched</param> /// <returns>The result of calling the message sink</returns> public static bool OnMessage(this IMessageSinkWithTypes messageSink, IMessageSinkMessage message) => messageSink.OnMessageWithTypes(message, MessageSinkAdapter.GetImplementedInterfaces(message));
public static int Main(string[] args) { try { var reporters = GetAvailableRunnerReporters(); if (args.Length == 0 || args[0] == "-?") { PrintHeader(); PrintUsage(reporters); return 2; } AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; Console.CancelKeyPress += (sender, e) => { if (!cancel) { Console.WriteLine("Canceling... (Press Ctrl+C again to terminate)"); cancel = true; e.Cancel = true; } }; var defaultDirectory = Directory.GetCurrentDirectory(); if (!defaultDirectory.EndsWith(new string(new[] { Path.DirectorySeparatorChar }), StringComparison.Ordinal)) defaultDirectory += Path.DirectorySeparatorChar; var commandLine = CommandLine.Parse(reporters, args); if (commandLine.Debug) Debugger.Launch(); logger = new ConsoleRunnerLogger(!commandLine.NoColor); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(commandLine.Reporter.CreateMessageHandler(logger)); if (!commandLine.NoLogo) PrintHeader(); var failCount = RunProject(commandLine.Project, commandLine.Serialize, commandLine.ParallelizeAssemblies, commandLine.ParallelizeTestCollections, commandLine.MaxParallelThreads, commandLine.DiagnosticMessages, commandLine.NoColor, commandLine.NoAppDomain, commandLine.FailSkips); if (commandLine.Wait) { Console.WriteLine(); Console.Write("Press any key to continue..."); Console.ReadKey(); Console.WriteLine(); } return failCount > 0 ? 1 : 0; } catch (ArgumentException ex) { Console.WriteLine($"error: {ex.Message}"); return 3; } catch (BadImageFormatException ex) { Console.WriteLine(ex.Message); return 4; } finally { Console.ResetColor(); } }
public TestableDelegatingLongRunningTestDetectionSink(int longRunningSeconds, IMessageSinkWithTypes diagnosticMessageSink) : base(Substitute.For<IExecutionSink>(), TimeSpan.FromSeconds(longRunningSeconds), diagnosticMessageSink) { }