254 lines
8.6 KiB
PowerShell
254 lines
8.6 KiB
PowerShell
. $PSScriptRoot\..\..\Load-PesterModules.ps1
|
|
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
|
|
$functionPath = Join-Path -Path $here -ChildPath $sut
|
|
Write-Host "Overriding SUT: $functionPath"
|
|
Import-Module $functionPath -Force
|
|
$moduleForMock = ""
|
|
|
|
Describe 'Invoke-Parallel2' {
|
|
|
|
Context 'Ensure Correctness - Batched Parallelism' {
|
|
It 'Returns Correct Results' {
|
|
$numbers = 1..50
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
# Make sure it has the right number of results.
|
|
$results.Count | Should -Be 50
|
|
|
|
# Make sure it returned all of the right results.
|
|
# The sum of 1-50 is 1275
|
|
$sum = 0
|
|
foreach($result in $results.Result) {
|
|
$sum += $result
|
|
}
|
|
$sum | Should -Be 1275
|
|
}
|
|
|
|
It 'Handles Zero Items' {
|
|
$numbers = $null
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results | Should -Be $null
|
|
}
|
|
|
|
It 'Handles One Item' {
|
|
$numbers = @(1)
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Result | Should -Be 1
|
|
}
|
|
|
|
It 'Handles ThreadCount -gt NumObjects' {
|
|
$numbers = 1..8
|
|
$numThreads = 400
|
|
$results = Invoke-Parallel2 -objects $numbers -numThreads $numThreads -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Count | Should -Be 8
|
|
}
|
|
|
|
It 'Handles Odd Thread Division' {
|
|
$numbers = 1..8
|
|
$numThreads = 3
|
|
$results = Invoke-Parallel2 -objects $numbers -numThreads $numThreads -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Count | Should -Be 8
|
|
}
|
|
|
|
It 'Handles Jobless Last Thread' {
|
|
# This is an edge case where Ceil(21 items / 8 threads) is rounded up to 3 items per thread.
|
|
# 7*3 == 21, which means the last thread at 8 threads doesn't have any work to do.
|
|
# There isn't a more fair way to divy up the work between the threads.
|
|
# Arbitrarily giving the 8th thread work from the 7th thread won't help in theory.
|
|
$numbers = @(1..21)
|
|
$numThreads = 8
|
|
$results = Invoke-Parallel2 -objects $numbers -numThreads $numThreads -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Count | Should -Be 21
|
|
}
|
|
}
|
|
|
|
Context 'Ensure Correctness - Thread Per Object Parallelism' {
|
|
It 'Returns Correct Results' {
|
|
$numbers = 1..6
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
# Make sure it has the right number of results.
|
|
$results.Count | Should -Be 6
|
|
|
|
# Make sure it returned all of the right results.
|
|
# The sum of 1-6 is 21
|
|
$sum = 0
|
|
foreach($result in $results.Result) {
|
|
$sum += $result
|
|
}
|
|
$sum | Should -Be 21
|
|
}
|
|
|
|
It 'Handles Zero Items' {
|
|
$numbers = $null
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results | Should -Be $null
|
|
}
|
|
|
|
It 'Handles One Item' {
|
|
$numbers = @(1)
|
|
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Result | Should -Be 1
|
|
}
|
|
|
|
It 'Handles ThreadCount -gt NumObjects' {
|
|
$numbers = 1..8
|
|
$numThreads = 400
|
|
$results = Invoke-Parallel2 -objects $numbers -numThreads $numThreads -threadPerObject -script {
|
|
param($number)
|
|
return $number
|
|
}
|
|
|
|
$results.Count | Should -Be 8
|
|
}
|
|
}
|
|
|
|
Context 'Ensure Correctness - Thread Per Object Error Handling' {
|
|
|
|
It 'Returns Error Results' {
|
|
|
|
$numbers = 1..4
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -ErrorAction SilentlyContinue -script {
|
|
param($number)
|
|
throw "Failure!"
|
|
}
|
|
|
|
# All of the results should fail, and contain the correct error.
|
|
$badResults = $results | Where-Object { $_.Success -eq $false }
|
|
$badResults.Count | Should -Be 4
|
|
for($i = 0; $i -lt 4; $i++) {
|
|
$badResults[$i].Error | Should -Be "Failure!"
|
|
}
|
|
}
|
|
|
|
It 'Returns All Results When ContinueOnFailure is True' {
|
|
|
|
$numbers = 1..4
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -numThreads 1 -ErrorAction SilentlyContinue -script {
|
|
param($number)
|
|
throw "Failure!"
|
|
}
|
|
|
|
# All of the results should fail, and contain the correct error.
|
|
$badResults = $results | Where-Object { $_.Success -eq $false }
|
|
$badResults.Count | Should -Be 4
|
|
for($i = 0; $i -lt 4; $i++) {
|
|
$badResults[$i].Error | Should -Be "Failure!"
|
|
}
|
|
}
|
|
|
|
|
|
It 'Returns One Result With StopProcessingJobsOnError' {
|
|
$numbers = 1..4
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -numThreads 1 -ErrorAction SilentlyContinue -StopProcessingJobsOnError -script {
|
|
param($number)
|
|
throw "Failure!"
|
|
}
|
|
|
|
# Only one result should be returned because we are at a parallelism of 1, and we are -not- continuing on error.
|
|
[array]$badResults = $results | Where-Object { $_.Success -eq $false }
|
|
$badResults.Count | Should -Be 1
|
|
$badResults.Error | Should -Be "Failure!"
|
|
}
|
|
|
|
It 'Returns Outstanding Thread Results and Doesnt Create More' {
|
|
$numbers = 1..6
|
|
$results = Invoke-Parallel2 -objects $numbers -threadPerObject -numThreads 3 -ErrorAction SilentlyContinue -StopProcessingJobsOnError -script {
|
|
param($number)
|
|
|
|
if($number -eq 1) {
|
|
throw "Failure!"
|
|
} else {
|
|
# Make sure the other non-failing results take a little time, so that more jobs are not spawned.
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
}
|
|
|
|
[array]$goodResults = $results | Where-Object { $_.Success -eq $true }
|
|
[array]$badResults = $results | Where-Object { $_.Success -eq $false }
|
|
|
|
# We should have 3 results.
|
|
# .. because we are at a parallelism of 3 jobs (out of 6 objects)
|
|
# .. and one of them fails. Two should succeed, one should fail, and we should not create any more jobs.
|
|
$results.Count | Should -Be 3
|
|
$goodResults.Count | Should -Be 2
|
|
$badResults.Count | Should -Be 1
|
|
}
|
|
}
|
|
|
|
Context 'Ensure Correctness - Batched Error Handling' {
|
|
|
|
It 'Returns Success Results' {
|
|
|
|
$numbers = 1..4
|
|
$results = Invoke-Parallel2 -objects $numbers -ErrorAction SilentlyContinue -script {
|
|
param($number)
|
|
# Do nothing. All good.
|
|
}
|
|
|
|
# All of the results should fail, and contain the correct error.
|
|
$goodResults = $results | Where-Object { $_.Success -eq $true }
|
|
$goodResults.Count | Should -Be 4
|
|
for($i = 0; $i -lt 4; $i++) {
|
|
$goodResults[$i].Error | Should -Be $null
|
|
}
|
|
}
|
|
|
|
It 'Returns All Results When There is Failure' {
|
|
|
|
$numbers = 1..4
|
|
$results = Invoke-Parallel2 -objects $numbers -numThreads 1 -ErrorAction SilentlyContinue -script {
|
|
param($number)
|
|
throw "Failure!"
|
|
}
|
|
|
|
# All of the results should fail, and contain the correct error.
|
|
$badResults = $results | Where-Object { $_.Success -eq $false }
|
|
$badResults.Count | Should -Be 4
|
|
for($i = 0; $i -lt 4; $i++) {
|
|
$badResults[$i].Error | Should -Be "Failure!"
|
|
}
|
|
}
|
|
}
|
|
} |