Title: Test failures from module-path refactor PR #26565: tests 103778 / 103842 / 108309 fail on ZIP/TAR/portable distribution lanes · Issue #27345 · PowerShell/PowerShell · GitHub
Open Graph Title: Test failures from module-path refactor PR #26565: tests 103778 / 103842 / 108309 fail on ZIP/TAR/portable distribution lanes · Issue #27345 · PowerShell/PowerShell
X Title: Test failures from module-path refactor PR #26565: tests 103778 / 103842 / 108309 fail on ZIP/TAR/portable distribution lanes · Issue #27345 · PowerShell/PowerShell
Description: Summary 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 ("Refacto...
Open Graph Description: Summary 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 thr...
X Description: Summary 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 thr...
Opengraph URL: https://github.com/PowerShell/PowerShell/issues/27345
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Test failures from module-path refactor PR #26565: tests 103778 / 103842 / 108309 fail on ZIP/TAR/portable distribution lanes","articleBody":"## Summary\n\nThree 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).\n\n| Test ID | Test | File | Origin |\n|---|---|---|---|\n| 103778 | `ConsoleHost - SettingsFile - PSModulePath - Verify PowerShell PSModulePath should contain paths from config file` (Windows) | `test/powershell/Host/ConsoleHost.Tests.ps1#L402` | New test added by PR #26565 |\n| 103842 | Non-Windows equivalent of 103778 (same `It` block, run on Linux/macOS lanes) | `test/powershell/Host/ConsoleHost.Tests.ps1#L402` | New test added by PR #26565 |\n| 108309 | `Import-Module with WinCompat - WinCompat process does not inherit PowerShell-Core-specific paths` | `test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1#L727` | Pre-existing since PR #7183 (2018); newly fails in preview.1 |\n\nLanes affected (one or more of these tests fail per lane):\n\n- `WindowsServer2016ZIP - Unelevated`\n- `ubuntu22 TAR`\n- `mariner ARM64`\n- `macOS TAR`, `macOS`\n- `linux ARM32`\n- `debian12`\n- `azurelinux30`\n\nFirst failing build: `ReleaseAutomationTest-27557-ps-671171`.\n\nThese 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).\n\n## Background: what PR #26565 changed\n\nCommit `592668bd0` rewrote `ModuleIntrinsics.GetModulePath` and replaced the helper `AddToPath` (with `PathContainsSubstring`) with `UpdatePath`, which uses `HashSet\u003cstring\u003e` plus `Path.TrimEndingDirectorySeparator` for dedup and advances `insertPosition` after each insert. It also added a static `static ModuleIntrinsics() { SetModulePath(); }` initializer.\n\nThe \"EVT.Process exists\" branch in preview.1's `GetModulePath` is:\n\n```csharp\nstring systemModulePathToUse = string.IsNullOrEmpty(hklmMachineModulePath)\n ? psHomeModulePath\n : hklmMachineModulePath;\n\nint insertIndex = 0;\ncurrentProcessModulePath = UpdatePath(currentProcessModulePath, personalModulePathToUse, ref insertIndex);\ncurrentProcessModulePath = UpdatePath(currentProcessModulePath, sharedModulePath, ref insertIndex);\ncurrentProcessModulePath = UpdatePath(currentProcessModulePath, systemModulePathToUse, ref insertIndex);\n```\n\nWhen `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.\n\nPR #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 \u003e 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`.\n\n## Why each test fails\n\n### Tests 103778 (Windows) and 103842 (non-Windows)\n\n```powershell\n# BeforeAll: write settings file with PSModulePath = \"$PSHOME/Modules\u003csep\u003e$TestDrive/NonExist\"\n$psModulePath = \u0026 $powershell -NoProfile -SettingsFile $CustomSettingsFile -Command '$env:PSModulePath'\n# Assertion:\n$index = $psModulePath.IndexOf(\"$mPath1$pathSep\", [StringComparison]::OrdinalIgnoreCase)\n$index | Should -BeGreaterThan 0 # FAILS - $PSHOME/Modules ends up at position 0\n```\n\nFailure mechanics on a portable distribution:\n\n1. Child pwsh inherits parent `$env:PSModulePath` = `\u003cpersonal\u003e\u003csep\u003e\u003cshared\u003e\u003csep\u003e\u003cOS-defaults\u003e` and does **not** contain the ZIP/TAR-extracted `$PSHOME/Modules`.\n2. Settings-file `PSModulePath` is read as `hkcuUserModulePath = \"$PSHOME/Modules\u003csep\u003e$TestDrive/NonExist\"`.\n3. `GetModulePath` \"Process exists\" branch sets `personalModulePathToUse = hkcuUserModulePath`.\n4. `UpdatePath(current, \"$PSHOME/Modules\u003csep\u003e$TestDrive/NonExist\", ref insertIndex=0)`:\n - `$PSHOME/Modules` is NOT in `initialPaths` -\u003e inserted at position 0.\n - `$TestDrive/NonExist` is NOT in `initialPaths` -\u003e inserted at position 1.\n5. Final `PSModulePath` starts with `$PSHOME/Modules\u003csep\u003e$TestDrive/NonExist\u003csep\u003e...`.\n6. `IndexOf(\"$PSHOME/Modules\u003csep\u003e\")` = `0` -\u003e `Should -BeGreaterThan 0` fails.\n7. `StartsWith(\"$TestDrive/NonExist\u003csep\u003e\")` = `false` -\u003e later assertion also fails.\n\nThe `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.\n\n### Test 108309\n\n```powershell\n$pscoreSystemPath = Join-Path -Path $PSHOME -ChildPath 'Modules'\n$pscorePaths = $env:psmodulepath\n$pscorePaths | Should -BeLike \"*$pscoreSystemPath*\" # FAILS\n```\n\nSame root assumption - the test requires `$PSHOME/Modules` to be in `$env:PSModulePath`. On portable distributions this is not guaranteed.\n\nThis test is 7+ years old. It is reported as a \"New Failure\" by the comparator because it likely passed on the rc.1 baseline (rc.1 uses the older `AddToPath` path-construction code which had different ordering/dedup semantics) and now fails on preview.1 after PR #26565. **Open verification item:** confirm the rc.1 `ReleaseAutomationTest` result for 108309 on each affected lane.\n\n- If `Passed` on rc.1 -\u003e PR #26565 changed the effective `PSModulePath` shape; this is also a real product-side behavior change and may warrant a product fix in addition to the test fix.\n- If `Failed` / `Skipped` / `NotExecuted` on rc.1 -\u003e comparator artifact only; just apply the test fix.\n\n## Suggested resolution\n\n**Test side (required regardless):** make the assertions portable-distribution-aware.\n\nFor tests 103778 / 103842 (`test/powershell/Host/ConsoleHost.Tests.ps1`):\n\nOption A - have `BeforeAll` ensure the precondition the test was written against:\n\n```powershell\nBeforeAll {\n $CustomSettingsFile = Join-Path -Path $TestDrive -ChildPath 'powershell.test.json'\n $mPath1 = Join-Path $PSHOME 'Modules'\n $mPath2 = Join-Path $TestDrive 'NonExist'\n $pathSep = [System.IO.Path]::PathSeparator\n\n # Test assumes $PSHOME/Modules is already in $env:PSModulePath.\n # On ZIP/TAR/portable distributions this may not hold; ensure it.\n $contains = $env:PSModulePath -split [regex]::Escape($pathSep) |\n Where-Object { [string]::Equals($_, $mPath1, 'OrdinalIgnoreCase') }\n if (-not $contains) {\n $script:savedPSModulePath = $env:PSModulePath\n $env:PSModulePath = \"$mPath1$pathSep$env:PSModulePath\"\n }\n\n $ModulePath = \"${mPath1}${pathSep}${mPath2}\".Replace(''\\'', \"\\\\\")\n Set-Content -Path $CustomSettingsfile -Value \"{`\"Microsoft.PowerShell:ExecutionPolicy`\":`\"Unrestricted`\", `\"PSModulePath`\": `\"$ModulePath`\" }\" -ErrorAction Stop\n}\n\nAfterAll {\n if ($script:savedPSModulePath) {\n $env:PSModulePath = $script:savedPSModulePath\n }\n}\n```\n\nOption B - skip when the precondition does not hold:\n\n```powershell\nIt \"Verify PowerShell PSModulePath should contain paths from config file\" {\n if (($env:PSModulePath -split [regex]::Escape([IO.Path]::PathSeparator)) -notcontains $mPath1) {\n Set-ItResult -Skipped -Because ''$PSHOME/Modules is not in $env:PSModulePath (portable distribution); test precondition does not hold.''\n return\n }\n # ... existing assertions ...\n}\n```\n\nFor test 108309 (`test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1`):\n\n```powershell\nIt ''WinCompat process does not inherit PowerShell-Core-specific paths'' {\n $pscoreUserPath = Join-Path -Path $HOME -ChildPath \"Documents/PowerShell/Modules\"\n $pscoreSharedPath = Join-Path -Path $env:ProgramFiles -ChildPath \"PowerShell/Modules\"\n $pscoreSystemPath = Join-Path -Path $PSHOME -ChildPath ''Modules''\n $pscorePaths = $env:psmodulepath\n $pscorePaths | Should -BeLike \"*$pscoreUserPath*\"\n $pscorePaths | Should -BeLike \"*$pscoreSharedPath*\"\n if ($pscorePaths -like \"*$pscoreSystemPath*\") {\n $pscorePaths | Should -BeLike \"*$pscoreSystemPath*\"\n }\n # else: tolerated - portable/ZIP/TAR distributions do not put $PSHOME/Modules in $env:PSModulePath.\n # Remaining WinCompat exclusion assertions still run unchanged.\n # ...\n}\n```\n\n**Product side (only if 108309 was `Passed` on rc.1):** investigate whether the `AddToPath` -\u003e `UpdatePath` rewrite in PR #26565 changed the effective `PSModulePath` shape on portable distributions and, if so, restore the previous behavior or explicitly add `psHomeModulePath` to the system path even when HKLM (or its OS-level equivalent) is non-empty.\n\n## Branch strategy\n\nPer `.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.\n\n## Files affected\n\n- `test/powershell/Host/ConsoleHost.Tests.ps1` (lines 391-413) - tests 103778 / 103842\n- `test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1` (line 727) - test 108309\n- `src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs` - product-side, only if 108309 regression on rc.1 is confirmed\n\n## Related\n\n- PR #26565 - \"Refactor the module path construction code\" (commit `592668bd0`); not in `v7.6.0-rc.1`\n- Issue #27343 - parent triage issue (Cases 1 and 3); Case 2 was extracted into this issue\n- First failing build: `ReleaseAutomationTest-27557-ps-671171`","author":{"url":"https://github.com/jshigetomi","@type":"Person","name":"jshigetomi"},"datePublished":"2026-04-23T18:40:38.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/27345/PowerShell/issues/27345"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:a6e7a749-fabe-efc7-9fc1-bcdd17c775bb |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AE80:EEEA7:22DF156:2F1FB84:6A59AF6A |
| html-safe-nonce | 9ac496f72d69f3f57c7ac845dd32be5b30badf59724f77196c1db26e643f6e77 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBRTgwOkVFRUE3OjIyREYxNTY6MkYxRkI4NDo2QTU5QUY2QSIsInZpc2l0b3JfaWQiOiI0Nzk4MzIyNTA1NTA0MzcwNTM4IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 3444eb6913be8fc41d6930079aeebca60f1b0219cf1901fbd71689995142e02e |
| hovercard-subject-tag | issue:4318075670 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/PowerShell/PowerShell/27345/issue_layout |
| twitter:image | https://opengraph.githubassets.com/1dff1b5ca70968b88b6684da7f01d83b54a968de8121c1e123481ce9c979378a/PowerShell/PowerShell/issues/27345 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/1dff1b5ca70968b88b6684da7f01d83b54a968de8121c1e123481ce9c979378a/PowerShell/PowerShell/issues/27345 |
| og:image:alt | Summary 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 thr... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | jshigetomi |
| hostname | github.com |
| expected-hostname | github.com |
| None | ba3976babb66479b1c943a8edc0777d96157da48fadc0161f9ddb219deee8353 |
| turbo-cache-control | no-preview |
| go-import | github.com/PowerShell/PowerShell git https://github.com/PowerShell/PowerShell.git |
| octolytics-dimension-user_id | 11524380 |
| octolytics-dimension-user_login | PowerShell |
| octolytics-dimension-repository_id | 49609581 |
| octolytics-dimension-repository_nwo | PowerShell/PowerShell |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 49609581 |
| octolytics-dimension-repository_network_root_nwo | PowerShell/PowerShell |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | ab680789ae4a316cdaf0d5a292a1760140931cc4 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width