From 2365dced43977c702fa8f98ebbb5160b9ef43960 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Fri, 8 Feb 2019 14:37:53 -0800 Subject: [PATCH] Fix flaky process output reading for dotnet-watch tests (#7173) --- build/RepositoryBuild.targets | 7 ++-- build/buildorder.props | 2 +- .../src/Internal/ProcessRunner.cs | 33 +++++++++++-------- .../dotnet-watch/test/DotNetWatcherTests.cs | 15 ++------- .../test/Properties/AssemblyInfo.cs | 7 ++++ .../test/Scenario/WatchableApp.cs | 9 +++-- 6 files changed, 39 insertions(+), 34 deletions(-) create mode 100644 src/Tools/dotnet-watch/test/Properties/AssemblyInfo.cs diff --git a/build/RepositoryBuild.targets b/build/RepositoryBuild.targets index 3a2214a929..ee91e3a2ca 100644 --- a/build/RepositoryBuild.targets +++ b/build/RepositoryBuild.targets @@ -19,7 +19,8 @@ %(RepositoryBuildOrder.Identity) RepositoryToBuild=%(RepositoryBuildOrder.Identity); - BuildRepositoryRoot=$([MSBuild]::NormalizeDirectory(%(RepositoryBuildOrder.RootPath))) + BuildRepositoryRoot=$([MSBuild]::NormalizeDirectory(%(RepositoryBuildOrder.RootPath))); + SkipTests=%(RepositoryBuildOrder.SkipTests) @@ -171,7 +172,7 @@ - - + diff --git a/build/buildorder.props b/build/buildorder.props index 12b7cf9e85..13f9bc8ee3 100644 --- a/build/buildorder.props +++ b/build/buildorder.props @@ -7,7 +7,7 @@ - + diff --git a/src/Tools/dotnet-watch/src/Internal/ProcessRunner.cs b/src/Tools/dotnet-watch/src/Internal/ProcessRunner.cs index bbded25611..7874d592b6 100644 --- a/src/Tools/dotnet-watch/src/Internal/ProcessRunner.cs +++ b/src/Tools/dotnet-watch/src/Internal/ProcessRunner.cs @@ -37,17 +37,31 @@ namespace Microsoft.DotNet.Watcher.Internal { cancellationToken.Register(() => processState.TryKill()); + process.OutputDataReceived += (_, a) => + { + if (!string.IsNullOrEmpty(a.Data)) + { + processSpec.OutputCapture.AddLine(a.Data); + } + }; + process.ErrorDataReceived += (_, a) => + { + if (!string.IsNullOrEmpty(a.Data)) + { + processSpec.OutputCapture.AddLine(a.Data); + } + }; + stopwatch.Start(); process.Start(); + _reporter.Verbose($"Started '{processSpec.Executable}' with process id {process.Id}"); if (processSpec.IsOutputCaptured) { - await Task.WhenAll( - processState.Task, - ConsumeStreamAsync(process.StandardOutput, processSpec.OutputCapture.AddLine), - ConsumeStreamAsync(process.StandardError, processSpec.OutputCapture.AddLine) - ); + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + await processState.Task; } else { @@ -86,15 +100,6 @@ namespace Microsoft.DotNet.Watcher.Internal return process; } - private static async Task ConsumeStreamAsync(StreamReader reader, Action consume) - { - string line; - while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null) - { - consume?.Invoke(line); - } - } - private class ProcessState : IDisposable { private readonly IReporter _reporter; diff --git a/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs b/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs index d31f650aa6..7a38b94926 100644 --- a/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs +++ b/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs @@ -49,19 +49,8 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests await _app.IsWaitingForFileChange(); - try - { - File.SetLastWriteTime(source, DateTime.Now); - await _app.HasRestarted(); - } - catch (Exception ex) - { - _logger.WriteLine("Retrying. First attempt to restart app failed: " + ex.Message); - - // retry - File.SetLastWriteTime(source, DateTime.Now); - await _app.HasRestarted(); - } + File.SetLastWriteTime(source, DateTime.Now); + await _app.HasRestarted(TimeSpan.FromMinutes(1)); } } diff --git a/src/Tools/dotnet-watch/test/Properties/AssemblyInfo.cs b/src/Tools/dotnet-watch/test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..d8e6c031be --- /dev/null +++ b/src/Tools/dotnet-watch/test/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file diff --git a/src/Tools/dotnet-watch/test/Scenario/WatchableApp.cs b/src/Tools/dotnet-watch/test/Scenario/WatchableApp.cs index 4f2d575f01..7297c58ce1 100644 --- a/src/Tools/dotnet-watch/test/Scenario/WatchableApp.cs +++ b/src/Tools/dotnet-watch/test/Scenario/WatchableApp.cs @@ -42,7 +42,10 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests public string SourceDirectory { get; } public Task HasRestarted() - => Process.GetOutputLineAsync(StartedMessage, DefaultMessageTimeOut); + => HasRestarted(DefaultMessageTimeOut); + + public Task HasRestarted(TimeSpan timeout) + => Process.GetOutputLineAsync(StartedMessage, timeout); public async Task HasExited() { @@ -50,9 +53,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests await Process.GetOutputLineStartsWithAsync(WatchExitedMessage, DefaultMessageTimeOut); } - public async Task IsWaitingForFileChange() + public Task IsWaitingForFileChange() { - await Process.GetOutputLineStartsWithAsync(WaitingForFileChangeMessage, DefaultMessageTimeOut); + return Process.GetOutputLineStartsWithAsync(WaitingForFileChangeMessage, DefaultMessageTimeOut); } public bool UsePollingWatcher { get; set; }