From 3512c067c77cbd1054ce20d41b1299c158f04d2d Mon Sep 17 00:00:00 2001 From: kkeirstead Date: Wed, 18 Aug 2021 14:54:57 -0700 Subject: [PATCH] Cleaning up the tests. --- .../Program.cs | 14 +--- .../ExecuteActionTests.cs | 84 +++++++++++-------- .../CollectionRules/Actions/ExecuteAction.cs | 10 --- ...5b6cf9316c46308d2e3abe6d4df13b.failure.txt | 9 ++ src/Tools/dotnet-monitor/Strings.resx | 4 + 5 files changed, 64 insertions(+), 57 deletions(-) create mode 100644 src/Tools/dotnet-monitor/MSBuild_Logs/MSBuild_pid-20748_0f5b6cf9316c46308d2e3abe6d4df13b.failure.txt diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ExecuteActionApp/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ExecuteActionApp/Program.cs index 3fd20be6555..03b6525c0cf 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ExecuteActionApp/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ExecuteActionApp/Program.cs @@ -11,15 +11,13 @@ internal class Program { public static int Main(string[] args) { - //File.WriteAllText("C:\\Users\\kkeirstead\\FileOutputs\\Test.txt", args[0]); // Testing purposes only - string testType = args[0]; - const int DelayMs = 3000; // Should be greater than the token delay in the test. + const int DelayMs = 3000; // Must be greater than TokenTimeoutMs in ExecuteActionTests. switch (testType) { case "ZeroExitCode": - return 0; ; + return 0; case "NonzeroExitCode": return -1; @@ -29,13 +27,7 @@ public static int Main(string[] args) return 0; case "TextFileOutput": - //File.WriteAllText("C:\\Users\\kkeirstead\\FileOutputs\\Test2.txt", args[1]); // Testing purposes only - //File.WriteAllText("C:\\Users\\kkeirstead\\FileOutputs\\Test3.txt", args[2]); // Testing purposes only - - string textFilePath = args[1]; - string textFileMessage = args[2]; - - File.WriteAllText(textFilePath, textFileMessage); + File.WriteAllText(args[1], args[2]); return 0; default: diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExecuteActionTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExecuteActionTests.cs index dea8aae1bc3..7b50b9433d5 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExecuteActionTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExecuteActionTests.cs @@ -11,15 +11,14 @@ using System.Threading; using System; using System.IO; +using System.Diagnostics; +using Microsoft.Diagnostics.Tools.Monitor; namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests { public sealed class ExecuteActionTests { - private const int TokenTimeoutMs = 2000; // Arbitrarily set - - // This should be identical to the error message found in Strings.resx (except without the process's exit code) - private const string NonzeroExitCodeMessage = "The process exited with exit code"; + private const int TokenTimeoutMs = 2000; // Must be less than DelayMs in the ExecuteApp private const string TaskCanceledMessage = "A task was canceled"; @@ -31,14 +30,9 @@ public async Task ExecuteAction_ZeroExitCode() ExecuteOptions options = new(); options.Path = DotNetHost.HostExePath; - options.Arguments = Assembly.GetExecutingAssembly().Location.Replace( - Assembly.GetExecutingAssembly().GetName().Name, - "Microsoft.Diagnostics.Monitoring.ExecuteApp") + " ZeroExitCode"; + options.Arguments = GenerateArgumentsString(new string[] { "ZeroExitCode" }); - using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TokenTimeoutMs); - CancellationToken cancellationToken = cancellationTokenSource.Token; - - CollectionRuleActionResult result = await action.ExecuteAsync(options, null, cancellationToken); + CollectionRuleActionResult result = await action.ExecuteAsync(options, null, CreateCancellationToken()); Assert.Equal("0", result.OutputValues["ExitCode"]); } @@ -51,16 +45,12 @@ public async Task ExecuteAction_NonzeroExitCode() ExecuteOptions options = new(); options.Path = DotNetHost.HostExePath; - options.Arguments = Assembly.GetExecutingAssembly().Location.Replace( - Assembly.GetExecutingAssembly().GetName().Name, - "Microsoft.Diagnostics.Monitoring.ExecuteApp") + " NonzeroExitCode"; - - using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TokenTimeoutMs); - CancellationToken cancellationToken = cancellationTokenSource.Token; + options.Arguments = GenerateArgumentsString(new string[] { "NonzeroExitCode" }); InvalidOperationException invalidOperationException = await Assert.ThrowsAsync( - () => action.ExecuteAsync(options, null, cancellationToken)); - Assert.Contains(NonzeroExitCodeMessage, invalidOperationException.Message); + () => action.ExecuteAsync(options, null, CreateCancellationToken())); + + Assert.Contains(string.Format(Strings.ErrorMessage_NonzeroExitCode, "-1"), invalidOperationException.Message); } [Fact] @@ -71,15 +61,11 @@ public async Task ExecuteAction_TokenCancellation() ExecuteOptions options = new(); options.Path = DotNetHost.HostExePath; - options.Arguments = Assembly.GetExecutingAssembly().Location.Replace( - Assembly.GetExecutingAssembly().GetName().Name, - "Microsoft.Diagnostics.Monitoring.ExecuteApp") + " TokenCancellation"; - - using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TokenTimeoutMs); - CancellationToken cancellationToken = cancellationTokenSource.Token; + options.Arguments = GenerateArgumentsString(new string[] { "TokenCancellation" }); ; TaskCanceledException invalidOperationException = await Assert.ThrowsAsync( - () => action.ExecuteAsync(options, null, cancellationToken)); + () => action.ExecuteAsync(options, null, CreateCancellationToken())); + Assert.Contains(TaskCanceledMessage, invalidOperationException.Message); } @@ -91,21 +77,14 @@ public async Task ExecuteAction_TextFileOutput() ExecuteOptions options = new(); DirectoryInfo outputDirectory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "ExecuteAction", Guid.NewGuid().ToString())); - string textFileOutputPath = outputDirectory.FullName; - - textFileOutputPath += "\\file.txt"; + string textFileOutputPath = outputDirectory.FullName + "\\file.txt"; const string testMessage = "TestMessage"; options.Path = DotNetHost.HostExePath; - options.Arguments = Assembly.GetExecutingAssembly().Location.Replace( - Assembly.GetExecutingAssembly().GetName().Name, - "Microsoft.Diagnostics.Monitoring.ExecuteApp") + " TextFileOutput " + textFileOutputPath + " " + testMessage; - - using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TokenTimeoutMs); - CancellationToken cancellationToken = cancellationTokenSource.Token; + options.Arguments = GenerateArgumentsString(new string[] { "TextFileOutput", textFileOutputPath, testMessage }); - CollectionRuleActionResult result = await action.ExecuteAsync(options, null, cancellationToken); + CollectionRuleActionResult result = await action.ExecuteAsync(options, null, CreateCancellationToken()); Assert.Equal("0", result.OutputValues["ExitCode"]); Assert.Equal(testMessage, File.ReadAllText(textFileOutputPath)); @@ -118,5 +97,38 @@ public async Task ExecuteAction_TextFileOutput() { } } + + [Fact] + public async Task ExecuteAction_InvalidPath() + { + ExecuteAction action = new(); + + ExecuteOptions options = new(); + + string uniquePathName = Guid.NewGuid().ToString(); + + options.Path = uniquePathName; + options.Arguments = Assembly.GetExecutingAssembly().Location.Replace( + Assembly.GetExecutingAssembly().GetName().Name, + "Microsoft.Diagnostics.Monitoring.ExecuteApp"); + + FileNotFoundException fileNotFoundException = await Assert.ThrowsAsync( + () => action.ExecuteAsync(options, null, CreateCancellationToken())); + + Assert.Equal(string.Format(Strings.ErrorMessage_FileNotFound, uniquePathName), fileNotFoundException.Message); + } + + private static string GenerateArgumentsString(string[] additionalArgs) + { + return Assembly.GetExecutingAssembly().Location.Replace( + Assembly.GetExecutingAssembly().GetName().Name, + "Microsoft.Diagnostics.Monitoring.ExecuteApp") + ' ' + string.Join(' ', additionalArgs); + } + + private static CancellationToken CreateCancellationToken() + { + CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TokenTimeoutMs); + return cancellationTokenSource.Token; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index 7b94f0f9c15..c0cdd4fb19d 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -30,16 +30,6 @@ public async Task ExecuteAsync(ExecuteOptions option process.StartInfo = new ProcessStartInfo(path, arguments); - /* - process.StartInfo = new ProcessStartInfo(path); - - string[] args = arguments.Split(); - - foreach (string arg in args) - { - process.StartInfo.ArgumentList.Add(arg); - }*/ - process.EnableRaisingEvents = true; // Completion source that is signaled when the process exits diff --git a/src/Tools/dotnet-monitor/MSBuild_Logs/MSBuild_pid-20748_0f5b6cf9316c46308d2e3abe6d4df13b.failure.txt b/src/Tools/dotnet-monitor/MSBuild_Logs/MSBuild_pid-20748_0f5b6cf9316c46308d2e3abe6d4df13b.failure.txt new file mode 100644 index 00000000000..107f91c9aa9 --- /dev/null +++ b/src/Tools/dotnet-monitor/MSBuild_Logs/MSBuild_pid-20748_0f5b6cf9316c46308d2e3abe6d4df13b.failure.txt @@ -0,0 +1,9 @@ +UNHANDLED EXCEPTIONS FROM PROCESS 20748: +===================== +8/18/2021 2:19:23 PM +System.IO.IOException: Pipe is broken. + at System.IO.Pipes.PipeStream.WriteAsyncCore(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken) in System.IO.Pipes.dll:token 0x60000ec+0x33 + at System.IO.Pipes.PipeStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) in System.IO.Pipes.dll:token 0x60000e1+0x4a + at System.IO.Pipes.PipeStream.Write(Byte[] buffer, Int32 offset, Int32 count) in System.IO.Pipes.dll:token 0x60000df+0x8 + at Microsoft.Build.BackEnd.NodeEndpointOutOfProcBase.RunReadLoop(Stream localReadPipe, Stream localWritePipe, ConcurrentQueue`1 localPacketQueue, AutoResetEvent localPacketAvailable, AutoResetEvent localTerminatePacketPump) in Microsoft.Build.dll:token 0x600107a+0x1b8 +=================== diff --git a/src/Tools/dotnet-monitor/Strings.resx b/src/Tools/dotnet-monitor/Strings.resx index f5a7e952b99..5496192cb22 100644 --- a/src/Tools/dotnet-monitor/Strings.resx +++ b/src/Tools/dotnet-monitor/Strings.resx @@ -243,6 +243,10 @@ Unable to bind any urls. Gets a string similar to "Unable to bind any urls.". + + Unable to start: {0} {1} + {0} = FileName, {1} = Process's Arguments + Unhandled connection mode: {0} Gets the format string for egress provider failure due to missing provider.