From 929c2beeb80e7fb0a2b529cad12d6aa6d00847e9 Mon Sep 17 00:00:00 2001 From: Jon Hamm Date: Wed, 26 Aug 2015 23:11:17 -0400 Subject: [PATCH] Add support for new Xunit2 runner -noappdomain flag This flag exists in versions starting in 2.1beta4. Before executing the test process with the parameter NoAppDomain = true, this target will detect if the xunit console runner supports this flag. If it does not, the target will set the parameter to false. --- src/app/FakeLib/UnitTest/XUnit/XUnit2.fs | 26 ++++++++++++++++++++++-- src/test/Test.FAKECore/XUnit2Specs.cs | 12 +++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/app/FakeLib/UnitTest/XUnit/XUnit2.fs b/src/app/FakeLib/UnitTest/XUnit/XUnit2.fs index 67a70ca042a..c482d525a5e 100644 --- a/src/app/FakeLib/UnitTest/XUnit/XUnit2.fs +++ b/src/app/FakeLib/UnitTest/XUnit/XUnit2.fs @@ -4,6 +4,7 @@ module Fake.Testing.XUnit2 open System open System.IO +open System.Linq open System.Text open Fake @@ -14,6 +15,7 @@ Copyright (C) 2014 Outercurve Foundation. usage: xunit.console [configFile] [options] Valid options: + -noappdomain : do not use app domains to run test code -parallel option : set parallelization based on option : none - turn off all parallelization : collections - only parallelize collections @@ -70,6 +72,8 @@ type CollectionConcurrencyMode = type XUnit2Params = { /// The path to the xUnit console runner: `xunit.console.exe` ToolPath : string + /// Do not use app domains to run test code. + NoAppDomain : bool /// The xUnit parallelization mode. Parallel : ParallelMode /// The xUnit thread limiting strategy. @@ -107,6 +111,7 @@ type XUnit2Params = /// /// ## Defaults /// +/// - `NoAppDomain` - `false` /// - `Parallel` - `NoParallelization` /// - `MaxThreads` - `Default` /// - `HtmlOutputPath` - `None` @@ -124,7 +129,8 @@ type XUnit2Params = /// - `Silent` - `false` /// - `Wait` - `false` let XUnit2Defaults = - { Parallel = NoParallelization + { NoAppDomain = false + Parallel = NoParallelization MaxThreads = Default HtmlOutputPath = None XmlOutputPath = None @@ -151,6 +157,7 @@ let internal buildXUnit2Args assemblies parameters = new StringBuilder() |> appendFileNamesIfNotNull assemblies + |> appendIfTrueWithoutQuotes parameters.NoAppDomain "-noappdomain" |> appendWithoutQuotes "-parallel" |> appendWithoutQuotes (ParallelMode.ToArgument parameters.Parallel) |> appendIfSome (CollectionConcurrencyMode.ToArgument parameters.MaxThreads) (sprintf "-maxthreads %d") @@ -167,6 +174,16 @@ let internal buildXUnit2Args assemblies parameters = |> appendTraits parameters.ExcludeTraits "-notrait" |> toText +/// Helper method to detect if the xunit console runner supports the -noappdomain flag. +/// If the xunit console runner does not support this flag, it will change the value to false +/// so it does not interfere with older versions. +let internal discoverNoAppDomainExists parameters = + let helpText = + ExecProcessAndReturnMessages (fun info -> + info.FileName <- parameters.ToolPath ) (TimeSpan.FromMinutes 1.) + let canSetNoAppDomain = helpText.Messages.Any(fun msg -> msg.Contains("-noappdomain")) + {parameters with NoAppDomain = canSetNoAppDomain} + module internal ResultHandling = let (|OK|Failure|) = function | 0 -> OK @@ -205,7 +222,12 @@ module internal ResultHandling = let xUnit2 setParams assemblies = let details = separated ", " assemblies traceStartTask "xUnit2" details - let parameters = setParams XUnit2Defaults + let parametersFirst = setParams XUnit2Defaults + + let parameters = + if parametersFirst.NoAppDomain + then discoverNoAppDomainExists parametersFirst + else parametersFirst let result = ExecProcess (fun info -> diff --git a/src/test/Test.FAKECore/XUnit2Specs.cs b/src/test/Test.FAKECore/XUnit2Specs.cs index de466cee981..cd4622561e0 100644 --- a/src/test/Test.FAKECore/XUnit2Specs.cs +++ b/src/test/Test.FAKECore/XUnit2Specs.cs @@ -70,6 +70,9 @@ internal class When_using_the_default_parameters It should_not_force_AppVeyor_output = () => Arguments.ShouldNotContain(" -appveyor"); + + It should_not_force_NoAppDomain = () => + Arguments.ShouldNotContain(" -noappdomain"); } internal class When_using_parameters_which_include_traits @@ -79,6 +82,7 @@ internal class When_using_parameters_which_include_traits { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.XUnit2Defaults.Parallel, XUnit2.XUnit2Defaults.MaxThreads, XUnit2.XUnit2Defaults.HtmlOutputPath, @@ -114,6 +118,7 @@ internal class When_using_parameters_which_include_reports { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.XUnit2Defaults.Parallel, XUnit2.XUnit2Defaults.MaxThreads, FSharpOption.Some("html.html"), @@ -152,6 +157,7 @@ internal class When_using_parameters_which_request_total_parallel_execution { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.ParallelMode.All, XUnit2.CollectionConcurrencyMode.Unlimited, XUnit2.XUnit2Defaults.HtmlOutputPath, @@ -184,6 +190,7 @@ internal class When_using_parameters_which_request_assembly_only_parallel_execut { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.ParallelMode.Assemblies, XUnit2.CollectionConcurrencyMode.Default, XUnit2.XUnit2Defaults.HtmlOutputPath, @@ -216,6 +223,7 @@ internal class When_using_parameters_which_request_collection_only_parallel_exec { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.ParallelMode.Collections, XUnit2.CollectionConcurrencyMode.NewMaxThreads(42), XUnit2.XUnit2Defaults.HtmlOutputPath, @@ -249,6 +257,7 @@ internal class When_using_parameters_which_request_non_default_flags { Parameters = new XUnit2.XUnit2Params( XUnit2.XUnit2Defaults.ToolPath, + !XUnit2.XUnit2Defaults.NoAppDomain, XUnit2.XUnit2Defaults.Parallel, XUnit2.XUnit2Defaults.MaxThreads, XUnit2.XUnit2Defaults.HtmlOutputPath, @@ -281,6 +290,9 @@ internal class When_using_parameters_which_request_non_default_flags It should_force_AppVeyor_output = () => Arguments.ShouldContain(" -appveyor"); + + It should_force_NoAppDomain = () => + Arguments.ShouldContain(" -noappdomain"); } [Subject(typeof(XUnit2), "result handling")]