Skip to content

Commit aa41df2

Browse files
authored
Merge pull request #29 from santisq/25-update-pester-tests-for-v116
Closes #25
2 parents a4b2d74 + a9f0ac9 commit aa41df2

File tree

6 files changed

+190
-95
lines changed

6 files changed

+190
-95
lines changed

src/PSParallelPipeline/Commands/InvokeParallelCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ private void ProcessOutput(PSOutputData data)
166166
WriteVerbose((string)data.Output);
167167
break;
168168

169-
case Type.Wraning:
169+
case Type.Warning:
170170
WriteWarning((string)data.Output);
171171
break;
172172
}

src/PSParallelPipeline/PSOutputStreams.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ internal sealed class PSOutputStreams : IDisposable
2323

2424
internal PSDataCollection<VerboseRecord> Verbose { get; } = [];
2525

26-
internal PSDataCollection<WarningRecord> Wraning { get; } = [];
26+
internal PSDataCollection<WarningRecord> Warning { get; } = [];
2727

2828
private readonly Worker _worker;
2929

@@ -86,11 +86,11 @@ private static void SetStreams(PSOutputStreams outputStreams)
8686
}
8787
};
8888

89-
outputStreams.Wraning.DataAdded += (s, e) =>
89+
outputStreams.Warning.DataAdded += (s, e) =>
9090
{
91-
foreach (WarningRecord warning in outputStreams.Wraning.ReadAll())
91+
foreach (WarningRecord warning in outputStreams.Warning.ReadAll())
9292
{
93-
outputStreams.AddOutput(new PSOutputData(Type.Wraning, warning.Message));
93+
outputStreams.AddOutput(new PSOutputData(Type.Warning, warning.Message));
9494
}
9595
};
9696
}

src/PSParallelPipeline/PSTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ private static void HookStreams(PSTask ps, PSOutputStreams outputStreams)
4444
ps._streams.Information = outputStreams.Information;
4545
ps._streams.Progress = outputStreams.Progress;
4646
ps._streams.Verbose = outputStreams.Verbose;
47-
ps._streams.Warning = outputStreams.Wraning;
47+
ps._streams.Warning = outputStreams.Warning;
4848
}
4949

5050
private static Task InvokePowerShellAsync(

src/PSParallelPipeline/Records.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal enum Type
1111
Information,
1212
Progress,
1313
Verbose,
14-
Wraning
14+
Warning
1515
}
1616

1717
internal record struct PSOutputData(Type Type, object Output);

tests/PSParallelPipeline.tests.ps1

Lines changed: 183 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,241 @@
1-
$moduleName = (Get-Item ([IO.Path]::Combine($PSScriptRoot, '..', 'module', '*.psd1'))).BaseName
2-
$manifestPath = [IO.Path]::Combine($PSScriptRoot, '..', 'output', $moduleName)
1+
using namespace System.IO
2+
using namespace System.Management.Automation
3+
using namespace System.Diagnostics
4+
using namespace System.Collections.Concurrent
5+
6+
$moduleName = (Get-Item ([Path]::Combine($PSScriptRoot, '..', 'module', '*.psd1'))).BaseName
7+
$manifestPath = [Path]::Combine($PSScriptRoot, '..', 'output', $moduleName)
38

49
Import-Module $manifestPath
5-
Import-Module ([System.IO.Path]::Combine($PSScriptRoot, 'common.psm1'))
10+
Import-Module ([Path]::Combine($PSScriptRoot, 'common.psm1'))
611

