Skip to content

Commit 842ac7e

Browse files
author
Staffan Gustafsson
committed
Adding Invoke-Parallel
1 parent d19d576 commit 842ac7e

13 files changed

+1194
-0
lines changed

.gitattributes

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
###############################################################################
2+
# Set default behavior to automatically normalize line endings.
3+
###############################################################################
4+
* text=auto
5+
6+
###############################################################################
7+
# Set default behavior for command prompt diff.
8+
#
9+
# This is need for earlier builds of msysgit that does not have it on by
10+
# default for csharp files.
11+
# Note: This is only used by command line
12+
###############################################################################
13+
#*.cs diff=csharp
14+
15+
###############################################################################
16+
# Set the merge driver for project and solution files
17+
#
18+
# Merging from the command prompt will add diff markers to the files if there
19+
# are conflicts (Merging from VS is not affected by the settings below, in VS
20+
# the diff markers are never inserted). Diff markers may cause the following
21+
# file extensions to fail to load in VS. An alternative would be to treat
22+
# these files as binary and thus will always conflict and require user
23+
# intervention with every merge. To do so, just uncomment the entries below
24+
###############################################################################
25+
#*.sln merge=binary
26+
#*.csproj merge=binary
27+
#*.vbproj merge=binary
28+
#*.vcxproj merge=binary
29+
#*.vcproj merge=binary
30+
#*.dbproj merge=binary
31+
#*.fsproj merge=binary
32+
#*.lsproj merge=binary
33+
#*.wixproj merge=binary
34+
#*.modelproj merge=binary
35+
#*.sqlproj merge=binary
36+
#*.wwaproj merge=binary
37+
38+
###############################################################################
39+
# behavior for image files
40+
#
41+
# image files are treated as binary by default.
42+
###############################################################################
43+
#*.jpg binary
44+
#*.png binary
45+
#*.gif binary
46+
47+
###############################################################################
48+
# diff behavior for common document formats
49+
#
50+
# Convert binary document formats to text before diffing them. This feature
51+
# is only available from the command line. Turn it on by uncommenting the
52+
# entries below.
53+
###############################################################################
54+
#*.doc diff=astextplain
55+
#*.DOC diff=astextplain
56+
#*.docx diff=astextplain
57+
#*.DOCX diff=astextplain
58+
#*.dot diff=astextplain
59+
#*.DOT diff=astextplain
60+
#*.pdf diff=astextplain
61+
#*.PDF diff=astextplain
62+
#*.rtf diff=astextplain
63+
#*.RTF diff=astextplain

