From 79a9294379d9bca3a12cd4b22ec69040deb21748 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 17:12:54 -0700 Subject: [PATCH 1/6] Enable exit code from xUnit runner --- xunit.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xunit.sh b/xunit.sh index 6b0a7c7d5..aec4f65dd 100755 --- a/xunit.sh +++ b/xunit.sh @@ -25,4 +25,7 @@ dotnet build cp -r ../../src/Microsoft.PowerShell.Linux.Host/{Modules,*ps1xml} bin/Debug/netstandardapp1.5/ubuntu.14.04-x64 ## Test dotnet test +result=$? popd + +exit $result From 41260dd9c8b8c2d51676cddcdb39eb3932ac0346 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 17:13:16 -0700 Subject: [PATCH 2/6] Run xUnit tests on Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b5c143a43..12c6eae38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ before_install: script: - powershell -c "Import-Module ./PowerShellGitHubDev.psm1; Start-PSBuild" - ./pester.sh + - ./xunit.sh notifications: slack: secure: sKYd4n61+ZFzGZuWGUl8V1kN0NM16wRVOFVlNhlFCwnkrEsKROb++EvXf5uwnKuzxkhEjvPWO+UFgeshQDoR93y4s5YLfhC5JupK4nUzjPzWs208KTrh8u/x9MY8X6Ojxi85EEAiku5GzMoMlkucSStZUYwbIfnelzqdw8uoRwmm2MW4XCPwsuEuDUVghyiva0Mdx1G6MopCrK8T96WywJXT3chhfZQgVt+sQCBt9g+2kjDaObKrzG0P07IVK43ZpDgnu6AoxlyBzIx9mJH2Oa/tki3/kTO72Wcp3ps3qvmiStADamzVKR9p1VlWCLWAd6VOehxuByCGEyujpzk135Wud2DZYO+8LD6inZVhFe3Wt5pCU9BDXZppiATfMCqgXEH7nK54pEn79yHcjthRJ2+Z9ot7As2fu3RSBmTAi8nRP0fxRyX/jctR3S6P0qt0y1ynx9nzBfhmhPQW0PMVazWS/nruQIvK/3iiYXjZxM5bBwIvabmwV00EYeTdbL6ufXWNgQcG1ZWkDsi2I3vst/ytUbHwaFYg83bXWpxg9DCzJeWLVUvE5/3NfBxRAuCTot/fgTEA9IYScvrlL7Q/bT0cOt0vEM98MPf1UO+WP85uxhsRgHtwDEo+jMaL6ZFkPhlV6mmmED4NdY2//a571cLNXdnuMAze5O3TWGBG53g= From 6ec3dc308ec17e20ef7ee2b6749c9f55fb92034a Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 17:15:19 -0700 Subject: [PATCH 3/6] Build Linux configuration for xUnit tests --- xunit.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xunit.sh b/xunit.sh index aec4f65dd..a8038da49 100755 --- a/xunit.sh +++ b/xunit.sh @@ -20,11 +20,11 @@ popd # Run xUnit tests pushd test/csharp ## Build -dotnet build +dotnet build -c Linux ## Work-around dotnet/cli#753 -cp -r ../../src/Microsoft.PowerShell.Linux.Host/{Modules,*ps1xml} bin/Debug/netstandardapp1.5/ubuntu.14.04-x64 +cp -r ../../src/Microsoft.PowerShell.Linux.Host/{Modules,*ps1xml} bin/Linux/netstandardapp1.5/ubuntu.14.04-x64 ## Test -dotnet test +dotnet test -c Linux result=$? popd From b820817c84b8f4f236a938144d16359ec1a93e29 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 17:36:06 -0700 Subject: [PATCH 4/6] Fix AssemblyLoadContext fixture Resolves #676. --- test/csharp/fixture_AssemblyLoadContext.cs | 26 ++++++++++++++++++++++ test/csharp/test_Runspace.cs | 7 +----- 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 test/csharp/fixture_AssemblyLoadContext.cs diff --git a/test/csharp/fixture_AssemblyLoadContext.cs b/test/csharp/fixture_AssemblyLoadContext.cs new file mode 100644 index 000000000..71362729e --- /dev/null +++ b/test/csharp/fixture_AssemblyLoadContext.cs @@ -0,0 +1,26 @@ +using Xunit; +using System; +using System.Management.Automation; +using Microsoft.PowerShell.Linux.Host; + +// 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_Runspace.cs b/test/csharp/test_Runspace.cs index 96dbe6355..0a7b00eb9 100644 --- a/test/csharp/test_Runspace.cs +++ b/test/csharp/test_Runspace.cs @@ -9,17 +9,12 @@ 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-process | select-object -first {count}"); - // Initialize the Core PowerShell AssemblyLoadContext - public RunspaceTests() - { - PowerShellAssemblyLoadContextInitializer.SetPowerShellAssemblyLoadContext(AppContext.BaseDirectory); - } - [Fact] public void TestRunspaceWithPipeline() { From 6d93a1766bbb60d2adc19e43bc94d1f3311eb0a4 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 18:15:39 -0700 Subject: [PATCH 5/6] Add all classes to AssemblyLoadContext collection To ensure that the initializer is called before any other code. This is as close to a global init hook as I can find. --- test/csharp/test_Binders.cs | 1 + test/csharp/test_CorePsExtensions.cs | 1 + test/csharp/test_CorePsPlatform.cs | 1 + test/csharp/test_ExtensionMethods.cs | 1 + test/csharp/test_FileSystemProvider.cs | 1 + test/csharp/test_MshSnapinInfo.cs | 1 + test/csharp/test_PSVersionInfo.cs | 1 + test/csharp/test_SecuritySupport.cs | 1 + test/csharp/test_Utils.cs | 1 + 9 files changed, 9 insertions(+) diff --git a/test/csharp/test_Binders.cs b/test/csharp/test_Binders.cs index 6f5a8f7d1..91dc76d25 100644 --- a/test/csharp/test_Binders.cs +++ b/test/csharp/test_Binders.cs @@ -4,6 +4,7 @@ using System.Management.Automation.Language; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class PSEnumerableBinderTests { [Fact] diff --git a/test/csharp/test_CorePsExtensions.cs b/test/csharp/test_CorePsExtensions.cs index 2a736d7f9..97d2ee50f 100644 --- a/test/csharp/test_CorePsExtensions.cs +++ b/test/csharp/test_CorePsExtensions.cs @@ -4,6 +4,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class CorePsExtensionsTests { [Fact] diff --git a/test/csharp/test_CorePsPlatform.cs b/test/csharp/test_CorePsPlatform.cs index 7196862eb..e36f5aa4f 100644 --- a/test/csharp/test_CorePsPlatform.cs +++ b/test/csharp/test_CorePsPlatform.cs @@ -6,6 +6,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class PlatformTests { [Fact] diff --git a/test/csharp/test_ExtensionMethods.cs b/test/csharp/test_ExtensionMethods.cs index e22de8be5..134f94b28 100644 --- a/test/csharp/test_ExtensionMethods.cs +++ b/test/csharp/test_ExtensionMethods.cs @@ -4,6 +4,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class PSTypeExtensionsTests { [Fact] diff --git a/test/csharp/test_FileSystemProvider.cs b/test/csharp/test_FileSystemProvider.cs index 2bdcacbfc..7c33910d8 100644 --- a/test/csharp/test_FileSystemProvider.cs +++ b/test/csharp/test_FileSystemProvider.cs @@ -5,6 +5,7 @@ using Microsoft.PowerShell.Commands; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class FileSystemProviderTests { [Fact] diff --git a/test/csharp/test_MshSnapinInfo.cs b/test/csharp/test_MshSnapinInfo.cs index a283e7995..8a14afb89 100644 --- a/test/csharp/test_MshSnapinInfo.cs +++ b/test/csharp/test_MshSnapinInfo.cs @@ -5,6 +5,7 @@ using System.Management.Automation; namespace PSTests { // Not static because a test requires non-const variables + [Collection("AssemblyLoadContext")] public class MshSnapinInfoTests { // Test that it does not throw an exception diff --git a/test/csharp/test_PSVersionInfo.cs b/test/csharp/test_PSVersionInfo.cs index ef980475e..5bd7acb82 100644 --- a/test/csharp/test_PSVersionInfo.cs +++ b/test/csharp/test_PSVersionInfo.cs @@ -4,6 +4,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class PSVersionInfoTests { [Fact] diff --git a/test/csharp/test_SecuritySupport.cs b/test/csharp/test_SecuritySupport.cs index 962dc6670..33c336308 100644 --- a/test/csharp/test_SecuritySupport.cs +++ b/test/csharp/test_SecuritySupport.cs @@ -4,6 +4,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class SecuritySupportTests { [Fact] diff --git a/test/csharp/test_Utils.cs b/test/csharp/test_Utils.cs index eb5167780..65ded34f6 100644 --- a/test/csharp/test_Utils.cs +++ b/test/csharp/test_Utils.cs @@ -4,6 +4,7 @@ using System.Management.Automation; namespace PSTests { + [Collection("AssemblyLoadContext")] public static class UtilsTests { [Fact] From 60ef5cd58df985c754553d48aab0c4baa75e4ba6 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 17 Mar 2016 18:20:05 -0700 Subject: [PATCH 6/6] Add xUnit tests readme --- test/csharp/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/csharp/README.md diff --git a/test/csharp/README.md b/test/csharp/README.md new file mode 100644 index 000000000..cb7983fbb --- /dev/null +++ b/test/csharp/README.md @@ -0,0 +1,13 @@ +# xUnit Tests + +This tests are completely Linux specific. + +Every test class *must* belong to +`[Collection("AssemblyLoadContext")]`. This ensures that PowerShell's +AssemblyLoadContext is initialized before any other code is executed. +When this is not the case, late initialization fails with +`System.InvalidOperationException : Binding model is already locked +for the AppDomain and cannot be reset.` + +Having every class in the same collection is as close to an xUnit +global init hook as can be done.