2020-03-24 19:08:37 +01:00
# Copyright (c) Microsoft Corporation.
2018-02-13 18:23:53 +01:00
# Licensed under the MIT License.
2016-08-12 02:59:04 +02:00
Describe " SxS Module Path Basic Tests " -tags " CI " {
2017-01-16 22:31:14 +01:00
2016-08-12 02:59:04 +02:00
BeforeAll {
2017-01-16 22:31:14 +01:00
if ( $IsWindows )
2016-08-12 02:59:04 +02:00
{
2017-10-18 02:25:11 +02:00
$powershell = " $PSHOME \pwsh.exe "
2016-08-12 02:59:04 +02:00
$ProductName = " WindowsPowerShell "
if ( $IsCoreCLR -and ( $PSHOME -notlike " *Windows\System32\WindowsPowerShell\v1.0 " ) )
{
$ProductName = " PowerShell "
}
$expectedUserPath = Join-Path -Path $HOME -ChildPath " Documents\ $ProductName \Modules "
$expectedSharedPath = Join-Path -Path $env:ProgramFiles -ChildPath " $ProductName \Modules "
2019-11-16 02:29:04 +01:00
$userConfigPath = " ~/Documents/powershell/powershell.config.json "
2016-08-12 02:59:04 +02:00
}
else
{
2017-10-18 02:25:11 +02:00
$powershell = " $PSHOME /pwsh "
2016-08-12 02:59:04 +02:00
$expectedUserPath = [ System.Management.Automation.Platform ] :: SelectProductNameForDirectory ( " USER_MODULES " )
$expectedSharedPath = [ System.Management.Automation.Platform ] :: SelectProductNameForDirectory ( " SHARED_MODULES " )
2019-11-16 02:29:04 +01:00
$userConfigPath = " ~/.config/powershell/powershell.config.json "
}
$userConfigExists = $false
if ( Test-Path $userConfigPath ) {
$userConfigExists = $true
Copy-Item $userConfigPath " $userConfigPath .backup " -Force -ErrorAction Ignore
2016-08-12 02:59:04 +02:00
}
2019-11-16 02:29:04 +01:00
2016-08-12 02:59:04 +02:00
$expectedSystemPath = Join-Path -Path $PSHOME -ChildPath 'Modules'
2016-09-14 21:17:54 +02:00
2018-09-17 22:22:00 +02:00
# Skip these tests in cases when there is no 'pwsh' executable (e.g. when framework dependent PS package is used)
$skipNoPwsh = -not ( Test-Path $powershell )
2019-05-03 12:38:06 +02:00
2018-07-17 01:58:40 +02:00
if ( $IsWindows )
{
$expectedWindowsPowerShellPSHomePath = Join-Path $env:windir " System32 " " WindowsPowerShell " " v1.0 " " Modules "
}
2016-09-14 21:17:54 +02:00
## Setup a fake PSHome
$fakePSHome = Join-Path -Path $TestDrive -ChildPath 'FakePSHome'
$fakePSHomeModuleDir = Join-Path -Path $fakePSHome -ChildPath 'Modules'
$fakePowerShell = Join-Path -Path $fakePSHome -ChildPath ( Split-Path -Path $powershell -Leaf )
2017-10-18 02:25:11 +02:00
$fakePSDepsFile = Join-Path -Path $fakePSHome -ChildPath " pwsh.deps.json "
2016-09-14 21:17:54 +02:00
New-Item -Path $fakePSHome -ItemType Directory > $null
New-Item -Path $fakePSHomeModuleDir -ItemType Directory > $null
2016-08-12 02:59:04 +02:00
}
2016-08-11 01:34:07 +02:00
2019-11-16 02:29:04 +01:00
AfterAll {
if ( $userConfigExists ) {
Move-Item " $userConfigPath .backup " $userConfigPath -Force -ErrorAction Ignore
}
else {
Remove-Item " $userConfigPath " -Force -ErrorAction Ignore
}
}
2016-08-12 02:59:04 +02:00
BeforeEach {
2017-03-15 20:04:28 +01:00
$originalModulePath = $env:PSModulePath
2016-08-12 02:59:04 +02:00
}
2016-08-11 01:34:07 +02:00
2016-08-12 02:59:04 +02:00
AfterEach {
2017-03-15 20:04:28 +01:00
$env:PSModulePath = $originalModulePath
2016-08-11 01:34:07 +02:00
}
2018-09-17 22:22:00 +02:00
It " validate sxs module path " -Skip: $skipNoPwsh {
2016-08-11 01:34:07 +02:00
2017-03-15 20:04:28 +01:00
$env:PSModulePath = " "
$defaultModulePath = & $powershell -nopro -c '$env:PSModulePath'
2019-12-10 01:25:08 +01:00
$pathSeparator = [ System.IO.Path ] :: PathSeparator
2016-08-11 01:34:07 +02:00
2019-12-10 01:25:08 +01:00
$paths = $defaultModulePath . Replace ( " $pathSeparator $pathSeparator " , " $pathSeparator " ) -split $pathSeparator
2016-08-11 01:34:07 +02:00
2018-07-17 01:58:40 +02:00
if ( $IsWindows )
{
2019-12-10 01:25:08 +01:00
$expectedPaths = 3 # user, shared, pshome
$userPaths = [ System.Environment ] :: GetEnvironmentVariable ( " PSModulePath " , [ System.EnvironmentVariableTarget ] :: User )
$expectedPaths + = $userPaths ? $userPaths . Split ( $pathSeparator ) . Count : 0
$machinePaths = [ System.Environment ] :: GetEnvironmentVariable ( " PSModulePath " , [ System.EnvironmentVariableTarget ] :: Machine )
$expectedPaths + = $machinePaths ? $machinePaths . Split ( $pathSeparator ) . Count : 0
$paths . Count | Should -Be $expectedPaths
2018-07-17 01:58:40 +02:00
}
else
{
$paths . Count | Should -Be 3
}
2018-03-14 20:13:32 +01:00
$paths [ 0 ] . TrimEnd ( [ System.IO.Path ] :: DirectorySeparatorChar ) | Should -Be $expectedUserPath
$paths [ 1 ] . TrimEnd ( [ System.IO.Path ] :: DirectorySeparatorChar ) | Should -Be $expectedSharedPath
$paths [ 2 ] . TrimEnd ( [ System.IO.Path ] :: DirectorySeparatorChar ) | Should -Be $expectedSystemPath
2019-12-10 01:25:08 +01:00
$defaultModulePath | Should -BeLike " * $expectedWindowsPowerShellPSHomePath * "
2016-09-14 21:17:54 +02:00
}
2019-11-16 02:29:04 +01:00
It " Works with pshome module path derived from a different PowerShell instance " -Skip: ( ! $IsCoreCLR -or $skipNoPwsh ) {
2016-09-14 21:17:54 +02:00
2017-10-18 02:25:11 +02:00
## Create 'powershell' and 'pwsh.deps.json' in the fake PSHome folder,
2016-09-14 21:17:54 +02:00
## so that the module path calculation logic would believe it's real.
New-Item -Path $fakePowerShell -ItemType File -Force > $null
New-Item -Path $fakePSDepsFile -ItemType File -Force > $null
try {
2019-05-11 00:34:27 +02:00
## PSHome module path derived from another PowerShell instance should be ignored
2017-03-15 20:04:28 +01:00
$env:PSModulePath = $fakePSHomeModuleDir
$newModulePath = & $powershell -nopro -c '$env:PSModulePath'
2016-09-14 21:17:54 +02:00
$paths = $newModulePath -split [ System.IO.Path ] :: PathSeparator
2019-11-16 02:29:04 +01:00
$paths . Count | Should -Be 4
2018-03-14 20:13:32 +01:00
$paths [ 0 ] | Should -Be $expectedUserPath
$paths [ 1 ] | Should -Be $expectedSharedPath
$paths [ 2 ] | Should -Be $expectedSystemPath
2019-11-16 02:29:04 +01:00
$paths [ 3 ] | Should -Be $fakePSHomeModuleDir
2016-09-14 21:17:54 +02:00
} finally {
2017-10-18 02:25:11 +02:00
## Remove 'powershell' and 'pwsh.deps.json' from the fake PSHome folder
2016-09-14 21:17:54 +02:00
Remove-Item -Path $fakePowerShell -Force -ErrorAction SilentlyContinue
Remove-Item -Path $fakePSDepsFile -Force -ErrorAction SilentlyContinue
}
}
2019-05-11 00:34:27 +02:00
It " keep non-pshome module path derived from PowerShell instance parent " -Skip: ( ! $IsCoreCLR -or $skipNoPwsh ) {
2016-09-14 21:17:54 +02:00
2019-05-11 00:34:27 +02:00
## non-pshome module path derived from another PowerShell instance should be preserved
2016-09-14 21:17:54 +02:00
$customeModules = Join-Path -Path $TestDrive -ChildPath 'CustomModules'
2017-03-15 20:04:28 +01:00
$env:PSModulePath = $fakePSHomeModuleDir , $customeModules -join ( [ System.IO.Path ] :: PathSeparator )
$newModulePath = & $powershell -nopro -c '$env:PSModulePath'
2016-09-14 21:17:54 +02:00
$paths = $newModulePath -split [ System.IO.Path ] :: PathSeparator
2019-11-16 02:29:04 +01:00
$paths . Count | Should -Be 5
2018-03-14 20:13:32 +01:00
$paths -contains $fakePSHomeModuleDir | Should -BeTrue
$paths -contains $customeModules | Should -BeTrue
2016-08-11 01:34:07 +02:00
}
2017-07-07 18:43:37 +02:00
2018-09-17 22:22:00 +02:00
It 'Ensures $PSHOME\Modules is inserted correctly when launched from a different version of PowerShell' -Skip: ( ! ( $IsCoreCLR -and $IsWindows ) -or $skipNoPwsh ) {
2018-09-10 19:58:38 +02:00
# When launched from a different version of PowerShell, PSModulePath contains the other version's PSHOME\Modules path
2019-05-03 12:38:06 +02:00
# and the Windows PowerShell module path. The other version's module path should be removed and this version's
2018-09-10 19:58:38 +02:00
# PSHOME\Modules path should be inserted before Windows PowerShell module path.
$winpwshModulePath = [ System.IO.Path ] :: Combine ( [ System.Environment ] :: SystemDirectory , " WindowsPowerShell " , " v1.0 " , " Modules " ) ;
$pwshModulePath = Join-Path -Path $PSHOME -ChildPath 'Modules'
# create a fake 'other version' $PSHOME and $PSHOME\Modules
$fakeHome = Join-Path -Path $TestDrive -ChildPath 'fakepwsh'
$fakeModulePath = Join-Path -Path $fakeHome -ChildPath 'Modules'
$null = New-Item -Path $fakeHome -ItemType Directory
$null = New-Item -Path $fakeModulePath -ItemType Directory
# powershell looks for these to files to determine the directory is a pwsh directory.
Set-Content -Path " $fakeHome \pwsh.exe " -Value " fake pwsh.exe "
Set-Content -Path " $fakeHome \pwsh.deps.json " -Value 'fake pwsh.deps.json'
# replace the actual pwsh module path with the fake one.
$fakeModulePath = $env:PSModulePath . Replace ( $pwshModulePath , $fakeModulePath , [ StringComparison ] :: OrdinalIgnoreCase )
$newModulePath = & $powershell -nopro -c '$env:PSModulePath'
$pwshIndex = $newModulePath . IndexOf ( $pwshModulePath , [ StringComparison ] :: OrdinalIgnoreCase )
$wpshIndex = $newModulePath . IndexOf ( $winpwshModulePath , [ StringComparison ] :: OrdinalIgnoreCase )
# ensure both module paths exist and the pwsh module path occurs before the Windows PowerShell module path
$pwshIndex | Should -Not -Be -1
$wpshIndex | Should -Not -Be -1
$pwshIndex | Should -BeLessThan $wpshIndex
}
2019-11-16 02:29:04 +01:00
It 'Windows PowerShell does not inherit PowerShell paths' -Skip: ( ! $IsWindows ) {
$out = powershell . exe -noprofile -command '$env:PSModulePath'
2020-03-10 07:31:44 +01:00
$out | Should -Not -BeLike " * $expectedUserPath * "
$out | Should -Not -BeLike " * $expectedSharedPath * "
$out | Should -Not -BeLike " * $expectedSystemPath * "
2019-11-16 02:29:04 +01:00
}
It 'Windows PowerShell inherits user added paths' -Skip: ( ! $IsWindows ) {
$env:PSModulePath + = " ;myPath "
$out = powershell . exe -noprofile -command '$env:PSModulePath'
$out | Should -BeLike '*;myPath'
}
It 'Windows PowerShell does not inherit path defined in powershell.config.json' -Skip: ( ! $IsWindows ) {
2019-12-10 01:25:08 +01:00
try {
$userConfig = '{ "PSModulePath": "myUserPath" }'
Set-Content -Path $userConfigPath -Value $userConfig -Force
2020-01-05 08:17:41 +01:00
$out = & $powershell -noprofile -command 'powershell.exe -noprofile -command $env:PSModulePath'
2019-12-10 01:25:08 +01:00
$out | Should -Not -BeLike 'myUserPath;*'
}
finally {
Remove-Item -Path $userConfigPath -Force
}
2019-11-16 02:29:04 +01:00
}
2016-08-11 01:34:07 +02:00
}