Skip to content
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

Open
wants to merge 34 commits into
base: Assignment9+10-Multithreading
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d719913
Changes to PingProcess
Pbrown34 Dec 10, 2024
97cbbe8
More Tests WIP
Pbrown34 Dec 10, 2024
473d86d
Fixed PingProcessTests
LeoMarlow Dec 10, 2024
e0ae246
sln fix
Pbrown34 Dec 10, 2024
dab3592
Sln fix 2
Pbrown34 Dec 10, 2024
96e9232
sln fix 3
Pbrown34 Dec 10, 2024
085d284
Sln fix 4
Pbrown34 Dec 10, 2024
1afed73
sln fix 5
Pbrown34 Dec 10, 2024
ff6aca5
sln fix 6
Pbrown34 Dec 10, 2024
b0f32f9
PingProcessTests-BuildFixes
LeoMarlow Dec 10, 2024
dbc3e39
syntax fix in Wildcard
Pbrown34 Dec 10, 2024
6054779
changes to tests, "-c 4 " to stop loop
Pbrown34 Dec 10, 2024
5b162fe
break the loop, created error in Wildcard
Pbrown34 Dec 11, 2024
bfab95b
Build Fixes
LeoMarlow Dec 11, 2024
8b3893a
Build Fixes- Wildcard Only
LeoMarlow Dec 11, 2024
ded62aa
Loop Breaker- To Fix Replace ; on nameSpace
LeoMarlow Dec 11, 2024
4fd88aa
Hopefully some fixes ?
LeoMarlow Dec 11, 2024
88d5d09
Merge branch 'Assignment9+10-Multithreading' of https://github.com/Pb…
LeoMarlow Dec 11, 2024
c57bc17
Test issue fixes
LeoMarlow Dec 11, 2024
d2c3856
small changes to pingtests
Pbrown34 Dec 11, 2024
7c0ab22
small fixes
Pbrown34 Dec 11, 2024
847b5b2
I can't believe this was the issue
LeoMarlow Dec 11, 2024
7d153f5
Hopefully the last 1 ?
LeoMarlow Dec 11, 2024
59d50fa
GoogleFix?
LeoMarlow Dec 11, 2024
57b1ed1
Replaced -n with -c
LeoMarlow Dec 11, 2024
f2e69ef
Merge branch 'Assignment9+10-Multithreading' of https://github.com/Pb…
LeoMarlow Dec 11, 2024
466ad04
Removed Writelines
LeoMarlow Dec 11, 2024
42348d5
Changes to tests
Pbrown34 Dec 11, 2024
ca961ac
final fix?
Pbrown34 Dec 11, 2024
d66c61e
ValidPingOutput is nothing but problems
Pbrown34 Dec 11, 2024
024f61c
commented out VaildPing
Pbrown34 Dec 11, 2024
df23f3e
Changes to RunAsync; RunLongRunning and tests
Pbrown34 Dec 12, 2024
20552b4
Changes to Tests
Pbrown34 Dec 12, 2024
4c10012
Re-Changes to LongRunningAsync and Tests
Pbrown34 Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
30 changes: 27 additions & 3 deletions Assignment/Assignment.sln → Assignment.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35507.96 d17.13
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Assignment", "Assignment\Assignment.csproj", "{F71D0FF8-246D-4D7E-9C1B-B6C15FE85EF8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E316FCD7-C0C8-4F2F-87FB-F92921756F02}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Assignment.Tests", "Assignment.Tests\Assignment.Tests.csproj", "{0081689F-904E-4E2F-ADFF-EF85CE769A53}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assignment.tests", "Assignment.tests\Assignment.Tests.csproj", "{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assignment", "Assignment\Assignment.csproj", "{1052D0D3-5D78-4226-BA08-966119B36C99}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -46,6 +46,30 @@ Global
{0081689F-904E-4E2F-ADFF-EF85CE769A53}.Release|x64.Build.0 = Release|Any CPU
{0081689F-904E-4E2F-ADFF-EF85CE769A53}.Release|x86.ActiveCfg = Release|Any CPU
{0081689F-904E-4E2F-ADFF-EF85CE769A53}.Release|x86.Build.0 = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|x64.ActiveCfg = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|x64.Build.0 = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|x86.ActiveCfg = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Debug|x86.Build.0 = Debug|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|Any CPU.Build.0 = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|x64.ActiveCfg = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|x64.Build.0 = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|x86.ActiveCfg = Release|Any CPU
{D093C6E1-5E4C-40AE-B7E7-DACD5B08FBFC}.Release|x86.Build.0 = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|x64.ActiveCfg = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|x64.Build.0 = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|x86.ActiveCfg = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Debug|x86.Build.0 = Debug|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|Any CPU.Build.0 = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|x64.ActiveCfg = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|x64.Build.0 = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|x86.ActiveCfg = Release|Any CPU
{1052D0D3-5D78-4226-BA08-966119B36C99}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
202 changes: 202 additions & 0 deletions Assignment.tests/PingProcessTests.cs
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);

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.

}

[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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to throw a new AggregateException(ex.InnerException) here when you're already expecting the exception.

Choose a reason for hiding this comment

The 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;

Choose a reason for hiding this comment

The 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 ex) we will actually lose the original stack trace on the exception. We want this information to potentially debug issues and understand where the exception was first thrown, even though this is a unit test.

}
}
}
[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);
// }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace IntelliTect.TestTools;
namespace Assignment.Tests;

/// <summary>
/// Useful string extensions for performing assertions.
Expand All @@ -14,7 +14,7 @@ public static class StringExtensions
/// <param name="s">The string to match</param>
/// <param name="pattern">The pattern to match it against.</param>
/// <returns></returns>
public static bool IsLikeRegEx(this string s, string pattern) =>
public static bool IsLikeRegExChacter(this string s, string pattern) =>
new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(s);

/// <summary>
Expand Down
Loading
Loading