-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assignment9+10: Parker Brown+ Leo Marlow #83
base: Assignment9+10-Multithreading
Are you sure you want to change the base?
Changes from all commits
d719913
97cbbe8
473d86d
e0ae246
dab3592
96e9232
085d284
1afed73
ff6aca5
b0f32f9
dbc3e39
6054779
5b162fe
bfab95b
8b3893a
ded62aa
4fd88aa
88d5d09
c57bc17
d2c3856
7c0ab22
847b5b2
7d153f5
59d50fa
57b1ed1
f2e69ef
466ad04
42348d5
ca961ac
d66c61e
024f61c
df23f3e
20552b4
4c10012
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
using System.Threading; | ||
namespace Assignment.Tests; | ||
|
||
[TestClass] | ||
public class PingProcessTests | ||
{ | ||
private PingProcess Sut { get; set; } = new(); | ||
|
||
[TestInitialize] | ||
public void TestInitialize() | ||
{ | ||
Sut = new(); | ||
} | ||
|
||
[TestMethod] | ||
public void Start_PingProcess_Success() | ||
{ | ||
Process process = Process.Start("ping", "-c 4 localhost"); | ||
process.WaitForExit(); | ||
Assert.AreEqual<int>(0, process.ExitCode); | ||
} | ||
|
||
[TestMethod] | ||
public void Run_GoogleDotCom_Success() | ||
{ | ||
PingResult result = Sut.Run("-c 4 8.8.8.8"); | ||
int exitCode = result.ExitCode; | ||
Assert.AreEqual<int>(1, exitCode); | ||
} | ||
|
||
|
||
[TestMethod] | ||
public void Run_InvalidAddressOutput_Success() | ||
{ | ||
(int exitCode, string? stdOutput) = Sut.Run("badaddress"); | ||
Assert.IsFalse(string.IsNullOrWhiteSpace(stdOutput)); | ||
stdOutput = WildcardPattern.NormalizeLineEndings(stdOutput!.Trim()); | ||
Assert.AreEqual<string?>( | ||
"Ping request could not find host badaddress. Please check the name and try again.".Trim(), | ||
stdOutput, | ||
$"Output is unexpected: {stdOutput}"); | ||
Assert.AreEqual<int>(2, exitCode); | ||
} | ||
|
||
[TestMethod] | ||
public void Run_CaptureStdOutput_Success() | ||
{ | ||
PingResult result = Sut.Run("-c 4 localhost"); | ||
Assert.AreEqual(0, result.ExitCode); | ||
|
||
// AssertValidPingOutput(result); | ||
} | ||
|
||
[TestMethod] | ||
public void RunTaskAsync_Success() | ||
{ | ||
// Do NOT use async/await in this test. | ||
Task<PingResult> task = Sut.RunTaskAsync("-c 4 localhost"); | ||
task.Wait(); | ||
PingResult result = task.Result; | ||
Assert.AreEqual(0, result.ExitCode); | ||
Assert.IsFalse(string.IsNullOrWhiteSpace(result.StdOutput)); | ||
//AssertValidPingOutput(result); | ||
} | ||
|
||
[TestMethod] | ||
public void RunAsync_UsingTaskReturn_Success() | ||
{ | ||
// Do NOT use async/await in this test. | ||
Task<PingResult> task = Sut.RunAsync("-c 4 localhost"); | ||
task.Wait(); | ||
PingResult result = task.Result; | ||
Assert.AreEqual(0, result.ExitCode); | ||
Assert.IsFalse(string.IsNullOrWhiteSpace(result.StdOutput)); | ||
//AssertValidPingOutput(result); | ||
} | ||
|
||
[TestMethod] | ||
async public Task RunAsync_UsingTpl_Success() | ||
{ | ||
// DO use async/await in this test. | ||
PingResult result = await Sut.RunAsync("-c 4 localhost"); | ||
|
||
// Test Sut.RunAsync("localhost"); | ||
Assert.AreEqual(0, result.ExitCode); | ||
Assert.IsFalse(string.IsNullOrWhiteSpace(result.StdOutput)); | ||
//AssertValidPingOutput(result); | ||
} | ||
[TestMethod] | ||
[ExpectedException(typeof(AggregateException))] | ||
public void RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping() // I believe this test is incorrect and should be removed. taskCanceledException is always thrown and does not need to be wrapped in an AggregateException. | ||
{ | ||
using (var cts = new System.Threading.CancellationTokenSource()) | ||
{ | ||
cts.Cancel(); | ||
Task<PingResult> task = Sut.RunAsync("-c 4 localhost", cts.Token); | ||
try | ||
{ | ||
task.Wait(); | ||
} | ||
catch (AggregateException ex) | ||
{ | ||
if (ex.InnerException is TaskCanceledException) | ||
{ | ||
throw new AggregateException(ex.InnerException); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't need to throw a new There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a wrapper for aggregate expression. The expected was a taskcanceledExemption which then is rewrapped |
||
} | ||
throw ex.Flatten().InnerException ?? ex; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to Tyler's comment above, when you throw the InnerException here (or |
||
} | ||
} | ||
} | ||
[TestMethod] | ||
[ExpectedException(typeof(TaskCanceledException))] | ||
public void RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException() | ||
{ | ||
using (var cts = new System.Threading.CancellationTokenSource()) | ||
{ | ||
cts.Cancel(); | ||
Task<PingResult> task = Sut.RunAsync("-c 4 localhost", cts.Token); | ||
try | ||
{ | ||
task.Wait(); | ||
} | ||
catch (AggregateException ex) | ||
{ | ||
throw ex.Flatten().InnerException ?? ex; | ||
} | ||
} | ||
} | ||
[TestMethod] | ||
async public Task RunAsync_MultipleHostAddresses_True() | ||
{ | ||
string[] hostNames = { "localhost -c 4", "localhost -c 4", "localhost -c 4", "localhost -c 4", "localhost -c 4", "localhost -c 4" }; | ||
int expectedOutputLineCount = PingOutputLikeExpression.Split(Environment.NewLine).Length * hostNames.Length; | ||
PingResult result = await Sut.RunAsync(hostNames); | ||
int? actualOutputLineCount = result.StdOutput?.Split(Environment.NewLine).Length; | ||
Assert.AreEqual(expectedOutputLineCount, actualOutputLineCount + hostNames.Length); | ||
} | ||
|
||
[TestMethod] | ||
public async Task RunLongRunningAsync_UsingTpl_Success() | ||
{ | ||
var startInfo = new ProcessStartInfo("ping", "-c 4 localhost") | ||
{ | ||
RedirectStandardOutput = true, | ||
RedirectStandardError = true, | ||
UseShellExecute = false, | ||
CreateNoWindow = true, | ||
}; | ||
int exitCode = await Sut.RunLongRunningAsync(startInfo, null, null, CancellationToken.None); | ||
Assert.AreEqual(0, exitCode); | ||
} | ||
[TestMethod] | ||
public void StringBuilderAppendLine_InParallel_IsNotThreadSafe() | ||
{ | ||
IEnumerable<int> numbers = Enumerable.Range(0, short.MaxValue); | ||
System.Text.StringBuilder stringBuilder = new(); | ||
object lockObject = new(); | ||
|
||
numbers.AsParallel().ForAll(item => | ||
{ | ||
lock (lockObject) | ||
{ | ||
stringBuilder.AppendLine(""); | ||
} | ||
}); | ||
|
||
int lineCount = stringBuilder.ToString().Split(Environment.NewLine).Length; | ||
Assert.AreEqual(numbers.Count() + 1, lineCount); | ||
} | ||
|
||
private readonly string PingOutputLikeExpression = @" | ||
Pinging * with * bytes of data: | ||
Reply from * | ||
Reply from * | ||
Reply from * | ||
Reply from * | ||
|
||
Ping statistics for ::1: | ||
Packets: Sent = *, Received = *, Lost = 0 (0% loss), | ||
Approximate round trip times in milli-seconds: | ||
Minimum = *, Maximum = *, Average = *".Trim(); | ||
// private void AssertValidPingOutput(int exitCode, string? stdOutput) | ||
// { | ||
// Assert.IsFalse(string.IsNullOrWhiteSpace(stdOutput)); | ||
// Console.WriteLine($"stdOutput: {stdOutput}"); | ||
// Console.WriteLine($"PingOutputLikeExpression: {PingOutputLikeExpression}"); | ||
// stdOutput = WildcardPattern.NormalizeLineEndings(stdOutput!.Trim()); | ||
// Assert.IsTrue(stdOutput?.IsLike(PingOutputLikeExpression) ?? false, $"Output is unexpected: {stdOutput}"); | ||
// Assert.AreEqual<int>(0, exitCode); | ||
// } | ||
// private void AssertValidPingOutput(PingResult result) | ||
// { | ||
// AssertValidPingOutput(result.ExitCode, result.StdOutput); | ||
// } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We want to remove unused/commented code prior to opening a PR.