tests/functions/runspace/end-to-end.Tests.ps1
|
Describe "Testing the End-To-End Runspace Workflows" -Tag "CI", "Pipeline", "Inegration" { BeforeEach { & (Get-Module PSFramework) { $script:runspaceWorkflows = @{ } } } AfterEach { Get-PSFRunspaceWorkflow | Remove-PSFRunspaceWorkflow & (Get-Module PSFramework) { $script:runspaceWorkflows = @{ } } } It "Should pass through input to output" { $workflow = New-PSFRunspaceWorkflow -Name "Test" $null = $workflow | Add-PSFRunspaceWorker -Name Node1 -InQueue Q1 -OutQueue Q2 -Count 1 -ScriptBlock { param ($Value) $Value } $null = $workflow | Add-PSFRunspaceWorker -Name Node2 -InQueue Q2 -OutQueue Q3 -Count 1 -ScriptBlock { $_ } $null = $workflow | Add-PSFRunspaceWorker -Name Node3 -InQueue Q3 -OutQueue Q4 -Count 1 -ScriptBlock { param ($Value) $Value } 1..10 | ForEach-Object { Write-PSFRunspaceQueue -Name Q1 -Value $_ -InputObject $workflow } $workflow | Start-PSFRunspaceWorkflow Start-Sleep -Seconds 1 $results = Read-PSFRunspaceQueue -InputObject $workflow -Name Q4 -All $results.Count | Should -Be 10 ($results | Measure-Object -Sum).Sum | Should -Be 55 } It "Should pass through input to output with V2 Workers" { $workflow = New-PSFRunspaceWorkflow -Name "Test V2" $workflow | Add-PSFRunspaceWorker -Name Node1 -InQueue Q1 -OutQueue Q2 -Count 1 -ScriptBlock { param ($Value) $Value } -WorkerVersion 2 $workflow | Add-PSFRunspaceWorker -Name Node2 -InQueue Q2 -OutQueue Q3 -Count 1 -ScriptBlock { $_ } -WorkerVersion 2 $workflow | Add-PSFRunspaceWorker -Name Node3 -InQueue Q3 -OutQueue Q4 -Count 1 -ScriptBlock { param ($Value) $Value } -WorkerVersion 2 1..10 | ForEach-Object { Write-PSFRunspaceQueue -Name Q1 -Value $_ -InputObject $workflow } $workflow | Start-PSFRunspaceWorkflow Start-Sleep -Seconds 1 $results = Read-PSFRunspaceQueue -InputObject $workflow -Name Q4 -All $results.Count | Should -Be 10 ($results | Measure-Object -Sum).Sum | Should -Be 55 } It "Should Respect per-item timeouts" { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -ScriptBlock { Write-PSFMessage "Start" Start-Sleep -Seconds $_ Write-PSFMessage "Done" $_ } -CloseOutQueue -Timeout '3s' -TimeoutType 'Start' $workflow | Write-PSFRunspaceQueue -Name Input -BulkValues (1..5) -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage $results | Should -Be 1, 2 $worker.Errors | Should -HaveCount 3 $messages | Should -HaveCount 7 $messages | Where-Object Message -EQ Done | Should -HaveCount 2 $messages | Where-Object Message -EQ Start | Should -HaveCount 5 $($worker.Errors)[0].Error.ToString() | Should -Be 'Workitem timed out! ExampleWorkflow>Processing>0: 3' $($worker.Errors)[1].Error.ToString() | Should -Be 'Workitem timed out! ExampleWorkflow>Processing>0: 4' $($worker.Errors)[2].Error.ToString() | Should -Be 'Workitem timed out! ExampleWorkflow>Processing>0: 5' } It "Should Respect Idle Timeouts - Expired" { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -ScriptBlock { Write-PSFMessage "Start" Start-Sleep -Seconds 3 Write-PSFMessage "Done" $_ } -CloseOutQueue -Timeout '2s' -TimeoutType 'Idle' $workflow | Write-PSFRunspaceQueue -Name Input -Value 1 -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage $results | Should -BeNullOrEmpty $worker.Errors | Should -HaveCount 1 $messages | Should -HaveCount 1 $messages | Where-Object Message -EQ Done | Should -HaveCount 0 $messages | Where-Object Message -EQ Start | Should -HaveCount 1 $($worker.Errors)[0].Error.ToString() | Should -Be 'Workitem timed out! ExampleWorkflow>Processing>0: 1' } It "Should Respect Idle Timeouts - Worked" { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -ScriptBlock { Write-PSFMessage "Start" Start-Sleep -Seconds 1 Write-PSFMessage "Processing" Start-Sleep -Seconds 1 Write-PSFMessage "Processing" Start-Sleep -Seconds 1 Write-PSFMessage "Done" $_ } -CloseOutQueue -Timeout '2s' -TimeoutType 'Idle' $workflow | Write-PSFRunspaceQueue -Name Input -Value 1 -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage $results | Should -Be 1 $worker.Errors | Should -HaveCount 0 $messages | Should -HaveCount 4 $messages | Where-Object Message -EQ Start | Should -HaveCount 1 $messages | Where-Object Message -EQ Processing | Should -HaveCount 2 $messages | Where-Object Message -EQ Done | Should -HaveCount 1 } It "Should retry as configured" { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -ScriptBlock { Write-PSFMessage "Start" 1 / 0 Write-PSFMessage "Done" $_ } -CloseOutQueue -RetryCount 3 $workflow | Write-PSFRunspaceQueue -Name Input -Value 1 -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage $results | Should -BeNullOrEmpty $worker.Errors | Should -HaveCount 1 $messages | Should -HaveCount 4 $messages | Where-Object Message -EQ Start | Should -HaveCount 4 $messages | Where-Object Message -EQ Done | Should -HaveCount 0 $($worker.Errors)[0].Error.ToString() | Should -Be 'Attempted to divide by zero.' } Context "Should retry as configured and applicable" { BeforeAll { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -Scriptblock { Write-PSFMessage "Start: $_" 1 / 0 Write-PSFMessage "Done: $_" $_ } -CloseOutQueue -RetryCount 3 -RetryCondition { $this -eq 1 } $workflow | Write-PSFRunspaceQueue -Name Input -BulkValues 1, 2 -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage } It "Should have no results" { $results | Should -BeNullOrEmpty } It "Should have failed twice and correctly" { $worker.Errors | Should -HaveCount 2 $($worker.Errors)[0].Error.ToString() | Should -Be 'Attempted to divide by zero.' $($worker.Errors)[1].Error.ToString() | Should -Be 'Attempted to divide by zero.' } It "Should have generated 5 messages, none completed" { $messages | Should -HaveCount 5 $messages | Where-Object Message -EQ 'Start: 1' | Should -HaveCount 4 $messages | Where-Object Message -EQ 'Start: 2' | Should -HaveCount 1 $messages | Where-Object Message -EQ Done | Should -HaveCount 0 } } Context "Should execute Begin, Process, and End correctly V1" { BeforeAll { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -Begin { Write-PSFMessage "Beginning" } -Scriptblock { Write-PSFMessage "Processing: $_" $_ } -End { Write-PSFMessage "Ending" } -CloseOutQueue $workflow | Write-PSFRunspaceQueue -Name Input -BulkValues (1..5) -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage } It "Should have 5 result numbers - 1, 2, 3, 4, 5" { $results | Should -Be 1, 2, 3, 4, 5 $results | Should -HaveCount 5 } It "Should have executed without errors" { $worker.Errors | Should -HaveCount 0 } It "Should have the expected 7 Messages" { $messages | Should -HaveCount 7 $messages | Where-Object Message -EQ 'Beginning' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 1' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 2' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 3' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 4' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 5' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Ending' | Should -HaveCount 1 } It "Should have executed in the same Agent Runspace" { $messages | Group-Object Runspace | Should -HaveCount 1 $messages | Where-Object Runspace -EQ ([runspace]::DefaultRunspace.InstanceId) | Should -HaveCount 0 } } Context "Should execute Begin, Process, and End correctly V2" { BeforeAll { Clear-PSFMessage $workflow = New-PSFRunspaceWorkflow -Name 'ExampleWorkflow' $worker = $workflow | Add-PSFRunspaceWorker -Name Processing -InQueue Input -OutQueue Done -Count 1 -Begin { Write-PSFMessage "Beginning" } -Scriptblock { Write-PSFMessage "Processing: $_" $_ } -End { Write-PSFMessage "Ending" } -CloseOutQueue -WorkerVersion 2 $workflow | Write-PSFRunspaceQueue -Name Input -BulkValues (1..5) -Close $workflow | Start-PSFRunspaceWorkflow $workflow | Wait-PSFRunspaceWorkflow -Queue Done -Closed -PassThru -Timeout '1m' | Stop-PSFRunspaceWorkflow $results = $workflow | Read-PSFRunspaceQueue -Name Done -All $workflow | Remove-PSFRunspaceWorkflow $messages = Get-PSFMessage } It "Should have 5 result numbers - 1, 2, 3, 4, 5" { $results | Should -Be 1, 2, 3, 4, 5 $results | Should -HaveCount 5 } It "Should have executed without errors" { $worker.Errors | Should -HaveCount 0 } It "Should have the expected 7 Messages" { $messages | Should -HaveCount 7 $messages | Where-Object Message -EQ 'Beginning' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 1' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 2' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 3' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 4' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Processing: 5' | Should -HaveCount 1 $messages | Where-Object Message -EQ 'Ending' | Should -HaveCount 1 } It "Should have executed in the same Agent Runspace" { $messages | Group-Object Runspace | Should -HaveCount 1 $messages | Where-Object Runspace -EQ ([runspace]::DefaultRunspace.InstanceId) | Should -HaveCount 0 } } } |