Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Tests/Build.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ Describe "Validation of build environment" -Tag Unit {
}

Context "Pester result gate" {
It "includes test, block, and container failures" {
$parallelPesterScript = Get-Content -LiteralPath (Join-Path $moduleRoot 'Tests/Invoke-ParallelPester.ps1') -Raw
BeforeAll {
$script:parallelPesterScript = Get-Content -LiteralPath (Join-Path $moduleRoot 'Tests/Invoke-ParallelPester.ps1') -Raw
}

It "includes test, block, and container failures" {
$parallelPesterScript | Should -Match '\$result\.FailedCount \+ \$result\.FailedBlocksCount \+ \$result\.FailedContainersCount'
}

It "does not share the parent host with Pester thread jobs" {
$parallelPesterScript | Should -Not -Match '(?m)^\s*-StreamingHost\b'
$parallelPesterScript | Should -Match '\$jobOutput = Receive-Job -Job \$job -ErrorAction Stop\s*\r?\n'
}
}

Context "CHANGELOG" {
Expand Down
32 changes: 11 additions & 21 deletions Tests/Invoke-ParallelPester.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
Start-ThreadJob lets us Wait-Job -Timeout each file individually, Stop-Job +
Remove-Job -Force to tear down stuck runspaces deterministically, and proceed
to the merged-XML write block + a clean `exit` regardless of background
thread state.
thread state. Child output is replayed when each job completes because sharing
the parent host via -StreamingHost can corrupt Pester discovery state.

.PARAMETER Path
Path to the directory containing test files, or an array of test file paths.
Expand Down Expand Up @@ -262,8 +263,8 @@ if ($canParallel) {
# so a single hung file can't take down the whole suite.
# * Stop-Job + Remove-Job -Force tears down the runspace deterministically.
# * -ThrottleLimit still bounds concurrency the same way as FE-O-P.
# * -StreamingHost preserves the live Write-Host streaming we get from
# FE-O-P today, so CI logs stay informative as files complete.
# * Receive-Job replays each file's output after completion, so CI logs
# remain informative without sharing the parent's host object.
# When this script's final `exit` runs, any still-running background
# threads are reaped by the process tearing down — they are no longer
# the orchestrator's problem to drain cleanly.
Expand All @@ -277,16 +278,14 @@ if ($canParallel) {
$perFileTimeoutSeconds = 600
$jobInfos = New-Object System.Collections.Generic.List[object]
foreach ($testFile in $testFiles) {
# NOTE: -StreamingHost streams Write-Host / Write-Information from
# the child runspace to the parent's host as it is produced, which
# keeps CI logs in the same shape FE-O-P produced. We pass $Host
# explicitly because $PSHost in a ThreadJob defaults to a default
# PSHost that does not write to the Actions runner stdout.
# Do not pass -StreamingHost here. Sharing the parent's host object
# across Pester thread jobs has an upstream race that can corrupt
# discovery state: https://github.com/pester/Pester/issues/2383
# Receive-Job replays the buffered output after each file completes.
$job = Start-ThreadJob `
-ScriptBlock ([scriptblock]::Create($runTestBodyText)) `
-ArgumentList @($testFile, $projectRoot, $Tag, $ExcludeTag, $Output, $tempResultsDir, $generateXml, $helpersPath) `
-ThrottleLimit $ThrottleLimit `
-StreamingHost $Host `
-Name "Pester:$($testFile.BaseName)"
$jobInfos.Add(@{ File = $testFile; Job = $job })
}
Expand Down Expand Up @@ -323,18 +322,9 @@ if ($canParallel) {
}
else {
try {
# Redirect the Information stream (6>) to $null. The child
# already wrote everything to the parent's host live via
# -StreamingHost above; without this redirect Receive-Job
# re-emits the Information records and we get every Pester
# line printed twice (once streamed, once replayed) — see
# the duplicated "Starting discovery / Discovery found / Running
# tests / [+] file / Tests completed / Tests Passed" blocks
# that appear in a smoke test against two unit test files.
# Keeping Error (2>), Warning (3>), Verbose (4>), and Debug
# (5>) intact: those are not streamed by -StreamingHost and
# we do want them surfaced if Receive-Job hits a real problem.
$jobOutput = Receive-Job -Job $job -ErrorAction Stop 6> $null
# No host is shared with the child runspace, so replay every
# stream once the file completes.
$jobOutput = Receive-Job -Job $job -ErrorAction Stop
if ($null -ne $jobOutput) { $results += $jobOutput }
}
catch {
Expand Down