PSParallel.sln

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.23107.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PSParallel", "src\PSParallell\PSParallel.csproj", "{D660B110-98CC-456A-B0A2-ED1C3BE9A25A}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PSParallelTests", "src\PSParallelTests\PSParallelTests.csproj", "{8E181CAF-1652-46A4-82B0-D6750EE25E53}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{D660B110-98CC-456A-B0A2-ED1C3BE9A25A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{D660B110-98CC-456A-B0A2-ED1C3BE9A25A}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{D660B110-98CC-456A-B0A2-ED1C3BE9A25A}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{D660B110-98CC-456A-B0A2-ED1C3BE9A25A}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{8E181CAF-1652-46A4-82B0-D6750EE25E53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{8E181CAF-1652-46A4-82B0-D6750EE25E53}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{8E181CAF-1652-46A4-82B0-D6750EE25E53}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{8E181CAF-1652-46A4-82B0-D6750EE25E53}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
EndGlobal
+281
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Management.Automation;
5+
using System.Management.Automation.Runspaces;
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
8+
namespace PSParallelTests
9+
{
10+
[TestClass]
11+
public class InvokeParallelTests : IDisposable
12+
{
13+
readonly RunspacePool m_runspacePool;
14+
15+
public InvokeParallelTests()
16+
{
17+
var path = Path.GetDirectoryName(typeof(InvokeParallelTests).Assembly.Location);
18+
var iss = InitialSessionState.CreateDefault2();
19+
iss.ImportPSModule(new [] { $"{path}\\PSParallel.dll" });
20+
m_runspacePool = RunspaceFactory.CreateRunspacePool(iss);
21+
m_runspacePool.SetMaxRunspaces(10);
22+
m_runspacePool.Open();
23+
}
24+
[TestMethod]
25+
public void TestOutput()
26+
{
27+
PowerShell ps = PowerShell.Create();
28+
ps.RunspacePool = m_runspacePool;
29+
30+
ps.AddCommand("Invoke-Parallel")
31+
.AddParameter("Process", ScriptBlock.Create("$_* 2"))
32+
.AddParameter("ThrottleLimit", 1);
33+
var input = new PSDataCollection<int> {1,2,3,4,5};
34+
input.Complete();
35+
var output = ps.Invoke<int>(input);
36+
var sum = output.Aggregate(0, (a, b) => a + b);
37+
Assert.AreEqual(30, sum);
38+
}
39+
40+
[TestMethod]
41+
public void TestParallelOutput()
42+
{
43+
PowerShell ps = PowerShell.Create();
44+
ps.RunspacePool = m_runspacePool;
45+
46+
ps.AddCommand("Invoke-Parallel")
47+
.AddParameter("Process", ScriptBlock.Create("$_* 2"))
48+
.AddParameter("ThrottleLimit", 10);
49+
var input = new PSDataCollection<int>(Enumerable.Range(1,1000));
50+
input.Complete();
51+
var output = ps.Invoke<int>(input);
52+
var sum = output.Aggregate(0, (a, b) => a + b);
53+
Assert.AreEqual(1001000, sum);
54+
}
55+
56+
[TestMethod]
57+
public void TestVerboseOutput()
58+
{
59+
PowerShell ps = PowerShell.Create();
60+
ps.RunspacePool = m_runspacePool;
61+
ps.AddScript("$VerbosePreference='Continue'", false).Invoke();
62+
ps.Commands.Clear();
63+
ps.AddStatement()
64+
.AddCommand("Invoke-Parallel",false)
65+
.AddParameter("Process", ScriptBlock.Create("Write-Verbose $_"))
66+
.AddParameter("ThrottleLimit", 1);
67+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
68+
input.Complete();
69+
ps.Invoke<int>(input);
70+
Assert.IsFalse(ps.HadErrors, "We don't expect errors here");
71+
var vrb = ps.Streams.Verbose.ReadAll();
72+
Assert.IsTrue(vrb.Any(v=> v.Message == "1"), "Some verbose message should be '1'");
73+
}
74+
75+
[TestMethod]
76+
public void TestNoVerboseOutputWithoutPreference()
77+
{
78+
PowerShell ps = PowerShell.Create();
79+
ps.RunspacePool = m_runspacePool;
80+
ps.AddStatement()
81+
.AddCommand("Invoke-Parallel", false)
82+
.AddParameter("Process", ScriptBlock.Create("Write-Verbose $_"))
83+
.AddParameter("ThrottleLimit", 1);
84+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
85+
input.Complete();
86+
ps.Invoke<int>(input);
87+
Assert.IsFalse(ps.HadErrors, "We don't expect errors here");
88+
var vrb = ps.Streams.Verbose.ReadAll();
89+
Assert.IsFalse(vrb.Any(v => v.Message == "1"), "No verbose message should be '1'");
90+
}
91+
92+
[TestMethod]
93+
public void TestDebugOutput()
94+
{
95+
PowerShell ps = PowerShell.Create();
96+
ps.RunspacePool = m_runspacePool;
97+
ps.AddScript("$DebugPreference='Continue'", false).Invoke();
98+
ps.Commands.Clear();
99+
ps.AddStatement()
100+
.AddCommand("Invoke-Parallel", false)
101+
.AddParameter("Process", ScriptBlock.Create("Write-Debug $_"))
102+
.AddParameter("ThrottleLimit", 1);
103+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
104+
input.Complete();
105+
ps.Invoke<int>(input);
106+
Assert.IsFalse(ps.HadErrors, "We don't expect errors here");
107+
var dbg = ps.Streams.Debug.ReadAll();
108+
Assert.IsTrue(dbg.Any(d => d.Message == "1"), "Some debug message should be '1'");
109+
}
110+
111+
[TestMethod]
112+
public void TestNoDebugOutputWithoutPreference()
113+
{
114+
PowerShell ps = PowerShell.Create();
115+
ps.RunspacePool = m_runspacePool;
116+
ps.Commands.Clear();
117+
ps.AddStatement()
118+
.AddCommand("Invoke-Parallel", false)
119+
.AddParameter("Process", ScriptBlock.Create("Write-Debug $_"))
120+
.AddParameter("ThrottleLimit", 1);
121+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
122+
input.Complete();
123+
ps.Invoke<int>(input);
124+
var dbg = ps.Streams.Debug.ReadAll();
125+
Assert.IsFalse(dbg.Any(d => d.Message == "1"), "No debug message should be '1'");
126+
}
127+
128+
[TestMethod]
129+
public void TestWarningOutput()
130+
{
131+
PowerShell ps = PowerShell.Create();
132+
ps.RunspacePool = m_runspacePool;
133+
ps.AddScript("$WarningPreference='Continue'", false).Invoke();
134+
ps.Commands.Clear();
135+
ps.AddStatement()
136+
.AddCommand("Invoke-Parallel", false)
137+
.AddParameter("Process", ScriptBlock.Create("Write-Warning $_"))
138+
.AddParameter("ThrottleLimit", 1);
139+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
140+
input.Complete();
141+
ps.Invoke<int>(input);
142+
var wrn = ps.Streams.Warning.ReadAll();
143+
Assert.IsTrue(wrn.Any(w => w.Message == "1"), "Some warning message should be '1'");
144+
}
145+
146+
[TestMethod]
147+
public void TestNoWarningOutputWithoutPreference()
148+
{
149+
PowerShell ps = PowerShell.Create();
150+
ps.RunspacePool = m_runspacePool;
151+
ps.AddScript("$WarningPreference='SilentlyContinue'", false).Invoke();
152+
ps.Commands.Clear();
153+
ps.AddStatement()
154+
.AddCommand("Invoke-Parallel", false)
155+
.AddParameter("Process", ScriptBlock.Create("Write-Warning $_"))
156+
.AddParameter("ThrottleLimit", 1);
157+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
158+
input.Complete();
159+
ps.Invoke<int>(input);
160+
var wrn = ps.Streams.Warning.ReadAll();
161+
Assert.IsFalse(wrn.Any(w => w.Message == "1"), "No warning message should be '1'");
162+
}
163+
164+
165+
[TestMethod]
166+
public void TestErrorOutput()
167+
{
168+
PowerShell ps = PowerShell.Create();
169+
ps.RunspacePool = m_runspacePool;
170+
ps.AddScript("$ErrorActionPreference='Continue'", false).Invoke();
171+
ps.Commands.Clear();
172+
ps.AddStatement()
173+
.AddCommand("Invoke-Parallel", false)
174+
.AddParameter("Process", ScriptBlock.Create("Write-Error -Message $_ -TargetObject $_"))
175+
.AddParameter("ThrottleLimit", 1);
176+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
177+
input.Complete();
178+
ps.Invoke<int>(input);
179+
var err = ps.Streams.Error.ReadAll();
180+
Assert.IsTrue(err.Any(e => e.Exception.Message == "1"), "Some warning message should be '1'");
181+
}
182+
183+
[TestMethod]
184+
public void TestNoErrorOutputWithoutPreference()
185+
{
186+
PowerShell ps = PowerShell.Create();
187+
ps.RunspacePool = m_runspacePool;
188+
ps.AddScript("$ErrorActionPreference='SilentlyContinue'", false).Invoke();
189+
ps.Commands.Clear();
190+
ps.AddStatement()
191+
.AddCommand("Invoke-Parallel", false)
192+
.AddParameter("Process", ScriptBlock.Create("Write-Error -message $_ -TargetObject $_"))
193+
.AddParameter("ThrottleLimit", 1);
194+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
195+
input.Complete();
196+
ps.Invoke<int>(input);
197+
var err = ps.Streams.Error.ReadAll();
198+
Assert.IsFalse(err.Any(e => e.Exception.Message == "1"), "No Error message should be '1'");
199+
}
200+
201+
[TestMethod]
202+
public void TestBinaryExpressionVariableCapture()
203+
{
204+
PowerShell ps = PowerShell.Create();
205+
ps.RunspacePool = m_runspacePool;
206+
ps.AddScript("[int]$x=10", false).Invoke();
207+
ps.Commands.Clear();
208+
ps.AddStatement()
209+
.AddCommand("Invoke-Parallel", false)
210+
.AddParameter("Process", ScriptBlock.Create("$x -eq 10"))
211+
.AddParameter("ThrottleLimit", 1)
212+
.AddParameter("InputObject", 1);
213+
214+
var result = ps.Invoke<bool>().First();
215+
Assert.IsTrue(result);
216+
}
217+
218+
[TestMethod]
219+
public void TestAssingmentExpressionVariableCapture()
220+
{
221+
PowerShell ps = PowerShell.Create();
222+
ps.RunspacePool = m_runspacePool;
223+
ps.AddScript("[int]$x=10;", false).Invoke();
224+
ps.Commands.Clear();
225+
ps.AddStatement()
226+
.AddCommand("Invoke-Parallel", false)
227+
.AddParameter("Process", ScriptBlock.Create("$y = $x * 5; $y"))
228+
.AddParameter("ThrottleLimit", 1)
229+
.AddParameter("InputObject", 1);
230+
231+
var result = ps.Invoke<int>().First();
232+
Assert.AreEqual(50, result);
233+
}
234+
235+
[TestMethod]
236+
public void TestProgressOutput()
237+
{
238+
PowerShell ps = PowerShell.Create();
239+
ps.RunspacePool = m_runspacePool;
240+
241+
ps.AddStatement()
242+
.AddCommand("Invoke-Parallel", false)
243+
.AddParameter("Process", ScriptBlock.Create("Write-Progress -activity 'Test' -Status 'Status' -currentoperation $_"))
244+
.AddParameter("ThrottleLimit", 1);
245+
246+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
247+
input.Complete();
248+
ps.Invoke(input);
249+
var progress = ps.Streams.Progress.ReadAll();
250+
Assert.AreEqual(11, progress.Count(pr=>pr.Activity == "Invoke-Parallel" || pr.Activity == "Test"));
251+
}
252+
253+
254+
[TestMethod]
255+
public void TestNoProgressOutput()
256+
{
257+
PowerShell ps = PowerShell.Create();
258+
ps.RunspacePool = m_runspacePool;
259+
260+
ps.AddStatement()
261+
.AddCommand("Invoke-Parallel", false)
262+
.AddParameter("Process", ScriptBlock.Create("Write-Progress -activity 'Test' -Status 'Status' -currentoperation $_"))
263+
.AddParameter("ThrottleLimit", 1)
264+
.AddParameter("NoProgress");
265+
266+
var input = new PSDataCollection<int> { 1, 2, 3, 4, 5 };
267+
input.Complete();
268+
ps.Invoke(input);
269+
var progress = ps.Streams.Progress.ReadAll();
270+
Assert.IsFalse( progress.Any(pr=>pr.Activity == "Invoke-Parallel"));
271+
Assert.AreEqual(5, progress.Count(pr=>pr.Activity == "Test"));
272+
}
273+
274+
275+
276+
public void Dispose()
277+
{
278+
m_runspacePool.Dispose();
279+
}
280+
}
281+
}

0 commit comments

Comments
 (0)