diff --git a/build.psm1 b/build.psm1
index d770d53e530..9c97a4e65ef 100644
--- a/build.psm1
+++ b/build.psm1
@@ -1188,6 +1188,53 @@ function Show-PSPesterError
}
+function Test-XUnitTestResults
+{
+ param(
+ [Parameter(Mandatory)]
+ [ValidateNotNullOrEmpty()]
+ [string] $TestResultsFile
+ )
+
+ if(-not (Test-Path $TestResultsFile))
+ {
+ throw "File not found $TestResultsFile"
+ }
+
+ try
+ {
+ $results = [xml] (Get-Content $TestResultsFile)
+ }
+ catch
+ {
+ throw "Cannot convert $TestResultsFile to xml : $($_.message)"
+ }
+
+ $failedTests = $results.assemblies.assembly.collection | Where-Object failed -gt 0
+
+ if(-not $failedTests)
+ {
+ return $true
+ }
+
+ foreach($failure in $failedTests)
+ {
+ $description = $failure.test.type
+ $name = $failure.test.method
+ $message = $failure.test.failure.message.'#cdata-section'
+ $stackTrace = $failure.test.failure.'stack-trace'.'#cdata-section'
+
+ logerror ("Description: " + $description)
+ logerror ("Name: " + $name)
+ logerror "message:"
+ logerror $message
+ logerror "stack-trace:"
+ logerror $stackTrace
+ }
+
+ throw "$($failedTests.failed) tests failed"
+}
+
#
# Read the test result file and
# Throw if a test failed
@@ -1251,46 +1298,67 @@ function Test-PSPesterResults
function Start-PSxUnit {
- [CmdletBinding()]param()
-
- log "xUnit tests are currently disabled pending fixes due to API and AssemblyLoadContext changes - @andschwa"
- return
-
- if ($Environment.IsWindows) {
- throw "xUnit tests are only currently supported on Linux / OS X"
- }
-
- if ($Environment.IsMacOS) {
- log "Not yet supported on OS X, pretending they passed..."
- return
- }
+ [CmdletBinding()]param(
+ [string] $TestResultsFile = "XUnitResults.xml"
+ )
# Add .NET CLI tools to PATH
Find-Dotnet
- $Arguments = "--configuration", "Linux", "-parallel", "none"
- if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) {
- $Arguments += "-verbose"
- }
-
$Content = Split-Path -Parent (Get-PSOutput)
if (-not (Test-Path $Content)) {
throw "PowerShell must be built before running tests!"
}
+ if(Test-Path $TestResultsFile)
+ {
+ Remove-Item $TestResultsFile -Force -ErrorAction SilentlyContinue
+ }
+
try {
Push-Location $PSScriptRoot/test/csharp
+
# Path manipulation to obtain test project output directory
- $Output = Join-Path $pwd ((Split-Path -Parent (Get-PSOutput)) -replace (New-PSOptions).Top)
- Write-Verbose "Output is $Output"
+ dotnet restore
- Copy-Item -ErrorAction SilentlyContinue -Recurse -Path $Content/* -Include Modules,libpsl-native* -Destination $Output
- Start-NativeExecution { dotnet test $Arguments }
+ # --fx-version workaround required due to https://github.com/dotnet/cli/issues/7901#issuecomment-343323674
+ if($Environment.IsWindows)
+ {
+ dotnet xunit --fx-version 2.0.0 -xml $TestResultsFile
+ }
+ else
+ {
+ if($Environment.IsMacOS)
+ {
+ $nativeLib = "$Content/libpsl-native.dylib"
+ }
+ else
+ {
+ $nativeLib = "$Content/libpsl-native.so"
+ }
+
+ $requiredDependencies = @(
+ $nativeLib,
+ "$Content/Microsoft.Management.Infrastructure.dll",
+ "$Content/System.Text.Encoding.CodePages.dll"
+ )
+
+ if((Test-Path $requiredDependencies) -notcontains $false)
+ {
+ $options = New-PSOptions
+ $Destination = "bin/$($options.configuration)/$($options.framework)"
+ New-Item $Destination -ItemType Directory -Force > $null
+ Copy-Item -Path $requiredDependencies -Destination $Destination -Force
+ }
+ else
+ {
+ throw "Dependencies $requiredDependencies not met."
+ }
- if ($LASTEXITCODE -ne 0) {
- throw "$LASTEXITCODE xUnit tests failed"
+ dotnet xunit --fx-version 2.0.0 -configuration $Options.configuration -xml $TestResultsFile
}
- } finally {
+ }
+ finally {
Pop-Location
}
}
diff --git a/test/csharp/csharp.tests.csproj b/test/csharp/csharp.tests.csproj
index 03eb9cf93af..6ecf16d2a44 100644
--- a/test/csharp/csharp.tests.csproj
+++ b/test/csharp/csharp.tests.csproj
@@ -1,21 +1,30 @@
-
+
- PowerShell On Linux xUnit Tests
+ PowerShell xUnit Tests
powershell-tests
win7-x86;win7-x64;osx.10.12-x64;linux-x64
+
+ true
+ ../../src/signing/visualstudiopublic.snk
+ true
+
+
-
+
+
+
-
-
-
+
+
+
+
diff --git a/test/csharp/fixture_AssemblyLoadContext.cs b/test/csharp/fixture_AssemblyLoadContext.cs
deleted file mode 100644
index b24f41fc269..00000000000
--- a/test/csharp/fixture_AssemblyLoadContext.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Xunit;
-using System;
-using System.Management.Automation;
-
-// This collection fixture initializes Core PowerShell's AssemblyLoadContext once and only
-// once. Attempting to initialize in a class level fixture will cause multiple
-// initializations, resulting in test failure due to "Binding model is already locked for
-// the AppDomain and cannot be reset".
-namespace PSTests
-{
- public class AssemblyLoadContextFixture
- {
- public AssemblyLoadContextFixture()
- {
- // Initialize the Core PowerShell AssemblyLoadContext
- PowerShellAssemblyLoadContextInitializer.SetPowerShellAssemblyLoadContext(AppContext.BaseDirectory);
- }
- }
-
- [CollectionDefinition("AssemblyLoadContext")]
- public class AssemblyLoadContextCollection : ICollectionFixture
- {
- // nothing to do but satisfy the interface
- }
-}
diff --git a/test/csharp/test_Binders.cs b/test/csharp/test_Binders.cs
index 91dc76d25b5..e73d6b44ca4 100644
--- a/test/csharp/test_Binders.cs
+++ b/test/csharp/test_Binders.cs
@@ -4,14 +4,13 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class PSEnumerableBinderTests
{
[Fact]
- public static void TestIsComObject()
+ public static void TestIsStaticTypePossiblyEnumerable()
{
- // It just needs an arbitrary object
- Assert.False(PSEnumerableBinder.IsComObject(42));
+ // It just needs an arbitrary type
+ Assert.False(PSEnumerableBinder.IsStaticTypePossiblyEnumerable(42.GetType()));
}
}
}
diff --git a/test/csharp/test_CorePsPlatform.cs b/test/csharp/test_CorePsPlatform.cs
index 33579d9ed41..11a744b4046 100644
--- a/test/csharp/test_CorePsPlatform.cs
+++ b/test/csharp/test_CorePsPlatform.cs
@@ -6,7 +6,6 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class PlatformTests
{
[Fact]
@@ -15,6 +14,7 @@ public static void TestIsCoreCLR()
Assert.True(Platform.IsCoreCLR);
}
+#if Unix
[Fact]
public static void TestGetUserName()
{
@@ -38,7 +38,7 @@ public static void TestGetUserName()
}
}
- [Fact(Skip="Bad arguments for macOS")]
+ [Fact]
public static void TestGetMachineName()
{
var startInfo = new ProcessStartInfo
@@ -61,7 +61,7 @@ public static void TestGetMachineName()
}
}
- [Fact(Skip="Bad arguments for macOS")]
+ [Fact]
public static void TestGetFQDN()
{
var startInfo = new ProcessStartInfo
@@ -84,7 +84,7 @@ public static void TestGetFQDN()
}
}
- [Fact(Skip="Bad arguments for macOS")]
+ [Fact]
public static void TestGetDomainName()
{
var startInfo = new ProcessStartInfo
@@ -255,5 +255,6 @@ public static void TestFileIsSymLink()
File.Delete(path);
File.Delete(link);
}
+#endif
}
}
diff --git a/test/csharp/test_ExtensionMethods.cs b/test/csharp/test_ExtensionMethods.cs
index 134f94b2811..0b2273fb3d2 100644
--- a/test/csharp/test_ExtensionMethods.cs
+++ b/test/csharp/test_ExtensionMethods.cs
@@ -4,14 +4,12 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class PSTypeExtensionsTests
{
[Fact]
- public static void TestIsComObject()
+ public static void TestIsNumeric()
{
- // It just needs an arbitrary type
- Assert.False(PSTypeExtensions.IsComObject(42.GetType()));
+ Assert.True(PSTypeExtensions.IsNumeric(42.GetType()));
}
}
}
diff --git a/test/csharp/test_FileSystemProvider.cs b/test/csharp/test_FileSystemProvider.cs
index 5ad95a6daf5..76d52137478 100644
--- a/test/csharp/test_FileSystemProvider.cs
+++ b/test/csharp/test_FileSystemProvider.cs
@@ -13,10 +13,10 @@
using System.Management.Automation.Runspaces;
using Microsoft.PowerShell;
using Microsoft.PowerShell.Commands;
+using System.Reflection;
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public class FileSystemProviderTests: IDisposable
{
private string testPath;
@@ -37,9 +37,8 @@ private ExecutionContext GetExecutionContext()
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
PSHost hostInterface = new DefaultHost(currentCulture,currentCulture);
- RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
InitialSessionState iss = InitialSessionState.CreateDefault2();
- AutomationEngine engine = new AutomationEngine(hostInterface, runspaceConfiguration, iss);
+ AutomationEngine engine = new AutomationEngine(hostInterface, iss);
ExecutionContext executionContext = new ExecutionContext(engine, hostInterface, iss);
return executionContext;
}
@@ -58,7 +57,14 @@ private ProviderInfo GetProvider()
[Fact]
public void TestCreateJunctionFails()
{
- Assert.False(InternalSymbolicLinkLinkCodeMethods.CreateJunction("",""));
+ if(!Platform.IsWindows)
+ {
+ Assert.False(InternalSymbolicLinkLinkCodeMethods.CreateJunction("",""));
+ }
+ else
+ {
+ Assert.Throws(delegate { InternalSymbolicLinkLinkCodeMethods.CreateJunction("",""); });
+ }
}
[Fact]
@@ -74,12 +80,26 @@ public void TestGetHelpMaml()
public void TestMode()
{
Assert.Equal(FileSystemProvider.Mode(null),String.Empty);
- FileSystemInfo directoryObject = new DirectoryInfo(@"/");
- FileSystemInfo fileObject = new FileInfo(@"/etc/hosts");
- FileSystemInfo executableObject = new FileInfo(@"/bin/echo");
- Assert.Equal(FileSystemProvider.Mode(PSObject.AsPSObject(directoryObject)).Replace("r","-"),"d-----");
- Assert.Equal(FileSystemProvider.Mode(PSObject.AsPSObject(fileObject)).Replace("r","-"),"------");
- Assert.Equal(FileSystemProvider.Mode(PSObject.AsPSObject(executableObject)).Replace("r","-"),"------");
+ FileSystemInfo directoryObject = null;
+ FileSystemInfo fileObject = null;
+ FileSystemInfo executableObject = null;
+
+ if(!Platform.IsWindows)
+ {
+ directoryObject = new DirectoryInfo(@"/");
+ fileObject = new FileInfo(@"/etc/hosts");
+ executableObject = new FileInfo(@"/bin/echo");
+ }
+ else
+ {
+ directoryObject = new DirectoryInfo(System.Environment.CurrentDirectory);
+ fileObject = new FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location);
+ executableObject = new FileInfo(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
+ }
+
+ Assert.Equal("d-----", FileSystemProvider.Mode(PSObject.AsPSObject(directoryObject)).Replace("r","-"));
+ Assert.Equal("------", FileSystemProvider.Mode(PSObject.AsPSObject(fileObject)).Replace("r","-").Replace("a","-"));
+ Assert.Equal("------", FileSystemProvider.Mode(PSObject.AsPSObject(executableObject)).Replace("r","-").Replace("a","-"));
}
[Fact]
@@ -99,7 +119,7 @@ public void TestGetProperty()
{
if(property.Name == "IsReadOnly")
{
- Assert.Equal(property.Value,false);
+ Assert.False((bool)property.Value);
}
}
}
@@ -118,7 +138,7 @@ public void TestSetProperty()
{
if(property.Name == "Name")
{
- Assert.Equal(property.Value,"test");
+ Assert.Equal("test", property.Value);
}
}
}
diff --git a/test/csharp/test_MshSnapinInfo.cs b/test/csharp/test_MshSnapinInfo.cs
index ac755ec5afa..454a4ec0a60 100644
--- a/test/csharp/test_MshSnapinInfo.cs
+++ b/test/csharp/test_MshSnapinInfo.cs
@@ -5,22 +5,23 @@
namespace PSTests
{
// Not static because a test requires non-const variables
- [Collection("AssemblyLoadContext")]
public class MshSnapinInfoTests
{
// Test that it does not throw an exception
- [Fact]
+ [SkippableFact]
public void TestReadRegistryInfo()
{
+ Skip.IfNot(Platform.IsWindows);
Version someVersion = null;
string someString = null;
PSSnapInReader.ReadRegistryInfo(out someVersion, out someString, out someString, out someString, out someString, out someVersion);
}
// PublicKeyToken is null on Linux
- [Fact]
+ [SkippableFact]
public void TestReadCoreEngineSnapIn()
{
+ Skip.IfNot(Platform.IsWindows);
PSSnapInInfo pSSnapInInfo = PSSnapInReader.ReadCoreEngineSnapIn();
Assert.Contains("PublicKeyToken=31bf3856ad364e35", pSSnapInInfo.AssemblyName);
}
diff --git a/test/csharp/test_PSVersionInfo.cs b/test/csharp/test_PSVersionInfo.cs
index 5bd7acb82e8..ef980475ebf 100644
--- a/test/csharp/test_PSVersionInfo.cs
+++ b/test/csharp/test_PSVersionInfo.cs
@@ -4,7 +4,6 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class PSVersionInfoTests
{
[Fact]
diff --git a/test/csharp/test_Runspace.cs b/test/csharp/test_Runspace.cs
index 9b42341962a..ee7877523ac 100644
--- a/test/csharp/test_Runspace.cs
+++ b/test/csharp/test_Runspace.cs
@@ -8,11 +8,10 @@ namespace PSTests
// NOTE: do not call AddCommand("out-host") after invoking or MergeMyResults,
// otherwise Invoke will not return any objects
- [Collection("AssemblyLoadContext")]
public class RunspaceTests
{
- private static int count = 3;
- private static string script = String.Format($"get-command | select-object -first {count}");
+ private static int count = 1;
+ private static string script = String.Format($"get-command get-command");
[Fact]
public void TestRunspaceWithPipeline()
@@ -63,7 +62,7 @@ public void TestRunspaceWithPowerShell()
}
- [Fact(Skip="Fails in Travis CI, need investigation")]
+ [Fact]
public void TestRunspaceWithPowerShellAndInitialSessionState()
{
InitialSessionState iss = InitialSessionState.CreateDefault2();
@@ -76,11 +75,14 @@ public void TestRunspaceWithPowerShellAndInitialSessionState()
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.Runspace = runspace;
-
+ powerShell.AddScript("Import-Module Microsoft.PowerShell.Utility -Force");
powerShell.AddScript(script);
int objCount = 0;
- foreach (var result in powerShell.Invoke())
+
+ var results = powerShell.Invoke();
+
+ foreach (var result in results)
{
// this is how an object would be captured here and looked at,
// each result is a PSObject with the data from the pipeline
diff --git a/test/csharp/test_SecuritySupport.cs b/test/csharp/test_SecuritySupport.cs
index 33c336308cc..aef3ac5ee8a 100644
--- a/test/csharp/test_SecuritySupport.cs
+++ b/test/csharp/test_SecuritySupport.cs
@@ -4,21 +4,12 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class SecuritySupportTests
{
[Fact]
public static void TestScanContent()
{
- Assert.Equal(AmsiUtils.ScanContent("", ""), AmsiUtils.AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED);
- }
-
- [Fact]
- public static void TestCurrentDomain_ProcessExit()
- {
- Assert.Throws(delegate {
- AmsiUtils.CurrentDomain_ProcessExit(null, EventArgs.Empty);
- });
+ Assert.Equal(AmsiUtils.AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED, AmsiUtils.ScanContent("", ""));
}
[Fact]
diff --git a/test/csharp/test_SessionState.cs b/test/csharp/test_SessionState.cs
index 7558c1b6789..990242f69f1 100644
--- a/test/csharp/test_SessionState.cs
+++ b/test/csharp/test_SessionState.cs
@@ -12,17 +12,16 @@
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public class SessionStateTests
{
- [Fact]
+ [SkippableFact]
public void TestDrives()
{
+ Skip.IfNot(Platform.IsWindows);
CultureInfo currentCulture = CultureInfo.CurrentCulture;
PSHost hostInterface = new DefaultHost(currentCulture,currentCulture);
- RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
InitialSessionState iss = InitialSessionState.CreateDefault2();
- AutomationEngine engine = new AutomationEngine(hostInterface, runspaceConfiguration, iss);
+ AutomationEngine engine = new AutomationEngine(hostInterface, iss);
ExecutionContext executionContext = new ExecutionContext(engine, hostInterface, iss);
SessionStateInternal sessionState = new SessionStateInternal(executionContext);
Collection drives = sessionState.Drives(null);
diff --git a/test/csharp/test_Utils.cs b/test/csharp/test_Utils.cs
index 65ded34f637..be1c5cfa492 100644
--- a/test/csharp/test_Utils.cs
+++ b/test/csharp/test_Utils.cs
@@ -1,15 +1,16 @@
using Xunit;
using System;
using System.Management.Automation;
+using System.Reflection;
namespace PSTests
{
- [Collection("AssemblyLoadContext")]
public static class UtilsTests
{
- [Fact]
+ [SkippableFact]
public static void TestIsWinPEHost()
{
+ Skip.IfNot(Platform.IsWindows);
Assert.False(Utils.IsWinPEHost());
}
}
diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1
index a1401a1bb7e..dd7b069e2cc 100644
--- a/tools/appveyor.psm1
+++ b/tools/appveyor.psm1
@@ -325,6 +325,7 @@ function Invoke-AppVeyorTest
Write-Host -Foreground Green 'Run CoreCLR tests'
$testResultsNonAdminFile = "$pwd\TestsResultsNonAdmin.xml"
$testResultsAdminFile = "$pwd\TestsResultsAdmin.xml"
+ $testResultsXUnitFile = "$pwd\TestResultsXUnit.xml"
if(!(Test-Path "$env:CoreOutput\pwsh.exe"))
{
throw "CoreCLR pwsh.exe was not built"
@@ -358,6 +359,10 @@ function Invoke-AppVeyorTest
Write-Host -Foreground Green 'Upload CoreCLR Admin test results'
Update-AppVeyorTestResults -resultsFile $testResultsAdminFile
+ Start-PSxUnit -TestResultsFile $testResultsXUnitFile
+ Write-Host -ForegroundColor Green 'Uploading PSxUnit test results'
+ Update-AppVeyorTestResults -resultsFile $testResultsXUnitFile
+
#
# Fail the build, if tests failed
@(
@@ -367,6 +372,8 @@ function Invoke-AppVeyorTest
Test-PSPesterResults -TestResultsFile $_
}
+ $testPassResult = Test-XUnitTestResults -TestResultsFile $testResultsXUnitFile
+
Set-BuildVariable -Name TestPassed -Value True
}
diff --git a/tools/travis.ps1 b/tools/travis.ps1
index 670b012693d..5e4ecf0a437 100644
--- a/tools/travis.ps1
+++ b/tools/travis.ps1
@@ -240,7 +240,10 @@ elseif($Stage -eq 'Build')
}
try {
- Start-PSxUnit
+ $testResultsXUnitFile = "$pwd/TestResultsXUnit.xml"
+ Start-PSxUnit -TestResultsFile $testResultsXUnitFile
+ # If there are failures, Test-XUnitTestResults throws
+ $testPassResult = Test-XUnitTestResults -TestResultsFile $testResultsXUnitFile
}
catch {
$result = "FAIL"