You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three Pester tests fail in the ReleaseAutomationTest comparison of 7.7.0-preview.1 against the 7.6.0-rc.1 baseline on portable (ZIP/TAR) and several non-portable distribution lanes. All three are downstream of PR #26565 ("Refactor the module path construction code", commit 592668bd0), which is in release/v7.7.0-preview.1 but is not in v7.6.0-rc.1 (verified: git merge-base --is-ancestor 592668bd0 v7.6.0-rc.1 returns 1).
Test ID
Test
File
Origin
103778
ConsoleHost - SettingsFile - PSModulePath - Verify PowerShell PSModulePath should contain paths from config file (Windows)
Pre-existing since PR #7183 (2018); newly fails in preview.1
Lanes affected (one or more of these tests fail per lane):
WindowsServer2016ZIP - Unelevated
ubuntu22 TAR
mariner ARM64
macOS TAR, macOS
linux ARM32
debian12
azurelinux30
First failing build: ReleaseAutomationTest-27557-ps-671171.
These tests were previously tracked as Case 2 of issue #27343 and are split out here because the root cause is unrelated to PR #27305 (the original framing of #27343).
Commit 592668bd0 rewrote ModuleIntrinsics.GetModulePath and replaced the helper AddToPath (with PathContainsSubstring) with UpdatePath, which uses HashSet<string> plus Path.TrimEndingDirectorySeparator for dedup and advances insertPosition after each insert. It also added a static static ModuleIntrinsics() { SetModulePath(); } initializer.
The "EVT.Process exists" branch in preview.1's GetModulePath is:
When hklmMachineModulePath is non-empty, systemModulePathToUse = hklmMachineModulePath and psHomeModulePath (i.e., $PSHOME/Modules) is never added to the process PSModulePath. The same logical branch exists on Linux/macOS via the equivalent OS-level system module path.
PR #26565 also added the new test Verify PowerShell PSModulePath should contain paths from config file (test 103778 / 103842) that asserts $PSHOME/Modules is already present at IndexOf > 0 in $env:PSModulePath. That assertion is incompatible with portable distributions where $PSHOME is a user-local path not registered in the OS-level PSModulePath.
Why each test fails
Tests 103778 (Windows) and 103842 (non-Windows)
# BeforeAll: write settings file with PSModulePath = "$PSHOME/Modules<sep>$TestDrive/NonExist"$psModulePath=&$powershell-NoProfile -SettingsFile $CustomSettingsFile-Command '$env:PSModulePath'# Assertion:$index=$psModulePath.IndexOf("$mPath1$pathSep", [StringComparison]::OrdinalIgnoreCase)
$index| Should -BeGreaterThan 0# FAILS - $PSHOME/Modules ends up at position 0
Failure mechanics on a portable distribution:
Child pwsh inherits parent $env:PSModulePath = <personal><sep><shared><sep><OS-defaults> and does not contain the ZIP/TAR-extracted $PSHOME/Modules.
Settings-file PSModulePath is read as hkcuUserModulePath = "$PSHOME/Modules<sep>$TestDrive/NonExist".
$PSHOME/Modules is NOT in initialPaths -> inserted at position 0.
$TestDrive/NonExist is NOT in initialPaths -> inserted at position 1.
Final PSModulePath starts with $PSHOME/Modules<sep>$TestDrive/NonExist<sep>....
IndexOf("$PSHOME/Modules<sep>") = 0 -> Should -BeGreaterThan 0 fails.
StartsWith("$TestDrive/NonExist<sep>") = false -> later assertion also fails.
The BeforeAll comment in the test literally states: "$mPath1 already exists in the value of env PSModulePath, so it won''t be added again." That precondition does not hold on portable distributions. Since the It block is shared across platforms, it manifests as test 103778 on Windows lanes and 103842 on non-Windows lanes.
Test 108309
$pscoreSystemPath=Join-Path-Path $PSHOME-ChildPath 'Modules'$pscorePaths=$env:psmodulepath$pscorePaths| Should -BeLike "*$pscoreSystemPath*"# FAILS
Same root assumption - the test requires $PSHOME/Modules to be in $env:PSModulePath. On portable distributions this is not guaranteed.
This test is 7+ years old and passed on the v7.6.0-rc.1 baseline (confirmed via the rc.1 ReleaseAutomationTest xUnit output: <test-case description="WinCompat process does not inherit PowerShell-Core-specific paths" ... result="Success" success="True" executed="True"/>). It now fails on preview.1, so this is a real product-side regression introduced by PR #26565 - not just a comparator artifact. The rc.1 code (AddToPath + PathContainsSubstring) produced an effective PSModulePath that contained $PSHOME/Modules on the affected lanes; preview.1's UpdatePath rewrite no longer does. A product-side fix is required in addition to the test fix below.
Suggested resolution
Test side (required regardless): make the assertions portable-distribution-aware.
For tests 103778 / 103842 (test/powershell/Host/ConsoleHost.Tests.ps1):
Option A - have BeforeAll ensure the precondition the test was written against:
BeforeAll {
$CustomSettingsFile=Join-Path-Path $TestDrive-ChildPath 'powershell.test.json'$mPath1=Join-Path$PSHOME'Modules'$mPath2=Join-Path$TestDrive'NonExist'$pathSep= [System.IO.Path]::PathSeparator
# Test assumes $PSHOME/Modules is already in $env:PSModulePath.# On ZIP/TAR/portable distributions this may not hold; ensure it.$contains=$env:PSModulePath-split [regex]::Escape($pathSep) |Where-Object { [string]::Equals($_,$mPath1,'OrdinalIgnoreCase') }
if (-not$contains) {
$script:savedPSModulePath=$env:PSModulePath$env:PSModulePath="$mPath1$pathSep$env:PSModulePath"
}
$ModulePath="${mPath1}${pathSep}${mPath2}".Replace(''\'',"\\")
Set-Content-Path $CustomSettingsfile-Value "{`"Microsoft.PowerShell:ExecutionPolicy`":`"Unrestricted`", `"PSModulePath`": `"$ModulePath`" }"-ErrorAction Stop
}
AfterAll {
if ($script:savedPSModulePath) {
$env:PSModulePath=$script:savedPSModulePath
}
}
Option B - skip when the precondition does not hold:
It "Verify PowerShell PSModulePath should contain paths from config file" {
if (($env:PSModulePath-split [regex]::Escape([IO.Path]::PathSeparator)) -notcontains$mPath1) {
Set-ItResult-Skipped -Because ''$PSHOME/Modules is not in$env:PSModulePath (portable distribution); test precondition does not hold.''return
}
# ... existing assertions ...
}
For test 108309 (test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1):
It ''WinCompat process does not inherit PowerShell-Core-specific paths'' {
$pscoreUserPath=Join-Path-Path $HOME-ChildPath "Documents/PowerShell/Modules"$pscoreSharedPath=Join-Path-Path $env:ProgramFiles-ChildPath "PowerShell/Modules"$pscoreSystemPath=Join-Path-Path $PSHOME-ChildPath ''Modules''$pscorePaths=$env:psmodulepath$pscorePaths| Should -BeLike "*$pscoreUserPath*"$pscorePaths| Should -BeLike "*$pscoreSharedPath*"if ($pscorePaths-like"*$pscoreSystemPath*") {
$pscorePaths| Should -BeLike "*$pscoreSystemPath*"
}
# else: tolerated - portable/ZIP/TAR distributions do not put $PSHOME/Modules in $env:PSModulePath.# Remaining WinCompat exclusion assertions still run unchanged.# ...
}
Product side (required - confirmed regression): PR #26565's AddToPath -> UpdatePath rewrite changed the effective PSModulePath shape on the affected lanes; rc.1 included $PSHOME/Modules, preview.1 does not. Two viable options:
Always include psHomeModulePath in the system path. In the "EVT.Process exists" branch of ModuleIntrinsics.GetModulePath, instead of:
Option 1 is preferred. After the fix, re-run the ReleaseAutomationTest lanes that originally failed (especially WindowsServer2016ZIP - Unelevated) and confirm $PSHOME/Modules is in $env:PSModulePath.
Branch strategy
Per .github/instructions/code-review-branch-strategy.instructions.md: PR #26565 is on master and on release/v7.7.0-preview.1. Fix the test files on master first; backport to release branches as needed. Do not add ZIP/TAR-specific workarounds only on the release branch.
Summary
Three Pester tests fail in the
ReleaseAutomationTestcomparison of 7.7.0-preview.1 against the 7.6.0-rc.1 baseline on portable (ZIP/TAR) and several non-portable distribution lanes. All three are downstream of PR #26565 ("Refactor the module path construction code", commit592668bd0), which is inrelease/v7.7.0-preview.1but is not inv7.6.0-rc.1(verified:git merge-base --is-ancestor 592668bd0 v7.6.0-rc.1returns 1).ConsoleHost - SettingsFile - PSModulePath - Verify PowerShell PSModulePath should contain paths from config file(Windows)test/powershell/Host/ConsoleHost.Tests.ps1#L402Itblock, run on Linux/macOS lanes)test/powershell/Host/ConsoleHost.Tests.ps1#L402Import-Module with WinCompat - WinCompat process does not inherit PowerShell-Core-specific pathstest/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1#L727Lanes affected (one or more of these tests fail per lane):
WindowsServer2016ZIP - Unelevatedubuntu22 TARmariner ARM64macOS TAR,macOSlinux ARM32debian12azurelinux30First failing build:
ReleaseAutomationTest-27557-ps-671171.These tests were previously tracked as Case 2 of issue #27343 and are split out here because the root cause is unrelated to PR #27305 (the original framing of #27343).
Background: what PR #26565 changed
Commit
592668bd0rewroteModuleIntrinsics.GetModulePathand replaced the helperAddToPath(withPathContainsSubstring) withUpdatePath, which usesHashSet<string>plusPath.TrimEndingDirectorySeparatorfor dedup and advancesinsertPositionafter each insert. It also added a staticstatic ModuleIntrinsics() { SetModulePath(); }initializer.The "EVT.Process exists" branch in preview.1's
GetModulePathis:When
hklmMachineModulePathis non-empty,systemModulePathToUse = hklmMachineModulePathandpsHomeModulePath(i.e.,$PSHOME/Modules) is never added to the processPSModulePath. The same logical branch exists on Linux/macOS via the equivalent OS-level system module path.PR #26565 also added the new test
Verify PowerShell PSModulePath should contain paths from config file(test 103778 / 103842) that asserts$PSHOME/Modulesis already present atIndexOf > 0in$env:PSModulePath. That assertion is incompatible with portable distributions where$PSHOMEis a user-local path not registered in the OS-levelPSModulePath.Why each test fails
Tests 103778 (Windows) and 103842 (non-Windows)
Failure mechanics on a portable distribution:
$env:PSModulePath=<personal><sep><shared><sep><OS-defaults>and does not contain the ZIP/TAR-extracted$PSHOME/Modules.PSModulePathis read ashkcuUserModulePath = "$PSHOME/Modules<sep>$TestDrive/NonExist".GetModulePath"Process exists" branch setspersonalModulePathToUse = hkcuUserModulePath.UpdatePath(current, "$PSHOME/Modules<sep>$TestDrive/NonExist", ref insertIndex=0):$PSHOME/Modulesis NOT ininitialPaths-> inserted at position 0.$TestDrive/NonExistis NOT ininitialPaths-> inserted at position 1.PSModulePathstarts with$PSHOME/Modules<sep>$TestDrive/NonExist<sep>....IndexOf("$PSHOME/Modules<sep>")=0->Should -BeGreaterThan 0fails.StartsWith("$TestDrive/NonExist<sep>")=false-> later assertion also fails.The
BeforeAllcomment in the test literally states: "$mPath1 already exists in the value of env PSModulePath, so it won''t be added again." That precondition does not hold on portable distributions. Since theItblock is shared across platforms, it manifests as test 103778 on Windows lanes and 103842 on non-Windows lanes.Test 108309
Same root assumption - the test requires
$PSHOME/Modulesto be in$env:PSModulePath. On portable distributions this is not guaranteed.This test is 7+ years old and passed on the v7.6.0-rc.1 baseline (confirmed via the rc.1
ReleaseAutomationTestxUnit output:<test-case description="WinCompat process does not inherit PowerShell-Core-specific paths" ... result="Success" success="True" executed="True"/>). It now fails on preview.1, so this is a real product-side regression introduced by PR #26565 - not just a comparator artifact. The rc.1 code (AddToPath+PathContainsSubstring) produced an effectivePSModulePaththat contained$PSHOME/Moduleson the affected lanes; preview.1'sUpdatePathrewrite no longer does. A product-side fix is required in addition to the test fix below.Suggested resolution
Test side (required regardless): make the assertions portable-distribution-aware.
For tests 103778 / 103842 (
test/powershell/Host/ConsoleHost.Tests.ps1):Option A - have
BeforeAllensure the precondition the test was written against:BeforeAll { $CustomSettingsFile = Join-Path -Path $TestDrive -ChildPath 'powershell.test.json' $mPath1 = Join-Path $PSHOME 'Modules' $mPath2 = Join-Path $TestDrive 'NonExist' $pathSep = [System.IO.Path]::PathSeparator # Test assumes $PSHOME/Modules is already in $env:PSModulePath. # On ZIP/TAR/portable distributions this may not hold; ensure it. $contains = $env:PSModulePath -split [regex]::Escape($pathSep) | Where-Object { [string]::Equals($_, $mPath1, 'OrdinalIgnoreCase') } if (-not $contains) { $script:savedPSModulePath = $env:PSModulePath $env:PSModulePath = "$mPath1$pathSep$env:PSModulePath" } $ModulePath = "${mPath1}${pathSep}${mPath2}".Replace(''\'', "\\") Set-Content -Path $CustomSettingsfile -Value "{`"Microsoft.PowerShell:ExecutionPolicy`":`"Unrestricted`", `"PSModulePath`": `"$ModulePath`" }" -ErrorAction Stop } AfterAll { if ($script:savedPSModulePath) { $env:PSModulePath = $script:savedPSModulePath } }Option B - skip when the precondition does not hold:
For test 108309 (
test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1):Product side (required - confirmed regression): PR #26565's
AddToPath->UpdatePathrewrite changed the effectivePSModulePathshape on the affected lanes; rc.1 included$PSHOME/Modules, preview.1 does not. Two viable options:Always include
psHomeModulePathin the system path. In the "EVT.Process exists" branch ofModuleIntrinsics.GetModulePath, instead of:add both, so
$PSHOME/Modulesis always present regardless of HKLM state:UpdatePathalready dedups viaHashSet<string>, so no double-insertion when HKLM also contains$PSHOME/Modules(e.g. MSI install).Restore the rc.1 path-construction shape directly by reverting the relevant portion of
GetModulePathto the pre-Refactor the module path construction code to make it more robust and easier to maintain #26565 behavior (compose viaAddToPathsemantics) for the affected branch. Lower-risk for backport but loses the dedup/ordering improvements of Refactor the module path construction code to make it more robust and easier to maintain #26565.Option 1 is preferred. After the fix, re-run the
ReleaseAutomationTestlanes that originally failed (especiallyWindowsServer2016ZIP - Unelevated) and confirm$PSHOME/Modulesis in$env:PSModulePath.Branch strategy
Per
.github/instructions/code-review-branch-strategy.instructions.md: PR #26565 is onmasterand onrelease/v7.7.0-preview.1. Fix the test files onmasterfirst; backport to release branches as needed. Do not add ZIP/TAR-specific workarounds only on the release branch.Files affected
test/powershell/Host/ConsoleHost.Tests.ps1(lines 391-413) - tests 103778 / 103842test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1(line 727) - test 108309src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs- product-side fix for confirmed 108309 regression (rc.1 result:Success)Related
592668bd0); not inv7.6.0-rc.1ReleaseAutomationTest-27557-ps-671171