Import Pester via its manifest in parallel workers#2819
Merged
Conversation
Invoke-TestInParallel handed each worker $ExecutionContext.SessionState.Module.Path,
which is the root module (Pester.psm1), not the manifest (Pester.psd1). Importing the
bare .psm1 loads Pester without its manifest metadata, so the worker's Pester reports
ModuleVersion 0.0.0.0.
A test that imports a module whose manifest lists Pester in RequiredModules (e.g.
@{ ModuleName = 'Pester'; ModuleVersion = '5.7.1' }) then fails under Run.Parallel,
because the loaded 0.0.0.0 Pester does not satisfy the required version and PowerShell
tries to load Pester from disk instead - throwing either "no valid module file was
found in any module directory" or an assembly-already-loaded conflict.
Resolve the manifest (.psd1) next to the module and import that, falling back to the
root module path when no manifest is present, so workers load Pester with its real
version.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Collaborator
|
Of course! That's why the formatview tests failed when I tested parallel in this repo. 💡 |
The regression test imports a RequiresPester module whose manifest lists Pester in RequiredModules. When Run.Parallel falls back to sequential (e.g. Windows PowerShell 5.1, which has no ForEach-Object -Parallel) that import runs in the current process, so the module leaks into the shared P-test session. The next *.ts.ps1 file's `Get-Module Pester | Remove-Module` then fails with "Unable to remove the module 'Pester' because it is required by 'RequiresPester'". Remove the module in the test's finally block before deleting its folder. Unloading first also releases the lock on its .psm1 so the folder removal cannot fail on Windows. The cleanup is a harmless no-op on the true-parallel path, where the import stays in the worker runspace. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Under
Run.Parallel, a test that imports a module whose manifest lists Pester inRequiredModulesfails, e.g.:The same test passes in a sequential run.
Root cause
Invoke-TestInParallelhanded each worker$ExecutionContext.SessionState.Module.Path, which is the root module (Pester.psm1), not the manifest (Pester.psd1). Each worker doesImport-Module <that path>, and importing the bare.psm1loads Pester without its manifest metadata, so the worker's Pester reportsModuleVersion0.0.0.0.When a test then imports a third‑party module that requires
Pester >= 5.7.1, the loaded0.0.0.0Pester does not satisfy the requirement, so PowerShell tries to load Pester from disk — throwing either "no valid module file was found in any module directory" (reporter's environment) or "Could not load file or assembly 'Pester … already loaded" (when a real Pester is installed). Sequential runs are unaffected because the parent imported Pester through its manifest, so the version is correct.Fix
Resolve the manifest (
<ModuleBase>/<Name>.psd1) and import that in the worker, falling back to the root‑module path when no manifest is present. Workers now load Pester with its real version, soRequiredModules = Pesterresolves against the already‑loaded module.Test
Adds a regression test in
tst/Pester.RSpec.Parallel.ts.ps1that runs a module declaringRequiredModules = @{ ModuleName = 'Pester'; … }underRun.Parallel. It fails before the fix (worker Pester is0.0.0.0) and passes after. Verified the full parallel suite stays green and the custom build analyzer is clean.Fix #2816