/// <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>
 /// 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);
 }
Beispiel #8
0
        /// <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));
        }
Beispiel #11
0
 public TestableTestExecutionSink(IMessageSinkWithTypes diagnosticMessageSink = null,
                                  ConcurrentDictionary <string, ExecutionSummary> competionMessages = null,
                                  Func <bool> cancelThunk = null,
                                  int longRunningSeconds  = -1)
     : base(diagnosticMessageSink, competionMessages, cancelThunk, longRunningSeconds)
 {
 }
 /// <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 DelegatingExecutionSummarySinkTests()
    {
        innerSink = Substitute.For<IMessageSinkWithTypes>();
        innerSink.OnMessageWithTypes(null, null).ReturnsForAnyArgs(true);

        testMessage = Substitute.For<IMessageSinkMessage>();
    }
Beispiel #14
0
        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);
        }
Beispiel #15
0
 /// <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);
 }
Beispiel #16
0
 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)
 {
 }
Beispiel #17
0
        /// <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;
        }
Beispiel #20
0
        /// <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;
        }
Beispiel #21
0
    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);
    }
Beispiel #22
0
        /// <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;
            }
        }
Beispiel #23
0
        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;
        }
Beispiel #24
0
        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();
                }
            }
        }
Beispiel #25
0
 /// <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));
Beispiel #26
0
 MessageSinkAdapter(IMessageSinkWithTypes inner)
 {
     this.inner = inner;
 }
Beispiel #27
0
        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);
            }
        }
Beispiel #28
0
        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();
            }
        }
 /// <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));
Beispiel #30
0
        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));
        }
Beispiel #31
0
        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);
        }
Beispiel #32
0
        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));
        }
Beispiel #33
0
 public OptimizedRemoteMessageSink(IMessageSinkWithTypes runnerSink)
 {
     this.runnerSink = runnerSink;
 }
Beispiel #34
0
        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);
            }
        }
Beispiel #35
0
        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));
        }
Beispiel #36
0
        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();
                }
            }
        }
Beispiel #37
0
        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();
            }
        }
 MessageSinkAdapter(IMessageSinkWithTypes inner)
 {
     this.inner = inner;
 }
 /// <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));
Beispiel #40
0
        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) { }
        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 OptimizedRemoteMessageSink(IMessageSinkWithTypes runnerSink)
 {
     this.runnerSink = runnerSink;
 }