Reduce flakiness in tests caused by the OS re-using the PID on test processes (#512)

We were using PID to assert that dotnet-watch had restarted processes. The OS does not guaranteed the uniqueness of PID, so I've changed tests to use PID + process start time to distinguish between processes.
This commit is contained in:
Nate McMaster 2018-11-06 09:57:17 -08:00 committed by GitHub
parent 9de04520e0
commit a24b4ee459
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 19 additions and 14 deletions

View File

@ -27,7 +27,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
public async Task RestartProcessOnFileChange()
{
await _app.StartWatcherAsync(new[] { "--no-exit" });
var pid = await _app.GetProcessId();
var processIdentifier = await _app.GetProcessIdentifier();
// Then wait for it to restart when we change a file
var fileToChange = Path.Combine(_app.SourceDirectory, "Program.cs");
@ -37,15 +37,15 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
await _app.HasRestarted();
Assert.DoesNotContain(_app.Process.Output, l => l.StartsWith("Exited with error code"));
var pid2 = await _app.GetProcessId();
Assert.NotEqual(pid, pid2);
var processIdentifier2 = await _app.GetProcessIdentifier();
Assert.NotEqual(processIdentifier, processIdentifier2);
}
[Fact]
public async Task RestartProcessThatTerminatesAfterFileChange()
{
await _app.StartWatcherAsync();
var pid = await _app.GetProcessId();
var processIdentifier = await _app.GetProcessIdentifier();
await _app.HasExited(); // process should exit after run
await _app.IsWaitingForFileChange();
@ -63,8 +63,8 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
await _app.HasRestarted();
}
var pid2 = await _app.GetProcessId();
Assert.NotEqual(pid, pid2);
var processIdentifier2 = await _app.GetProcessIdentifier();
Assert.NotEqual(processIdentifier, processIdentifier2);
await _app.HasExited(); // process should exit after run
}

View File

@ -57,11 +57,12 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
public bool UsePollingWatcher { get; set; }
public async Task<int> GetProcessId()
public async Task<string> GetProcessIdentifier()
{
var line = await Process.GetOutputLineStartsWithAsync("PID =", DefaultMessageTimeOut);
var pid = line.Split('=').Last();
return int.Parse(pid);
// Process ID is insufficient because PID's may be reused. Process identifier also includes other info to distinguish
// between different process instances.
var line = await Process.GetOutputLineStartsWithAsync("Process identifier =", DefaultMessageTimeOut);
return line.Split('=').Last();
}
public async Task PrepareAsync()

View File

@ -14,7 +14,8 @@ namespace ConsoleApplication
public static void Main(string[] args)
{
Console.WriteLine("Started");
Console.WriteLine($"PID = " + Process.GetCurrentProcess().Id);
// Process ID is insufficient because PID's may be reused.
Console.WriteLine($"Process identifier = {Process.GetCurrentProcess().Id}, {Process.GetCurrentProcess().StartTime:hh:mm:ss.FF}");
Thread.Sleep(Timeout.Infinite);
}
}

View File

@ -14,7 +14,8 @@ namespace ConsoleApplication
public static void Main(string[] args)
{
Console.WriteLine("Started");
Console.WriteLine("PID = " + Process.GetCurrentProcess().Id);
// Process ID is insufficient because PID's may be reused.
Console.WriteLine($"Process identifier = {Process.GetCurrentProcess().Id}, {Process.GetCurrentProcess().StartTime:hh:mm:ss.FF}");
Console.WriteLine("Defined types = " + typeof(Program).GetTypeInfo().Assembly.DefinedTypes.Count());
Thread.Sleep(Timeout.Infinite);
}

View File

@ -11,7 +11,8 @@ namespace KitchenSink
static void Main(string[] args)
{
Console.WriteLine("Started");
Console.WriteLine("PID = " + Process.GetCurrentProcess().Id);
// Process ID is insufficient because PID's may be reused.
Console.WriteLine($"Process identifier = {Process.GetCurrentProcess().Id}, {Process.GetCurrentProcess().StartTime:hh:mm:ss.FF}");
Console.WriteLine("DOTNET_WATCH = " + Environment.GetEnvironmentVariable("DOTNET_WATCH"));
Console.WriteLine("DOTNET_WATCH_ITERATION = " + Environment.GetEnvironmentVariable("DOTNET_WATCH_ITERATION"));
}

View File

@ -12,7 +12,8 @@ namespace ConsoleApplication
public static void Main(string[] args)
{
Console.WriteLine("Started");
Console.WriteLine($"PID = " + Process.GetCurrentProcess().Id);
// Process ID is insufficient because PID's may be reused.
Console.WriteLine($"Process identifier = {Process.GetCurrentProcess().Id}, {Process.GetCurrentProcess().StartTime:hh:mm:ss.FF}");
if (args.Length > 0 && args[0] == "--no-exit")
{
Thread.Sleep(Timeout.Infinite);