Converge implementations of AwaitableProcess and ProcessEx (#26069)

* Converge implementations of AwaitableProcess and ProcessEx

* dotnet-watch tests are running in to the same issue as GRPC tests (https://github.com/dotnet/aspnetcore/pull/20341/files).
This change carries over some of the patterns from the other type to remedy this issue.

* Revive dotnet-watch tests on OSX

* Remove build artifacts that were accidentally commited to source.
This commit is contained in:
Pranav K 2020-09-18 16:32:06 -07:00 committed by GitHub
parent 7afaf45b54
commit 140f177d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 45 deletions

View File

@ -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<string> _lines;
@ -22,6 +24,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
private ITestOutputHelper _logger;
private TaskCompletionSource<int> _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<string>();
_lines = new List<string>();
_exited = new TaskCompletionSource<int>();
_exited = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
}
public IEnumerable<string> 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<string> 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<string> 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;

View File

@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")]

View File

@ -1,28 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
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.

View File

@ -12,9 +12,6 @@
-->
<UseAspNetCoreSharedRuntime>true</UseAspNetCoreSharedRuntime>
<DoNotApplyWorkaroundsToMicrosoftAspNetCoreApp>true</DoNotApplyWorkaroundsToMicrosoftAspNetCoreApp>
<!-- Skipped due to https://github.com/dotnet/aspnetcore/issues/26061 -->
<SkipTests Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</SkipTests>
</PropertyGroup>
<ItemGroup>