712
Describe PSParallelPipeline {
8-
Context 'Invoke-Parallel' -Tag 'Invoke-Parallel' {
9-
It 'Should process all pipeline input' {
10-
{ 0..10 | Invoke-Parallel { $_ } } |
11-
Should -Not -Throw
13+
Context 'Output Streams' {
14+
It 'Success' {
15+
1 | Invoke-Parallel { $_ } | Should -BeOfType ([int])
16+
1 | Invoke-Parallel { $_ } | Should -BeExactly 1
17+
}
1218

13-
$items = 0..10 | Invoke-Parallel { $_ } |
14-
Sort-Object
19+
It 'Error' {
20+
1 | Invoke-Parallel { Write-Error $_ } 2>&1 |
21+
Should -BeOfType ([ErrorRecord])
22+
}
1523

16-
$items | Should -BeExactly (0..10)
17-
$items | Should -HaveCount 11
24+
It 'Warning' {
25+
1 | Invoke-Parallel { Write-Warning $_ } 3>&1 |
26+
Should -BeOfType ([WarningRecord])
1827
}
1928

20-
It 'Should process in parallel' {
21-
$timer = [System.Diagnostics.Stopwatch]::StartNew()
22-
0..5 | Invoke-Parallel { Start-Sleep 1 } -ThrottleLimit 5
23-
$timer.Elapsed | Should -BeLessOrEqual ([timespan]::FromSeconds(5))
24-
$timer.Stop()
29+
It 'Verbose' {
30+
1 | Invoke-Parallel { Write-Verbose $_ -Verbose } -Verbose 4>&1 |
31+
Should -BeOfType ([VerboseRecord])
2532
}
2633

27-
It 'Should stop processing after a set timeout' {
28-
$timer = [System.Diagnostics.Stopwatch]::StartNew()
34+
It 'Debug' {
35+
if ($IsCoreCLR) {
36+
1 | Invoke-Parallel { Write-Debug $_ -Debug } -Debug 5>&1 |
37+
Should -BeOfType ([DebugRecord])
38+
return
39+
}
2940

30-
{ 0..5 | Invoke-Parallel { Start-Sleep 10 } -TimeoutSeconds 2 -ErrorAction Stop } |
31-
Should -Throw -ExceptionType ([System.TimeoutException])
41+
# Debug is weird in PowerShell 5.1. Needs a different test.
42+
$DebugPreference = 'Continue'
43+
1 | Invoke-Parallel { & { [CmdletBinding()]param() $PSCmdlet.WriteDebug(123) } -Debug } 5>&1 |
44+
Should -BeOfType ([DebugRecord])
45+
}
3246

33-
$timer.Elapsed | Should -BeLessOrEqual ([timespan]::FromSeconds(4))
34-
$timer.Stop()
47+
It 'Information' {
48+
1 | Invoke-Parallel { Write-Host $_ } 6>&1 |
49+
Should -BeOfType ([InformationRecord])
3550
}
3651

37-
It 'Allows $using: statements' {
38-
$message = 'Hello world from {0:D2}'
39-
$items = 0..10 | Invoke-Parallel { $using:message -f $_ } |
40-
Sort-Object
52+
It 'Progress' {
53+
$ProgressPreference = 'SilentlyContinue'
4154

42-
$items | Should -BeExactly @(
43-
0..10 | ForEach-Object { 'Hello world from {0:D2}' -f $_ }
44-
)
55+
$null | Invoke-Parallel {
56+
1..10 | ForEach-Object {
57+
Write-Progress -Activity 'Progress Output' -PercentComplete (10 * $_)
58+
Start-Sleep -Milliseconds 200
59+
}
60+
Write-Progress -Completed -Activity 'Progress Output'
61+
} | Should -BeNullOrEmpty
4562
}
63+
}
4664

47-
It 'Can make variables available through the -Variables parameter' {
48-
$invokeParallelSplat = @{
49-
Variables = @{ message = 'Hello world from {0:D2}' }
50-
ScriptBlock = { $message -f $_ }
51-
}
65+
Context 'Common Parameters' {
66+
It 'Supports ActionPreference' {
67+
{ 1 | Invoke-Parallel { Write-Error $_ } -ErrorAction Stop } |
68+
Should -Throw
5269

53-
$items = 0..10 | Invoke-Parallel @invokeParallelSplat |
54-
Sort-Object
70+
{ 1 | Invoke-Parallel { Write-Warning $_ } -WarningAction Stop 3>$null } |
71+
Should -Throw
5572

56-
$items | Should -BeExactly @(
57-
0..10 | ForEach-Object { 'Hello world from {0:D2}' -f $_ }
58-
)
73+
{ 1 | Invoke-Parallel { Write-Host $_ } -InformationAction Stop 6>$null } |
74+
Should -Throw
75+
76+
1 | Invoke-Parallel { Write-Error $_ } -ErrorAction Ignore 2>&1 |
77+
Should -BeNullOrEmpty
78+
79+
1 | Invoke-Parallel { Write-Warning $_ } -WarningAction Ignore 2>&1 |
80+
Should -BeNullOrEmpty
81+
82+
1 | Invoke-Parallel { Write-Host $_ } -InformationAction Ignore 2>&1 |
83+
Should -BeNullOrEmpty
5984
}
6085

86+
It 'Supports PipelineVariable' {
87+
1 | Invoke-Parallel { $_ } -PipelineVariable pipe |
88+
ForEach-Object { Get-Variable pipe -ValueOnly } |
89+
Should -BeExactly 1
90+
}
91+
}
92+
93+
Context 'UseNewRunspace Parameter' {
6194
It 'Should reuse runspaces by default' {
62-
0..10 | Invoke-Parallel { [runspace]::DefaultRunspace.InstanceId } -ThrottleLimit 5 |
63-
Select-Object -Unique |
95+
0..10 | Invoke-Parallel { [runspace]::DefaultRunspace } |
96+
Select-Object -ExpandProperty InstanceId -Unique |
6497
Should -HaveCount 5
6598
}
6699

67-
It 'Should use a new runspace when the -UseNewRunspace parameter is used' {
68-
0..10 | Invoke-Parallel { [runspace]::DefaultRunspace.InstanceId } -UseNewRunspace |
69-
Select-Object -Unique |
100+
It 'Should use a new runspace when the -UseNewRunspace is used' {
101+
0..10 | Invoke-Parallel { [runspace]::DefaultRunspace } -UseNewRunspace |
102+
Select-Object -ExpandProperty InstanceId -Unique |
70103
Should -HaveCount 11
71104
}
105+
}
72106

73-
It 'Can add items to a single thread instance' {
74-
$dict = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new()
75-
76-
Get-Process | Invoke-Parallel { ($using:dict).TryAdd($_.Id, $_) } |
77-
Should -Contain $true
107+
Context 'Variables Parameter' {
108+
It 'Makes variables available in the parallel scope' {
109+
$items = 0..10 | Invoke-Parallel { $message -f $_ } -Variables @{
110+
message = 'Hello world from {0:D2}'
111+
} | Sort-Object
78112

79-
$dict[$PID].ProcessName | Should -Be (Get-Process -Id $PID).ProcessName
113+
$shouldBe = 0..10 | ForEach-Object { 'Hello world from {0:D2}' -f $_ }
114+
$items | Should -BeExactly $shouldBe
80115
}
116+
}
81117

82-
It 'Should add functions to the parallel scope with -Functions parameter' {
83-
$invokeParallelSplat = @{
84-
Functions = 'Test-Function'
85-
ScriptBlock = { Test-Function $_ }
86-
}
87-
88-
0..10 | Invoke-Parallel @invokeParallelSplat |
118+
Context 'Functions Parameter' {
119+
It 'Makes functions available in the parallel scope' {
120+
0..10 | Invoke-Parallel { Test-Function $_ } -Functions Test-Function |
89121
Sort-Object |
90122
Should -BeExactly @(0..10 | ForEach-Object { Test-Function $_ })
91123
}
124+
}
92125

93-
It 'Should autocomplete existing commands in the caller scope' {
94-
$result = TabExpansion2 -inputScript ($s = 'Invoke-Parallel -Function Get-') -cursorColumn $s.Length
95-
$result.CompletionMatches.Count | Should -BeGreaterThan 0
96-
$result.CompletionMatches.ListItemText | Should -Match '^Get-'
97-
}
126+
Context 'ThrottleLimit Parameter' {
127+
It 'Defines the degree of parallelism' {
128+
Measure-Command {
129+
0..10 | Invoke-Parallel { Start-Sleep 1 }
130+
} | ForEach-Object TotalSeconds | Should -BeGreaterOrEqual 3
98131

99-
It 'Should throw a terminating error' {
100-
{ $null | Invoke-Parallel { Write-Error 'Error' } -ErrorAction Stop } |
101-
Should -Throw
132+
Measure-Command {
133+
0..10 | Invoke-Parallel { Start-Sleep 1 } -ThrottleLimit 11
134+
} | ForEach-Object TotalSeconds | Should -BeLessOrEqual 1.5
102135
}
136+
}
103137

104-
It 'Should write to the Error Stream' {
105-
$null | Invoke-Parallel { Write-Error 'Error' } 2>&1 |
106-
Should -BeOfType ([System.Management.Automation.ErrorRecord])
138+
Context 'TimeoutSeconds Parameter' {
139+
It 'Stops processing after the specified seconds' {
140+
$timer = [Stopwatch]::StartNew()
141+
{ 0..5 | Invoke-Parallel { Start-Sleep 10 } -TimeoutSeconds 2 -ErrorAction Stop } |
142+
Should -Throw -ExceptionType ([TimeoutException])
143+
$timer.Stop()
144+
$timer.Elapsed | Should -BeLessOrEqual ([timespan]::FromSeconds(2.1))
107145
}
146+
}
147+
148+
Context 'CommandCompleter' {
149+
It 'Should autocomplete existing commands in the caller scope' {
150+
Complete 'Invoke-Parallel -Functions Compl' |
151+
Should -Not -BeNullOrEmpty
108152

109-
It 'Should throw if passing a scriptblock with using: scope modifier' {
110-
{
111-
$sb = { }
112-
1..1 | Invoke-Parallel { $using:sb }
113-
} | Should -Throw
153+
Complete 'Invoke-Parallel -Functions Compl' |
154+
ForEach-Object ListItemText |
155+
Should -Contain 'Complete'
114156
}
157+
}
115158

116-
It 'Should throw if passing a scriptblock with the -Variables parameter' {
117-
{
118-
$sb = { }
119-
1..1 | Invoke-Parallel { $sb } -Variables @{ sb = $sb }
120-
} | Should -Throw
159+
Context '$using: keyword Support' {
160+
It 'Allows passed-in variables through $using: keyword' {
161+
$message = 'Hello world from {0:D2}'
162+
$items = 0..10 | Invoke-Parallel { $using:message -f $_ } |
163+
Sort-Object
164+
165+
$shouldBe = 0..10 | ForEach-Object { 'Hello world from {0:D2}' -f $_ }
166+
$items | Should -BeExactly $shouldBe
121167
}
122168

123-
It 'Allows indexing on using: statements' {
169+
It 'Allows indexing on $using: passed-in variables' {
124170
$arr = 0..10; $hash = @{ foo = 'bar' }
125171
1 | Invoke-Parallel { $using:arr[-1] } | Should -BeExactly 10
126172
1 | Invoke-Parallel { $using:hash['FOO'] } | Should -BeExactly 'bar'
127173
}
128174

129-
It 'Allows member accessing on using: statemets' {
175+
It 'Allows member access on $using: passed-in variables' {
130176
$hash = @{
131177
foo = @{
132178
bar = [pscustomobject]@{ Index = 0..10 }
133179
}
134180
}
135181

136-
1 | Invoke-Parallel { $using:hash['foo']['bar'].Index[5] } | Should -BeExactly 5
182+
1 | Invoke-Parallel { $using:hash['foo']['bar'].Index[5] } |
183+
Should -BeExactly 5
184+
}
185+
}
186+
187+
Context 'Script Block Assertions' {
188+
It 'Should throw on passed-in Script Block via $using: keyword' {
189+
{ $sb = { }; 1..1 | Invoke-Parallel { $using:sb } } |
190+
Should -Throw -ExceptionType ([PSArgumentException])
191+
}
192+
193+
It 'Should throw on passed-in Script Block via -Variables parameter' {
194+
{ $sb = { }; 1..1 | Invoke-Parallel { $sb } -Variables @{ sb = $sb } } |
195+
Should -Throw -ExceptionType ([PSArgumentException])
196+
}
197+
198+
It 'Should throw on passed-in Script Block via input object' {
199+
{ { 1 + 1 } | Invoke-Parallel { & $_ } } |
200+
Should -Throw -ExceptionType ([PSArgumentException])
201+
}
202+
}
203+
204+
Context 'Invoke-Parallel' {
205+
It 'Process in parallel' {
206+
$timer = [Stopwatch]::StartNew()
207+
1..5 | Invoke-Parallel { Start-Sleep 1 }
208+
$timer.Stop()
209+
$timer.Elapsed | Should -BeLessOrEqual ([timespan]::FromSeconds(1.5))
210+
}
211+
212+
It 'Supports streaming output' {
213+
Measure-Command {
214+
0..10 | Invoke-Parallel {
215+
0..10 | ForEach-Object {
216+
Start-Sleep 1
217+
$_
218+
}
219+
} | Select-Object -First 5 |
220+
Should -HaveCount 5
221+
} | ForEach-Object TotalSeconds |
222+
Should -BeLessThan 2
223+
224+
Measure-Command {
225+
0..10 | Invoke-Parallel { Start-Sleep 1; $_ } -ThrottleLimit 2 |
226+
Select-Object -First 10 |
227+
Should -HaveCount 10
228+
} | ForEach-Object TotalSeconds |
229+
Should -BeLessThan 6
230+
}
231+
232+
It 'Can add items to a single thread instance' {
233+
$dict = [ConcurrentDictionary[string, object]]::new()
234+
235+
Get-Process | Invoke-Parallel { ($using:dict).TryAdd($_.Id, $_) } |
236+
Should -Contain $true
237+
238+
$dict[$PID].ProcessName | Should -Be (Get-Process -Id $PID).ProcessName
137239
}
138240
}
139241
}

tests/common.psm1

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,3 @@ function Complete {
1515
$null).CompletionMatches
1616
}
1717
}
18-
19-
function Test-Completer {
20-
param(
21-
[ArgumentCompleter([PSParallelPipeline.CommandCompleter])]
22-
[string] $Test
23-
)
24-
}

0 commit comments

Comments
 (0)