Support using non-compatible Windows PowerShell modules in PowerShell Core (#10973)

This commit is contained in:
Andrew
2019-11-18 10:44:55 -08:00
committed by Dongbo Wang
parent 6dda2308fe
commit b218e6f6cc
21 changed files with 469 additions and 78 deletions
@@ -41,7 +41,7 @@ function New-EditionCompatibleModule
New-Item -Path $modulePath -ItemType Directory
New-Item -Path $psm1Path -Value "function Test-$ModuleName { `$true }"
New-Item -Path $psm1Path -Value "function Test-$ModuleName { `$true } function Test-${ModuleName}PSEdition { `$PSVersionTable.PSEdition }" -Force
if ($CompatiblePSEditions)
{
@@ -117,11 +117,11 @@ function New-TestNestedModule
if ($UseRootModule)
{
$newManifestCmd += "-RootModule $RootModuleFilename "
$newManifestCmd += "-FunctionsToExport @('Test-RootModule') "
$newManifestCmd += "-FunctionsToExport @('Test-RootModule','Test-RootModulePSEdition') "
}
else
{
$newManifestCmd += "-FunctionsToExport @('Test-ScriptModule') "
$newManifestCmd += "-FunctionsToExport @('Test-ScriptModule','Test-ScriptModulePSEdition') "
}
$newManifestCmd += "-CmdletsToExport @() -VariablesToExport @() -AliasesToExport @() "
@@ -248,6 +248,10 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
$allModules = ($successCases + $failCases).ModuleName
# make sure there are no ImplicitRemoting leftovers from previous tests
Get-Module | Where-Object {$_.PrivateData.ImplicitRemoting} | Remove-Module -Force
Get-PSSession -Name WinPSCompatSession -ErrorAction SilentlyContinue | Remove-PSSession
# Emulate the System32 module path for tests
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("TestWindowsPowerShellPSHomeLocation", $basePath)
}
@@ -276,12 +280,11 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
& "Test-$ModuleName" | Should -Be $Result
}
It "Fails to import incompatible modules from the module path with PSEdition <Editions>" -TestCases $failCases -Skip:(-not $IsWindows) {
It "Successfully imports incompatible modules from the module path with PSEdition <Editions> using WinCompat" -TestCases $failCases -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
{
Import-Module $ModuleName -Force -ErrorAction 'Stop'; & "Test-$ModuleName"
} | Should -Throw -ErrorId "Modules_PSEditionNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand"
Import-Module $ModuleName -Force -ErrorAction 'Stop'
& "Test-$ModuleName" | Should -Be $Result
}
It "Imports an incompatible module from the module path with -SkipEditionCheck with PSEdition <Editions>" -TestCases ($successCases + $failCases) -Skip:(-not $IsWindows) {
@@ -290,6 +293,13 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
Import-Module $ModuleName -SkipEditionCheck -Force
& "Test-$ModuleName" | Should -Be $Result
}
It "Imports any module using WinCompat from the module path with -UseWindowsPowerShell with PSEdition <Editions>" -TestCases ($successCases + $failCases) -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
Import-Module $ModuleName -UseWindowsPowerShell -Force
& "Test-${ModuleName}PSEdition" | Should -Be 'Desktop'
}
}
Context "Imports from absolute path" {
@@ -302,14 +312,13 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
& "Test-$ModuleName" | Should -Be $Result
}
It "Fails to import incompatible modules from an absolute path with PSEdition <Editions>" -TestCases $failCases -Skip:(-not $IsWindows) {
It "Successfully imports incompatible modules from an absolute path with PSEdition <Editions> using WinCompat" -TestCases $failCases -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
$path = Join-Path -Path $basePath -ChildPath $ModuleName
{
Import-Module $path -Force -ErrorAction 'Stop'; & "Test-$ModuleName"
} | Should -Throw -ErrorId "Modules_PSEditionNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand"
Import-Module $path -Force -ErrorAction 'Stop'
& "Test-$ModuleName" | Should -Be $Result
}
It "Imports an incompatible module from an absolute path with -SkipEditionCheck with PSEdition <Editions>" -TestCases ($successCases + $failCases) -Skip:(-not $IsWindows) {
@@ -320,6 +329,37 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
Import-Module $path -SkipEditionCheck -Force
& "Test-$ModuleName" | Should -Be $Result
}
It "Imports any module using WinCompat from an absolute path with -UseWindowsPowerShell with PSEdition <Editions>" -TestCases ($successCases + $failCases) -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
$path = Join-Path -Path $basePath -ChildPath $ModuleName
Import-Module $path -UseWindowsPowerShell -Force
& "Test-${ModuleName}PSEdition" | Should -Be 'Desktop'
}
}
Context "Imports using CommandDiscovery\ModuleAutoload" {
BeforeAll {
Add-ModulePath $basePath
}
AfterAll {
Restore-ModulePath
}
It "Successfully auto-imports compatible modules from the module path with PSEdition <Editions>" -TestCases $successCases -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
& "Test-$ModuleName" | Should -Be $Result
}
It "Successfully auto-imports incompatible modules from the module path with PSEdition <Editions> using WinCompat" -TestCases $failCases -Skip:(-not $IsWindows) {
param($Editions, $ModuleName, $Result)
& "Test-${ModuleName}PSEdition" | Should -Be 'Desktop'
}
}
}
@@ -673,6 +713,7 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
UseRootModule = @($true, $false)
UseAbsolutePath = @($true, $false)
MarkedEdition = @($null, "Desktop", "Core", @("Desktop","Core"))
UseWindowsPowerShell = @($true, $false)
}
# Combine all the test conditions into a list of test cases
@@ -693,12 +734,12 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
# Define nested script module
$scriptModuleName = "NestedScriptModule"
$scriptModuleFile = "$scriptModuleName.psm1"
$scriptModuleContent = 'function Test-ScriptModule { return $true }'
$scriptModuleContent = 'function Test-ScriptModule { return $true } function Test-ScriptModulePSEdition { $PSVersionTable.PSEdition }'
# Define root module definition
$rootModuleName = "RootModule"
$rootModuleFile = "$rootModuleName.psm1"
$rootModuleContent = 'function Test-RootModule { Test-ScriptModule }'
$rootModuleContent = 'function Test-RootModule { Test-ScriptModule } function Test-RootModulePSEdition { Test-ScriptModulePSEdition }'
# Module directory structure: $TestDrive/$compatibility/$guid/$moduleName/{module parts}
$compatibleDir = "Compatible"
@@ -710,6 +751,10 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
{
New-Item -Path $basePath -ItemType Directory
}
# make sure there are no ImplicitRemoting leftovers from previous tests
Get-Module | Where-Object {$_.PrivateData.ImplicitRemoting} | Remove-Module -Force
Get-PSSession -Name WinPSCompatSession -ErrorAction SilentlyContinue | Remove-PSSession
}
Context "Modules ON the System32 test path" {
@@ -737,8 +782,8 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
Restore-ModulePath
}
It "Import-Module when SkipEditionCheck: <SkipEditionCheck>, using root module: <UseRootModule>, using absolute path: <UseAbsolutePath>, CompatiblePSEditions: <MarkedEdition>" -TestCases $testCases -Skip:(-not $IsWindows) {
param([bool]$SkipEditionCheck, [bool]$UseRootModule, [bool]$UseAbsolutePath, [string[]]$MarkedEdition)
It "Import-Module when SkipEditionCheck: <SkipEditionCheck>, using root module: <UseRootModule>, using absolute path: <UseAbsolutePath>, CompatiblePSEditions: <MarkedEdition>, UseWindowsPowerShell: <UseWindowsPowerShell>" -TestCases $testCases -Skip:(-not $IsWindows) {
param([bool]$SkipEditionCheck, [bool]$UseRootModule, [bool]$UseAbsolutePath, [string[]]$MarkedEdition, [bool]$UseWindowsPowerShell)
New-TestNestedModule `
-ModuleBase $moduleBase `
@@ -754,16 +799,25 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
{
if ((-not $SkipEditionCheck) -and (-not ($MarkedEdition -contains "Core")))
{
{
Import-Module $moduleBase -ErrorAction Stop
} | Should -Throw -ErrorId "Modules_PSEditionNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand"
# this goes through WinCompat code
{ Import-Module $moduleBase -ErrorAction Stop } | Should Not Throw
Get-Module -Name $moduleName | Should Not BeNullOrEmpty
return
}
if ($SkipEditionCheck)
if ($SkipEditionCheck -and $UseWindowsPowerShell)
{
{ Import-Module $moduleBase -SkipEditionCheck -UseWindowsPowerShell } | Should -Throw -ErrorId "AmbiguousParameterSet"
return
}
elseif ($SkipEditionCheck)
{
Import-Module $moduleBase -SkipEditionCheck
}
elseif ($UseWindowsPowerShell)
{
Import-Module $moduleBase -UseWindowsPowerShell
}
else
{
Import-Module $moduleBase
@@ -773,26 +827,46 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
{
Test-RootModule | Should -BeTrue
{ Test-ScriptModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-RootModulePSEdition | Should -Be 'Desktop'
{ Test-ScriptModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
return
}
Test-ScriptModule | Should -BeTrue
{ Test-RootModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-ScriptModulePSEdition | Should -Be 'Desktop'
{ Test-RootModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
return
}
if ((-not $SkipEditionCheck) -and (-not ($MarkedEdition -contains "Core")))
{
{
Import-Module $moduleName -ErrorAction Stop
} | Should -Throw -ErrorId "Modules_PSEditionNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand"
# this goes through WinCompat code
{ Import-Module $moduleName -ErrorAction Stop } | Should Not Throw
Get-Module -Name $moduleName | Should Not BeNullOrEmpty
return
}
if ($SkipEditionCheck)
if ($SkipEditionCheck -and $UseWindowsPowerShell)
{
{ Import-Module $moduleName -SkipEditionCheck -UseWindowsPowerShell } | Should -Throw -ErrorId "AmbiguousParameterSet"
return
}
elseif ($SkipEditionCheck)
{
Import-Module $moduleName -SkipEditionCheck
}
elseif ($UseWindowsPowerShell)
{
Import-Module $moduleName -UseWindowsPowerShell
}
else
{
Import-Module $moduleName
@@ -802,11 +876,21 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
{
Test-RootModule | Should -BeTrue
{ Test-ScriptModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-RootModulePSEdition | Should -Be 'Desktop'
{ Test-ScriptModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
return
}
Test-ScriptModule | Should -BeTrue
{ Test-RootModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-ScriptModulePSEdition | Should -Be 'Desktop'
{ Test-RootModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
}
}
@@ -827,8 +911,13 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
Restore-ModulePath
}
It "Import-Module when SkipEditionCheck: <SkipEditionCheck>, using root module: <UseRootModule>, using absolute path: <UseAbsolutePath>, CompatiblePSEditions: <MarkedEdition>" -TestCases $testCases {
param([bool]$SkipEditionCheck, [bool]$UseRootModule, [bool]$UseAbsolutePath, [string[]]$MarkedEdition)
It "Import-Module when SkipEditionCheck: <SkipEditionCheck>, using root module: <UseRootModule>, using absolute path: <UseAbsolutePath>, CompatiblePSEditions: <MarkedEdition>, UseWindowsPowerShell: <UseWindowsPowerShell>" -TestCases $testCases {
param([bool]$SkipEditionCheck, [bool]$UseRootModule, [bool]$UseAbsolutePath, [string[]]$MarkedEdition, [bool]$UseWindowsPowerShell)
if ($UseWindowsPowerShell -and (-not $IsWindows))
{
Set-ItResult -Skipped -Because 'UseWindowsPowerShell parameter is supported only on Windows'
}
New-TestNestedModule `
-ModuleBase $moduleBase `
@@ -842,19 +931,37 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
if ($UseAbsolutePath)
{
if ($SkipEditionCheck)
if ($SkipEditionCheck -and $UseWindowsPowerShell)
{
{ Import-Module $moduleBase -SkipEditionCheck -UseWindowsPowerShell } | Should -Throw -ErrorId "AmbiguousParameterSet"
return
}
elseif ($SkipEditionCheck)
{
Import-Module $moduleBase -SkipEditionCheck
}
elseif ($UseWindowsPowerShell)
{
Import-Module $moduleBase -UseWindowsPowerShell
}
else
{
Import-Module $moduleBase
}
}
elseif ($SkipEditionCheck -and $UseWindowsPowerShell)
{
{ Import-Module $moduleName -SkipEditionCheck -UseWindowsPowerShell } | Should -Throw -ErrorId "AmbiguousParameterSet"
return
}
elseif ($SkipEditionCheck)
{
Import-Module $moduleName -SkipEditionCheck
}
elseif ($UseWindowsPowerShell)
{
Import-Module $moduleName -UseWindowsPowerShell
}
else
{
Import-Module $moduleName
@@ -864,11 +971,21 @@ Describe "Import-Module nested module behaviour with Edition checking" -Tag "Fea
{
Test-RootModule | Should -BeTrue
{ Test-ScriptModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-RootModulePSEdition | Should -Be 'Desktop'
{ Test-ScriptModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
return
}
Test-ScriptModule | Should -BeTrue
{ Test-RootModule } | Should -Throw -ErrorId "CommandNotFoundException"
if ($UseWindowsPowerShell)
{
Test-ScriptModulePSEdition | Should -Be 'Desktop'
{ Test-RootModulePSEdition } | Should -Throw -ErrorId "CommandNotFoundException"
}
}
}
}