Fix race condition in test code waiting for dotnet-watch to restart

This commit is contained in:
Nate McMaster 2018-03-30 17:44:31 -07:00
parent 1f41b26145
commit 6d4a632b96
No known key found for this signature in database
GPG Key ID: A778D9601BD78810
4 changed files with 24 additions and 4 deletions

View File

@ -105,9 +105,23 @@ namespace Microsoft.DotNet.Watcher.Internal
{
_process = process;
_process.Exited += OnExited;
Task = _tcs.Task.ContinueWith(_ =>
{
// We need to use two WaitForExit calls to ensure that all of the output/events are processed. Previously
// this code used Process.Exited, which could result in us missing some output due to the ordering of
// events.
//
// See the remarks here: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexit#System_Diagnostics_Process_WaitForExit_System_Int32_
if (!process.WaitForExit(Int32.MaxValue))
{
throw new TimeoutException();
}
process.WaitForExit();
});
}
public Task Task => _tcs.Task;
public Task Task { get; }
public void TryKill()
{

View File

@ -116,6 +116,8 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
private void OnExit(object sender, EventArgs args)
{
// Wait to ensure the process has exited and all output consumed
_process.WaitForExit();
_source.Complete();
}

View File

@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
Assert.Throws<ArgumentException>(() => Process.GetProcessById(pid));
}
[Fact(Skip="https://github.com/aspnet/DotNetTools/issues/407")]
[Fact]
public async Task RestartProcessThatTerminatesAfterFileChange()
{
await _app.StartWatcherAsync();

View File

@ -18,6 +18,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
private const string StartedMessage = "Started";
private const string ExitingMessage = "Exiting";
private const string WatchExitedMessage = "watch : Exited";
private readonly ITestOutputHelper _logger;
private string _appName;
@ -42,8 +43,11 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
public Task HasRestarted()
=> Process.GetOutputLineAsync(StartedMessage, DefaultMessageTimeOut);
public Task HasExited()
=> Process.GetOutputLineAsync(ExitingMessage, DefaultMessageTimeOut);
public async Task HasExited()
{
await Process.GetOutputLineAsync(ExitingMessage, DefaultMessageTimeOut);
await Process.GetOutputLineAsync(WatchExitedMessage, DefaultMessageTimeOut);
}
public bool UsePollingWatcher { get; set; }