diff --git a/src/Tools/dotnet-watch/test/AwaitableProcess.cs b/src/Tools/dotnet-watch/test/AwaitableProcess.cs index 553b7a4d11..794a3e1f51 100644 --- a/src/Tools/dotnet-watch/test/AwaitableProcess.cs +++ b/src/Tools/dotnet-watch/test/AwaitableProcess.cs @@ -15,6 +15,8 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests { public class AwaitableProcess : IDisposable { + private readonly object _testOutputLock = new object(); + private Process _process; private readonly ProcessSpec _spec; private readonly List _lines; @@ -22,6 +24,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests private ITestOutputHelper _logger; private TaskCompletionSource _exited; private bool _started; + private bool _disposed; public AwaitableProcess(ProcessSpec spec, ITestOutputHelper logger) { @@ -29,7 +32,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _logger = logger; _source = new BufferBlock(); _lines = new List(); - _exited = new TaskCompletionSource(); + _exited = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); } public IEnumerable Output => _lines; @@ -72,17 +75,17 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _process.ErrorDataReceived += OnData; _process.Exited += OnExit; - _logger.WriteLine($"{DateTime.Now}: starting process: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'"); + WriteTestOutput($"{DateTime.Now}: starting process: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'"); _process.Start(); _started = true; _process.BeginErrorReadLine(); _process.BeginOutputReadLine(); - _logger.WriteLine($"{DateTime.Now}: process started: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'"); + WriteTestOutput($"{DateTime.Now}: process started: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'"); } public async Task GetOutputLineAsync(string message, TimeSpan timeout) { - _logger.WriteLine($"Waiting for output line [msg == '{message}']. Will wait for {timeout.TotalSeconds} sec."); + WriteTestOutput($"Waiting for output line [msg == '{message}']. Will wait for {timeout.TotalSeconds} sec."); var cts = new CancellationTokenSource(); cts.CancelAfter(timeout); return await GetOutputLineAsync($"[msg == '{message}']", m => string.Equals(m, message, StringComparison.Ordinal), cts.Token); @@ -90,7 +93,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests public async Task GetOutputLineStartsWithAsync(string message, TimeSpan timeout) { - _logger.WriteLine($"Waiting for output line [msg.StartsWith('{message}')]. Will wait for {timeout.TotalSeconds} sec."); + WriteTestOutput($"Waiting for output line [msg.StartsWith('{message}')]. Will wait for {timeout.TotalSeconds} sec."); var cts = new CancellationTokenSource(); cts.CancelAfter(timeout); return await GetOutputLineAsync($"[msg.StartsWith('{message}')]", m => m != null && m.StartsWith(message, StringComparison.Ordinal), cts.Token); @@ -105,7 +108,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests var next = await _source.ReceiveAsync(cancellationToken); _lines.Add(next); var match = predicate(next); - _logger.WriteLine($"{DateTime.Now}: recv: '{next}'. {(match ? "Matches" : "Does not match")} condition '{predicateName}'."); + WriteTestOutput($"{DateTime.Now}: recv: '{next}'. {(match ? "Matches" : "Does not match")} condition '{predicateName}'."); if (match) { return next; @@ -124,7 +127,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests while (await _source.OutputAvailableAsync(cancellationToken)) { var next = await _source.ReceiveAsync(cancellationToken); - _logger.WriteLine($"{DateTime.Now}: recv: '{next}'"); + WriteTestOutput($"{DateTime.Now}: recv: '{next}'"); lines.Add(next); } } @@ -134,23 +137,40 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests private void OnData(object sender, DataReceivedEventArgs args) { var line = args.Data ?? string.Empty; - _logger.WriteLine($"{DateTime.Now}: post: '{line}'"); + + WriteTestOutput($"{DateTime.Now}: post: '{line}'"); _source.Post(line); } + private void WriteTestOutput(string text) + { + lock (_testOutputLock) + { + if (!_disposed) + { + _logger.WriteLine(text); + } + } + } + private void OnExit(object sender, EventArgs args) { // Wait to ensure the process has exited and all output consumed _process.WaitForExit(); _source.Complete(); _exited.TrySetResult(_process.ExitCode); - _logger.WriteLine($"Process {_process.Id} has exited"); + WriteTestOutput($"Process {_process.Id} has exited"); } public void Dispose() { _source.Complete(); + lock (_testOutputLock) + { + _disposed = true; + } + if (_process != null) { if (_started && !_process.HasExited) @@ -158,6 +178,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _process.KillTree(); } + _process.CancelErrorRead(); + _process.CancelOutputRead(); + _process.ErrorDataReceived -= OnData; _process.OutputDataReceived -= OnData; _process.Exited -= OnExit; diff --git a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs deleted file mode 100644 index 2f7e5ec5af..0000000000 --- a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -// -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")] diff --git a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfo.cs b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfo.cs deleted file mode 100644 index 1172632a87..0000000000 --- a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System; -using System.Reflection; - -[assembly: System.Reflection.AssemblyMetadataAttribute("SourceCommitUrl", "https://github.com/dotnet/aspnetcore/tree/")] -[assembly: System.Reflection.AssemblyMetadataAttribute("Serviceable", "True")] -[assembly: System.Reflection.AssemblyCompanyAttribute("Microsoft Corporation")] -[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] -[assembly: System.Reflection.AssemblyCopyrightAttribute("© Microsoft Corporation. All rights reserved.")] -[assembly: System.Reflection.AssemblyFileVersionAttribute("42.42.42.42424")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("5.0.0-dev")] -[assembly: System.Reflection.AssemblyProductAttribute("Microsoft ASP.NET Core")] -[assembly: System.Reflection.AssemblyTitleAttribute("KitchenSink")] -[assembly: System.Reflection.AssemblyVersionAttribute("5.0.0.0")] -[assembly: System.Reflection.AssemblyMetadataAttribute("RepositoryUrl", "https://github.com/dotnet/aspnetcore")] -[assembly: System.Resources.NeutralResourcesLanguageAttribute("en-US")] - -// Generated by the MSBuild WriteCodeFragment class. - diff --git a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfoInputs.cache b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfoInputs.cache deleted file mode 100644 index 9042200dfc..0000000000 --- a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfoInputs.cache +++ /dev/null @@ -1 +0,0 @@ -5426b0432f23f134c800ff0d43b24a23681aac3d diff --git a/src/Tools/dotnet-watch/test/dotnet-watch.Tests.csproj b/src/Tools/dotnet-watch/test/dotnet-watch.Tests.csproj index 3a65720a67..b9c9d9fe3c 100644 --- a/src/Tools/dotnet-watch/test/dotnet-watch.Tests.csproj +++ b/src/Tools/dotnet-watch/test/dotnet-watch.Tests.csproj @@ -12,9 +12,6 @@ --> true true - - - true