diff --git a/.gitignore b/.gitignore
index 29b7afec0..de69fc2e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,4 +177,6 @@ test-results
package
images
MockAssemblyResult.xml
-PortabilityAnalysis*.html
\ No newline at end of file
+PortabilityAnalysis*.html
+tools
+!tools/packages.config
diff --git a/.travis.yml b/.travis.yml
index 0fbf932db..593e92bd8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,14 +3,10 @@ sudo: false
mono:
- latest
- 4.2.4
- - 3.2.8
os:
- linux
- osx
matrix:
- exclude:
- - os: osx
- mono: 3.2.8
allow_failures:
- mono: latest
fast_finish: true
diff --git a/NUnitConsole.sln b/NUnitConsole.sln
index a33e06ec9..70d3fbbe0 100644
--- a/NUnitConsole.sln
+++ b/NUnitConsole.sln
@@ -51,23 +51,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "engine", "engine", "{43A219
nuget\engine\nunit.nuget.addins = nuget\engine\nunit.nuget.addins
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "framework", "framework", "{BC87F477-1A7A-45D0-9AC1-9F7315264732}"
- ProjectSection(SolutionItems) = preProject
- nuget\framework\nunit.nuspec = nuget\framework\nunit.nuspec
- nuget\framework\nunitCF.nuspec = nuget\framework\nunitCF.nuspec
- nuget\framework\nunitSL.nuspec = nuget\framework\nunitSL.nuspec
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nunitlite", "nunitlite", "{140CDAD6-6E11-4A97-94F3-B23A14391117}"
- ProjectSection(SolutionItems) = preProject
- nuget\nunitlite\install.ps1 = nuget\nunitlite\install.ps1
- nuget\nunitlite\nunitlite.nuspec = nuget\nunitlite\nunitlite.nuspec
- nuget\nunitlite\nunitliteCF.nuspec = nuget\nunitlite\nunitliteCF.nuspec
- nuget\nunitlite\nunitliteSL.nuspec = nuget\nunitlite\nunitliteSL.nuspec
- nuget\nunitlite\Program.cs = nuget\nunitlite\Program.cs
- nuget\nunitlite\Program.vb = nuget\nunitlite\Program.vb
- EndProjectSection
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "runners", "runners", "{F3E87D0F-6F06-4C0B-AE06-42C0834C3C6E}"
ProjectSection(SolutionItems) = preProject
nuget\runners\nunit.console-runner-with-extensions.nuspec = nuget\runners\nunit.console-runner-with-extensions.nuspec
@@ -129,8 +112,6 @@ Global
{B310A760-8AE1-41CA-81F8-03B12E2FCE30} = {576DB1E6-C5EC-4FEF-A826-EC19D8BEE572}
{28B605B2-E2E9-417E-8369-49E263F1F31B} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39}
{43A219A8-2995-4884-806F-FDB9CD25D403} = {A972031D-2F61-4183-AF75-99EE1A9F6B32}
- {BC87F477-1A7A-45D0-9AC1-9F7315264732} = {A972031D-2F61-4183-AF75-99EE1A9F6B32}
- {140CDAD6-6E11-4A97-94F3-B23A14391117} = {A972031D-2F61-4183-AF75-99EE1A9F6B32}
{F3E87D0F-6F06-4C0B-AE06-42C0834C3C6E} = {A972031D-2F61-4183-AF75-99EE1A9F6B32}
{D2C80E4B-1117-4F02-AB02-E453BDA0C58E} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39}
EndGlobalSection
diff --git a/build.cake b/build.cake
index e6e4dfa1e..ba2fa9786 100644
--- a/build.cake
+++ b/build.cake
@@ -334,20 +334,6 @@ Task("PackageConsole")
});
});
-Task("PackageZip")
- .IsDependentOn("CreateImage")
- .Does(() =>
- {
- CreateDirectory(PACKAGE_DIR);
-
- var currentImageDir = IMAGE_DIR + "NUnit-" + packageVersion + "/";
-
- var zipFiles =
- GetFiles(currentImageDir + "*.*") +
- GetFiles(currentImageDir + "bin/*.*");
- Zip(currentImageDir, File(ZIP_PACKAGE), zipFiles);
- });
-
//////////////////////////////////////////////////////////////////////
// SETUP AND TEARDOWN TASKS
//////////////////////////////////////////////////////////////////////
@@ -472,8 +458,7 @@ Task("Test")
Task("Package")
.IsDependentOn("CheckForError")
.IsDependentOn("PackageEngine")
- .IsDependentOn("PackageConsole")
- .IsDependentOn("PackageZip");
+ .IsDependentOn("PackageConsole");
Task("Appveyor")
.IsDependentOn("Build")
diff --git a/build.ps1 b/build.ps1
index 519ad09eb..44de57932 100644
--- a/build.ps1
+++ b/build.ps1
@@ -1,3 +1,44 @@
+##########################################################################
+# This is the Cake bootstrapper script for PowerShell.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
+
+<#
+
+.SYNOPSIS
+This is a Powershell script to bootstrap a Cake build.
+
+.DESCRIPTION
+This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
+and execute your Cake build script with the parameters you provide.
+
+.PARAMETER Script
+The build script to execute.
+.PARAMETER Target
+The build script target to run.
+.PARAMETER Configuration
+The build configuration to use.
+.PARAMETER Verbosity
+Specifies the amount of information to be displayed.
+.PARAMETER Experimental
+Tells Cake to use the latest Roslyn release.
+.PARAMETER WhatIf
+Performs a dry run of the build script.
+No tasks will be executed.
+.PARAMETER Mono
+Tells Cake to use the Mono scripting engine.
+.PARAMETER SkipToolPackageRestore
+Skips restoring of packages.
+.PARAMETER ScriptArgs
+Remaining arguments are added here.
+
+.LINK
+http://cakebuild.net
+
+#>
+
+[CmdletBinding()]
Param(
[string]$Script = "build.cake",
[string]$Target = "Default",
@@ -6,16 +47,63 @@ Param(
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
[string]$Verbosity = "Verbose",
[switch]$Experimental,
- [switch]$WhatIf
+ [Alias("DryRun","Noop")]
+ [switch]$WhatIf,
+ [switch]$Mono,
+ [switch]$SkipToolPackageRestore,
+ [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+ [string[]]$ScriptArgs
)
+[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
+function MD5HashFile([string] $filePath)
+{
+ if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
+ {
+ return $null
+ }
+
+ [System.IO.Stream] $file = $null;
+ [System.Security.Cryptography.MD5] $md5 = $null;
+ try
+ {
+ $md5 = [System.Security.Cryptography.MD5]::Create()
+ $file = [System.IO.File]::OpenRead($filePath)
+ return [System.BitConverter]::ToString($md5.ComputeHash($file))
+ }
+ finally
+ {
+ if ($file -ne $null)
+ {
+ $file.Dispose()
+ }
+ }
+}
+
+Write-Host "Preparing to run build script..."
+
+if(!$PSScriptRoot){
+ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+}
+
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
+$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
+$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
+$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
+
+# Should we use mono?
+$UseMono = "";
+if($Mono.IsPresent) {
+ Write-Verbose -Message "Using the Mono based scripting engine."
+ $UseMono = "-mono"
+}
-# Should we use experimental build of Roslyn?
+# Should we use the new Roslyn?
$UseExperimental = "";
-if($Experimental.IsPresent) {
+if($Experimental.IsPresent -and !($Mono.IsPresent)) {
+ Write-Verbose -Message "Using experimental version of Roslyn."
$UseExperimental = "-experimental"
}
@@ -25,31 +113,77 @@ if($WhatIf.IsPresent) {
$UseDryRun = "-dryrun"
}
-# Try download NuGet.exe if do not exist.
+# Make sure tools folder exists
+if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
+ Write-Verbose -Message "Creating tools directory..."
+ New-Item -Path $TOOLS_DIR -Type directory | out-null
+}
+
+# Make sure that packages.config exist.
+if (!(Test-Path $PACKAGES_CONFIG)) {
+ Write-Verbose -Message "Downloading packages.config..."
+ try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
+ Throw "Could not download packages.config."
+ }
+}
+
+# Try find NuGet.exe in path if not exists
if (!(Test-Path $NUGET_EXE)) {
- Invoke-WebRequest -Uri http://nuget.org/nuget.exe -OutFile $NUGET_EXE
+ Write-Verbose -Message "Trying to find nuget.exe in PATH..."
+ $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
+ $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
+ if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
+ Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
+ $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
+ }
}
-# Make sure NuGet exists where we expect it.
+# Try download NuGet.exe if not exists
if (!(Test-Path $NUGET_EXE)) {
- Throw "Could not find NuGet.exe"
+ Write-Verbose -Message "Downloading NuGet.exe..."
+ try {
+ (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
+ } catch {
+ Throw "Could not download NuGet.exe."
+ }
}
-# Restore tools from NuGet.
-Push-Location
-Set-Location $TOOLS_DIR
-Invoke-Expression "$NUGET_EXE install -ExcludeVersion"
-Pop-Location
-if ($LASTEXITCODE -ne 0) {
- exit $LASTEXITCODE
+# Save nuget.exe path to environment to be available to child processed
+$ENV:NUGET_EXE = $NUGET_EXE
+
+# Restore tools from NuGet?
+if(-Not $SkipToolPackageRestore.IsPresent) {
+ Push-Location
+ Set-Location $TOOLS_DIR
+
+ # Check for changes in packages.config and remove installed tools if true.
+ [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
+ if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
+ ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
+ Write-Verbose -Message "Missing or changed package.config hash..."
+ Remove-Item * -Recurse -Exclude packages.config,nuget.exe
+ }
+
+ Write-Verbose -Message "Restoring tools from NuGet..."
+ $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
+
+ if ($LASTEXITCODE -ne 0) {
+ Throw "An error occured while restoring NuGet tools."
+ }
+ else
+ {
+ $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
+ }
+ Write-Verbose -Message ($NuGetOutput | out-string)
+ Pop-Location
}
# Make sure that Cake has been installed.
if (!(Test-Path $CAKE_EXE)) {
- Throw "Could not find Cake.exe"
+ Throw "Could not find Cake.exe at $CAKE_EXE"
}
# Start Cake
-Invoke-Expression "$CAKE_EXE `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseDryRun $UseExperimental"
-Write-Host
+Write-Host "Running build script..."
+Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
exit $LASTEXITCODE
\ No newline at end of file
diff --git a/build.sh b/build.sh
index b9f997fc7..6e8f207c8 100755
--- a/build.sh
+++ b/build.sh
@@ -1,22 +1,35 @@
-#!/bin/bash
-###############################################################
-# This is the Cake bootstrapper script that is responsible for
-# downloading Cake and all specified tools from NuGet.
-###############################################################
+#!/usr/bin/env bash
+
+##########################################################################
+# This is the Cake bootstrapper script for Linux and OS X.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
# Define directories.
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TOOLS_DIR=$SCRIPT_DIR/tools
NUGET_EXE=$TOOLS_DIR/nuget.exe
CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
+PACKAGES_CONFIG=$TOOLS_DIR/packages.config
+PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
+
+# Define md5sum or md5 depending on Linux/OSX
+MD5_EXE=
+if [[ "$(uname -s)" == "Darwin" ]]; then
+ MD5_EXE="md5 -r"
+else
+ MD5_EXE="md5sum"
+fi
# Define default arguments.
SCRIPT="build.cake"
TARGET="Default"
CONFIGURATION="Release"
VERBOSITY="verbose"
-DRYRUN=false
+DRYRUN=
SHOW_VERSION=false
+SCRIPT_ARGUMENTS=()
# Parse arguments.
for i in "$@"; do
@@ -25,16 +38,33 @@ for i in "$@"; do
-t|--target) TARGET="$2"; shift ;;
-c|--configuration) CONFIGURATION="$2"; shift ;;
-v|--verbosity) VERBOSITY="$2"; shift ;;
- -d|--dryrun) DRYRUN=true ;;
+ -d|--dryrun) DRYRUN="-dryrun" ;;
--version) SHOW_VERSION=true ;;
+ --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;;
+ *) SCRIPT_ARGUMENTS+=("$1") ;;
esac
shift
done
+# Make sure the tools folder exist.
+if [ ! -d "$TOOLS_DIR" ]; then
+ mkdir "$TOOLS_DIR"
+fi
+
+# Make sure that packages.config exist.
+if [ ! -f "$TOOLS_DIR/packages.config" ]; then
+ echo "Downloading packages.config..."
+ curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages
+ if [ $? -ne 0 ]; then
+ echo "An error occured while downloading packages.config."
+ exit 1
+ fi
+fi
+
# Download NuGet if it does not exist.
-if [ ! -f $NUGET_EXE ]; then
+if [ ! -f "$NUGET_EXE" ]; then
echo "Downloading NuGet..."
- curl -Lsfo $NUGET_EXE https://www.nuget.org/nuget.exe
+ curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
if [ $? -ne 0 ]; then
echo "An error occured while downloading nuget.exe."
exit 1
@@ -42,24 +72,30 @@ if [ ! -f $NUGET_EXE ]; then
fi
# Restore tools from NuGet.
-pushd $TOOLS_DIR >/dev/null
-mono $NUGET_EXE install -ExcludeVersion
+pushd "$TOOLS_DIR" >/dev/null
+if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then
+ find . -type d ! -name . | xargs rm -rf
+fi
+
+mono "$NUGET_EXE" install -ExcludeVersion
+if [ $? -ne 0 ]; then
+ echo "Could not restore NuGet packages."
+ exit 1
+fi
+
+$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5
+
popd >/dev/null
# Make sure that Cake has been installed.
-if [ ! -f $CAKE_EXE ]; then
- echo "Could not find Cake.exe."
+if [ ! -f "$CAKE_EXE" ]; then
+ echo "Could not find Cake.exe at '$CAKE_EXE'."
exit 1
fi
# Start Cake
if $SHOW_VERSION; then
- mono $CAKE_EXE -version
-elif $DRYRUN; then
- mono $CAKE_EXE $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET -dryrun
+ exec mono "$CAKE_EXE" -version
else
- mono $CAKE_EXE $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET
-fi
-
-exit $?
-
+ exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}"
+fi
\ No newline at end of file
diff --git a/packages/repositories.config b/packages/repositories.config
index 98e54c9fb..d0745c6e6 100644
--- a/packages/repositories.config
+++ b/packages/repositories.config
@@ -1,21 +1,12 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/NUnitConsole/nunit3-console.tests/CommandLineTests.cs b/src/NUnitConsole/nunit3-console.tests/CommandLineTests.cs
index 74f365c4a..3d32ec454 100644
--- a/src/NUnitConsole/nunit3-console.tests/CommandLineTests.cs
+++ b/src/NUnitConsole/nunit3-console.tests/CommandLineTests.cs
@@ -104,6 +104,7 @@ public void CanRecognizeBooleanOptions(string propertyName, string pattern)
[TestCase("DisplayTestLabels", "labels", new string[] { "Off", "On", "All" }, new string[] { "JUNK" })]
[TestCase("InternalTraceLevel", "trace", new string[] { "Off", "Error", "Warning", "Info", "Debug", "Verbose" }, new string[] { "JUNK" })]
[TestCase("DefaultTestNamePattern", "test-name-format", new string[] { "{m}{a}" }, new string[0])]
+ [TestCase("ConsoleEncoding", "encoding", new string[] { "utf-8", "ascii", "unicode" }, new string[0])]
public void CanRecognizeStringOptions(string propertyName, string pattern, string[] goodValues, string[] badValues)
{
string[] prototypes = pattern.Split('|');
@@ -209,6 +210,7 @@ public void CanRecognizeIntOptions(string propertyName, string pattern)
[TestCase("--trace")]
[TestCase("--test-name-format")]
[TestCase("--params")]
+ [TestCase("--encoding")]
public void MissingValuesAreReported(string option)
{
ConsoleOptions options = new ConsoleOptions(option + "=");
diff --git a/src/NUnitConsole/nunit3-console.tests/ConsoleOutputTests.cs b/src/NUnitConsole/nunit3-console.tests/ConsoleOutputTests.cs
index a0adf1a97..70a12bb1b 100644
--- a/src/NUnitConsole/nunit3-console.tests/ConsoleOutputTests.cs
+++ b/src/NUnitConsole/nunit3-console.tests/ConsoleOutputTests.cs
@@ -21,10 +21,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
-using System;
-using System.Collections.Generic;
-using System.Text;
using NUnit.Framework;
+using System;
namespace NUnit.ConsoleRunner.Tests
{
@@ -71,5 +69,11 @@ public void Test()
Console.Error.WriteLine("Test: Console.Error.WriteLine()");
TestContext.WriteLine("Test: TestContext.WriteLine()");
}
+
+ [Test]
+ public void ConsoleEncoding()
+ {
+ TestContext.WriteLine("•ÑÜńĭŧ·");
+ }
}
}
diff --git a/src/NUnitConsole/nunit3-console.tests/TestEventHandlerTests.cs b/src/NUnitConsole/nunit3-console.tests/TestEventHandlerTests.cs
index 4f6d436c9..8d0e9239f 100644
--- a/src/NUnitConsole/nunit3-console.tests/TestEventHandlerTests.cs
+++ b/src/NUnitConsole/nunit3-console.tests/TestEventHandlerTests.cs
@@ -58,16 +58,16 @@ public void EventsWriteExpectedOutput(string report, string labels, string expec
static TestCaseData[] EventData = new TestCaseData[]
{
// Start Events
- new TestCaseData("", "Off", ""),
- new TestCaseData("", "On", ""),
- new TestCaseData("", "All", ""),
- new TestCaseData("", "Off", ""),
- new TestCaseData("", "On", ""),
- new TestCaseData("", "All", ""),
+ new TestCaseData("", "Off", ""),
+ new TestCaseData("", "On", ""),
+ new TestCaseData("", "All", "=> SomeName\r\n"),
+ new TestCaseData("", "Off", ""),
+ new TestCaseData("", "On", ""),
+ new TestCaseData("", "All", ""),
// Finish Events - No Output
new TestCaseData("", "Off", ""),
new TestCaseData("", "On", ""),
- new TestCaseData("", "All", "=> SomeName\r\n"),
+ new TestCaseData("", "All", ""),
new TestCaseData("", "Off", ""),
new TestCaseData("", "On", ""),
new TestCaseData("", "All", ""),
@@ -83,7 +83,7 @@ public void EventsWriteExpectedOutput(string report, string labels, string expec
new TestCaseData(
"",
"All",
- "=> SomeName\r\nOUTPUT\r\n"),
+ "OUTPUT\r\n"),
new TestCaseData(
"",
"Off",
@@ -95,7 +95,7 @@ public void EventsWriteExpectedOutput(string report, string labels, string expec
new TestCaseData(
"",
"All",
- "=> SomeName\r\nOUTPUT\r\n"),
+ "OUTPUT\r\n"),
// Output Events
new TestCaseData(
"OUTPUT",
diff --git a/src/NUnitConsole/nunit3-console/CommandLineOptions.cs b/src/NUnitConsole/nunit3-console/CommandLineOptions.cs
index bca033a59..c9519506b 100644
--- a/src/NUnitConsole/nunit3-console/CommandLineOptions.cs
+++ b/src/NUnitConsole/nunit3-console/CommandLineOptions.cs
@@ -109,6 +109,8 @@ public CommandLineOptions(params string[] args)
// Output Control
+ public string ConsoleEncoding { get; private set; }
+
public bool NoHeader { get; private set; }
public bool NoColor { get; private set; }
@@ -373,6 +375,9 @@ protected virtual void ConfigureOptions()
this.Add("version|V", "Display the header and exit.",
v => ShowVersion = v != null);
+ this.Add("encoding=", "Specifies the encoding to use for Console standard output, for example utf-8, ascii, unicode.",
+ v => ConsoleEncoding = RequiredValue(v, "--encoding"));
+
// Default
this.Add("<>", v =>
{
diff --git a/src/NUnitConsole/nunit3-console/Program.cs b/src/NUnitConsole/nunit3-console/Program.cs
index 961bc6b33..0f2b1709c 100644
--- a/src/NUnitConsole/nunit3-console/Program.cs
+++ b/src/NUnitConsole/nunit3-console/Program.cs
@@ -24,6 +24,7 @@
using System;
using System.IO;
using System.Reflection;
+using System.Text;
using NUnit.Common;
using NUnit.Options;
using NUnit.Engine;
@@ -64,6 +65,20 @@ public static int Main(string[] args)
return ConsoleRunner.INVALID_ARG;
}
+ if (!string.IsNullOrEmpty(Options.ConsoleEncoding))
+ {
+ try
+ {
+ Console.OutputEncoding = Encoding.GetEncoding(Options.ConsoleEncoding);
+ }
+ catch (Exception error)
+ {
+ WriteHeader();
+ OutWriter.WriteLine(ColorStyle.Error, string.Format("Unsupported Encoding, {0}", error.Message));
+ return ConsoleRunner.INVALID_ARG;
+ }
+ }
+
//ColorConsole.Enabled = !Options.NoColor;
// Create SettingsService early so we know the trace level right at the start
diff --git a/src/NUnitConsole/nunit3-console/TestEventHandler.cs b/src/NUnitConsole/nunit3-console/TestEventHandler.cs
index a9f85ac0d..f411bcd35 100644
--- a/src/NUnitConsole/nunit3-console/TestEventHandler.cs
+++ b/src/NUnitConsole/nunit3-console/TestEventHandler.cs
@@ -55,6 +55,10 @@ public void OnTestEvent(string report)
var testEvent = doc.FirstChild;
switch (testEvent.Name)
{
+ case "start-test":
+ TestStarted(testEvent);
+ break;
+
case "test-case":
TestFinished(testEvent);
break;
@@ -73,13 +77,18 @@ public void OnTestEvent(string report)
#region Individual Handlers
- private void TestFinished(XmlNode testResult)
+ private void TestStarted(XmlNode testResult)
{
var testName = testResult.Attributes["fullname"].Value;
- var outputNode = testResult.SelectSingleNode("output");
if (_displayLabels == "ALL")
WriteLabelLine(testName);
+ }
+
+ private void TestFinished(XmlNode testResult)
+ {
+ var testName = testResult.Attributes["fullname"].Value;
+ var outputNode = testResult.SelectSingleNode("output");
if (outputNode != null)
{
@@ -97,7 +106,7 @@ private void SuiteFinished(XmlNode testResult)
if (outputNode != null)
{
- if (_displayLabels == "ON" || _displayLabels == "ALL")
+ if (_displayLabels == "ON")
WriteLabelLine(suiteName);
WriteOutputLine(outputNode.InnerText);
diff --git a/src/NUnitEngine/nunit.engine.tests/HangingAppDomainFixture.cs b/src/NUnitEngine/nunit.engine.tests/HangingAppDomainFixture.cs
new file mode 100644
index 000000000..f278b2976
--- /dev/null
+++ b/src/NUnitEngine/nunit.engine.tests/HangingAppDomainFixture.cs
@@ -0,0 +1,44 @@
+// ***********************************************************************
+// Copyright (c) 2016 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Threading;
+using NUnit.Framework;
+
+namespace NUnit.Engine.Tests
+{
+ [Explicit]
+ public class HangingAppDomainFixture
+ {
+ [Test]
+ public void PassingTest()
+ {
+ Assert.Pass();
+ }
+
+ ~HangingAppDomainFixture()
+ {
+ Thread.Sleep(TimeSpan.FromDays(1));
+ }
+ }
+}
diff --git a/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj b/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
index 9cda4d402..b26b82456 100644
--- a/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
+++ b/src/NUnitEngine/nunit.engine.tests/nunit.engine.tests.csproj
@@ -70,6 +70,7 @@
+
diff --git a/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs b/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs
index 3a9bfb958..5395f81d6 100644
--- a/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs
+++ b/src/NUnitEngine/nunit.engine/Runners/ProcessRunner.cs
@@ -215,27 +215,58 @@ public override void StopRun(bool force)
protected override void Dispose(bool disposing)
{
- base.Dispose(disposing);
-
- try
+ // Disposal has to perform two actions, unloading the runner and
+ // stopping the agent. Both must be tried even if one fails so
+ // there can be up to two independent errors to be reported
+ // through an NUnitEngineException. We do that by combining messages.
+ if (!_disposed && disposing)
{
- if (disposing && _agent != null)
+ _disposed = true;
+
+ string unloadError = null;
+
+ try
{
- log.Debug("Stopping remote agent");
- _agent.Stop();
- _agent = null;
+ Unload();
}
- }
- catch (Exception e)
- {
- log.Error("Failed to stop the remote agent. {0}", e.Message);
- _agent = null;
+ catch(Exception ex)
+ {
+ // Save and log the unload error
+ unloadError = ex.Message;
+ log.Error(unloadError);
+ }
+
+ if (_agent != null)
+ {
+ try
+ {
+ log.Debug("Stopping remote agent");
+ _agent.Stop();
+ _agent = null;
+ }
+ catch (Exception e)
+ {
+ string stopError = string.Format("Failed to stop the remote agent. {0}", e.Message);
+ log.Error(stopError);
+ _agent = null;
+
+ // Stop error with no unload error, just rethrow
+ if (unloadError == null)
+ throw;
+
+ // Both kinds of errors, throw exception with combined message
+ throw new NUnitEngineException(unloadError + Environment.NewLine + stopError);
+ }
+ }
+
+ if (unloadError != null) // Add message line indicating we managed to stop agent anyway
+ throw (new NUnitEngineException(unloadError + "\nAgent Process was terminated successfully after error."));
}
}
- #endregion
+#endregion
- #region Helper Methods
+#region Helper Methods
private void CreateAgentAndRunner()
{
@@ -283,6 +314,6 @@ TestEngineResult CreateFailedResult(Exception e)
return new TestEngineResult(suite);
}
- #endregion
+#endregion
}
}
diff --git a/src/NUnitEngine/nunit.engine/Services/DomainManager.cs b/src/NUnitEngine/nunit.engine/Services/DomainManager.cs
index 3bfeb84a9..e72a212de 100644
--- a/src/NUnitEngine/nunit.engine/Services/DomainManager.cs
+++ b/src/NUnitEngine/nunit.engine/Services/DomainManager.cs
@@ -157,7 +157,7 @@ public void Unload()
if (!_unloadThread.Join(30000))
{
- string msg = "Unable to unload AppDomain, Unload thread timed out";
+ string msg = "Unable to unload AppDomain, Unload thread timed out.";
log.Error(msg);
Kill(_unloadThread);
diff --git a/src/NUnitEngine/nunit.engine/Services/DriverService.cs b/src/NUnitEngine/nunit.engine/Services/DriverService.cs
index cc75ce2d2..c45f1fd38 100644
--- a/src/NUnitEngine/nunit.engine/Services/DriverService.cs
+++ b/src/NUnitEngine/nunit.engine/Services/DriverService.cs
@@ -98,8 +98,6 @@ public override void StartService()
try
{
- _factories.Add(new NUnit3DriverFactory());
-
var extensionService = ServiceContext.GetService();
if (extensionService != null)
{
@@ -110,7 +108,9 @@ public override void StartService()
if (node != null)
_factories.Add(new NUnit2DriverFactory(node));
}
-
+
+ _factories.Add(new NUnit3DriverFactory());
+
Status = ServiceStatus.Started;
}
catch(Exception)
diff --git a/tools/packages.config b/tools/packages.config
index c5cdd6bb2..ff1c6fed5 100644
--- a/tools/packages.config
+++ b/tools/packages.config
@@ -1,4 +1,4 @@
-
+