Merge branch 'release/2.1' into dev
This commit is contained in:
commit
07517187b6
|
|
@ -286,98 +286,63 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
{
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
void Clear()
|
||||
{
|
||||
_output.WriteLine("Clear files changed list");
|
||||
filesChanged.Clear();
|
||||
}
|
||||
|
||||
UsingTempDirectory(dir =>
|
||||
{
|
||||
using (var changedEv = new AutoResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
handler = (_, f) =>
|
||||
{
|
||||
_output.WriteLine("File changed: " + f);
|
||||
filesChanged.Add(f);
|
||||
try
|
||||
{
|
||||
changedEv.Set();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// There's a known race condition here:
|
||||
// even though we tell the watcher to stop raising events and we unsubscribe the handler
|
||||
// there might be in-flight events that will still process. Since we dispose the reset
|
||||
// event, this code will fail if the handler executes after Dispose happens. There's no
|
||||
// better way to guard against it than catch because we cannot check if the object is
|
||||
// disposed nor can we check if there are any in-flight events.
|
||||
// This is actually a known issue in the corefx file watcher. It can trigger multiple
|
||||
// times for the same item.
|
||||
}
|
||||
};
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
|
||||
var testFileFullPath = Path.Combine(dir, "foo1");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
var fileChanged = Assert.Single(filesChanged);
|
||||
Assert.Equal(testFileFullPath, fileChanged);
|
||||
Clear();
|
||||
changedEv.Reset();
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
|
||||
testFileFullPath = Path.Combine(dir, "foo2");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
fileChanged = Assert.Single(filesChanged);
|
||||
Assert.Equal(testFileFullPath, fileChanged);
|
||||
Clear();
|
||||
changedEv.Reset();
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
|
||||
testFileFullPath = Path.Combine(dir, "foo3");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
fileChanged = Assert.Single(filesChanged);
|
||||
Assert.Equal(testFileFullPath, fileChanged);
|
||||
Clear();
|
||||
changedEv.Reset();
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
fileChanged = Assert.Single(filesChanged);
|
||||
Assert.Equal(testFileFullPath, fileChanged);
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
AssertFileChangeRaisesEvent(dir, watcher);
|
||||
}
|
||||
|
||||
watcher.EnableRaisingEvents = false;
|
||||
watcher.OnFileChange -= handler;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void AssertFileChangeRaisesEvent(string directory, IFileSystemWatcher watcher)
|
||||
{
|
||||
var semaphoreSlim = new SemaphoreSlim(0);
|
||||
var expectedPath = Path.Combine(directory, Path.GetRandomFileName());
|
||||
EventHandler<string> handler = (object _, string f) =>
|
||||
{
|
||||
_output.WriteLine("File changed: " + f);
|
||||
try
|
||||
{
|
||||
if (string.Equals(f, expectedPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
semaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// There's a known race condition here:
|
||||
// even though we tell the watcher to stop raising events and we unsubscribe the handler
|
||||
// there might be in-flight events that will still process. Since we dispose the reset
|
||||
// event, this code will fail if the handler executes after Dispose happens.
|
||||
}
|
||||
};
|
||||
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
try
|
||||
{
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
Assert.True(semaphoreSlim.Wait(DefaultTimeout), "Expected a file change event for " + expectedPath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
watcher.OnFileChange -= handler;
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue