Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not create custom instances of TestAssetsManager in tests, use SdkTest base instead #45071

Open
wants to merge 2 commits into
base: release/9.0.2xx
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions test/Microsoft.NET.TestFramework/SdkTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public abstract class SdkTest
protected SdkTest(ITestOutputHelper log)
{
Log = log;
#pragma warning disable CS0618 // The only allowed caller of TestAssetsManager constructor.
_testAssetsManager = new TestAssetsManager(log);
#pragma warning restore CS0618
}

protected static void WaitForUtcNowToAdvance()
Expand Down
1 change: 1 addition & 0 deletions test/Microsoft.NET.TestFramework/TestAssetsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class TestAssetsManager

protected ITestOutputHelper Log { get; }

[Obsolete($"Use instance provided by {nameof(SdkTest)}.")]
public TestAssetsManager(ITestOutputHelper log)
{
var testAssetsDirectory = TestContext.Current.TestAssetsDirectory;
Expand Down
6 changes: 2 additions & 4 deletions test/dotnet-watch.Tests/FileSetSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

namespace Microsoft.DotNet.Watch.UnitTests;

public class FileSetSerializerTests(ITestOutputHelper output)
public class FileSetSerializerTests(ITestOutputHelper output) : SdkTest(output)
{
private readonly TestAssetsManager _testAssetManager = new (output);

private static string Serialize(MSBuildFileSetResult fileSetResult, Stream stream)
{
foreach (var item in fileSetResult.Projects.Values)
Expand Down Expand Up @@ -102,7 +100,7 @@ public async Task Roundtrip()
[Fact]
public async Task Task()
{
var dir = _testAssetManager.CreateTestDirectory().Path;
var dir = _testAssetsManager.CreateTestDirectory().Path;
var outputPath = Path.Combine(dir, "output.txt");

var engine = new MockBuildEngine();
Expand Down
98 changes: 45 additions & 53 deletions test/dotnet-watch.Tests/FileWatcherTests.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable

namespace Microsoft.DotNet.Watch.UnitTests
{
public class FileWatcherTests(ITestOutputHelper output)
public class FileWatcherTests(ITestOutputHelper output) : SdkTest(output)
{
private readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(60);
private readonly TimeSpan NegativeTimeout = TimeSpan.FromSeconds(5);
private readonly TestAssetsManager _testAssetManager = new TestAssetsManager(output);
private static readonly TimeSpan s_defaultTimeout = TimeSpan.FromSeconds(60);
private static readonly TimeSpan s_negativeTimeout = TimeSpan.FromSeconds(5);

private async Task TestOperation(
string dir,
Expand All @@ -18,35 +19,47 @@ private async Task TestOperation(
using var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling);
if (watcher is EventBasedDirectoryWatcher dotnetWatcher)
{
dotnetWatcher.Logger = m => output.WriteLine(m);
dotnetWatcher.Logger = m => Log.WriteLine(m);
}

var barrierDir = Path.Combine(dir, ".barrier");
var seenBarrier = false;
var changedEv = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var filesChanged = new HashSet<(string path, ChangeKind kind)>();

EventHandler<(string path, ChangeKind kind)> handler = null;
EventHandler<(string path, ChangeKind kind)>? handler = null;
handler = (_, f) =>
{
if (filesChanged.Add(f))
if (!seenBarrier)
{
output.WriteLine($"Observed new {f.kind}: '{f.path}' ({filesChanged.Count} out of {expectedChanges.Length})");
seenBarrier = f.kind == ChangeKind.Add && f.path == barrierDir;
}
else
{
output.WriteLine($"Already seen {f.kind}: '{f.path}'");
}
if (filesChanged.Add(f))
{
Log.WriteLine($"Observed new {f.kind}: '{f.path}' ({filesChanged.Count} out of {expectedChanges.Length})");
}
else
{
Log.WriteLine($"Already seen {f.kind}: '{f.path}'");
}

if (filesChanged.Count == expectedChanges.Length)
{
watcher.EnableRaisingEvents = false;
watcher.OnFileChange -= handler;
changedEv.TrySetResult();
if (filesChanged.Count == expectedChanges.Length)
{
watcher.EnableRaisingEvents = false;
watcher.OnFileChange -= handler;
changedEv.TrySetResult();
}
}
};

watcher.OnFileChange += handler;
watcher.EnableRaisingEvents = true;

// Create a barrier directory. Only start registering events once the barrier add event is received.
Directory.CreateDirectory(barrierDir);

if (usePolling)
{
// On Unix the file write time is in 1s increments;
Expand All @@ -57,7 +70,7 @@ private async Task TestOperation(

operation();

await changedEv.Task.TimeoutAfter(DefaultTimeout);
await changedEv.Task.TimeoutAfter(s_defaultTimeout);
AssertEx.SequenceEqual(expectedChanges, filesChanged.Order());
}

Expand All @@ -66,7 +79,7 @@ private async Task TestOperation(
[InlineData(false)]
public async Task NewFile(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

var testFileFullPath = Path.Combine(dir, "foo");

Expand All @@ -91,7 +104,7 @@ await TestOperation(
[InlineData(false)]
public async Task NewFileInNewDirectory(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

var newDir = Path.Combine(dir, "Dir");
var newFile = Path.Combine(newDir, "foo");
Expand Down Expand Up @@ -122,7 +135,7 @@ await TestOperation(
[InlineData(false)]
public async Task ChangeFile(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

var testFileFullPath = Path.Combine(dir, "foo");
File.WriteAllText(testFileFullPath, string.Empty);
Expand All @@ -138,7 +151,7 @@ await TestOperation(
[CombinatorialData]
public async Task MoveFile(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var srcFile = Path.Combine(dir, "foo");
var dstFile = Path.Combine(dir, "foo2");

Expand Down Expand Up @@ -167,7 +180,7 @@ await TestOperation(
[Fact]
public async Task FileInSubdirectory()
{
var dir = _testAssetManager.CreateTestDirectory().Path;
var dir = _testAssetsManager.CreateTestDirectory().Path;

var subdir = Path.Combine(dir, "subdir");
Directory.CreateDirectory(subdir);
Expand All @@ -190,7 +203,7 @@ await TestOperation(
[InlineData(false)]
public async Task NoNotificationIfDisabled(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

using var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling);

Expand All @@ -211,15 +224,15 @@ public async Task NoNotificationIfDisabled(bool usePolling)
}
File.WriteAllText(testFileFullPath, string.Empty);

await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(NegativeTimeout));
await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(s_negativeTimeout));
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task DisposedNoEvents(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var changedEv = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
{
Expand All @@ -238,15 +251,15 @@ public async Task DisposedNoEvents(bool usePolling)
}
File.WriteAllText(testFileFullPath, string.Empty);

await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(NegativeTimeout));
await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(s_negativeTimeout));
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task MultipleFiles(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

File.WriteAllText(Path.Combine(dir, "foo1"), string.Empty);
File.WriteAllText(Path.Combine(dir, "foo2"), string.Empty);
Expand Down Expand Up @@ -274,7 +287,7 @@ await TestOperation(
[InlineData(false)]
public async Task MultipleTriggers(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(identifier: usePolling.ToString()).Path;

using var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling);

Expand All @@ -294,7 +307,7 @@ private async Task AssertFileChangeRaisesEvent(string directory, IDirectoryWatch
var expectedPath = Path.Combine(directory, Path.GetRandomFileName());
EventHandler<(string, ChangeKind)> handler = (_, f) =>
{
output.WriteLine("File changed: " + f);
Log.WriteLine("File changed: " + f);
try
{
if (string.Equals(f.Item1, expectedPath, StringComparison.OrdinalIgnoreCase))
Expand All @@ -321,7 +334,7 @@ private async Task AssertFileChangeRaisesEvent(string directory, IDirectoryWatch
// watcher will not detect the change
await Task.Delay(1000);
File.AppendAllText(expectedPath, " ");
await changedEv.Task.TimeoutAfter(DefaultTimeout);
await changedEv.Task.TimeoutAfter(s_defaultTimeout);
}
finally
{
Expand All @@ -334,7 +347,7 @@ private async Task AssertFileChangeRaisesEvent(string directory, IDirectoryWatch
[InlineData(false)]
public async Task DeleteSubfolder(bool usePolling)
{
var dir = _testAssetManager.CreateTestDirectory(usePolling.ToString()).Path;
var dir = _testAssetsManager.CreateTestDirectory(usePolling.ToString()).Path;

var subdir = Path.Combine(dir, "subdir");
Directory.CreateDirectory(subdir);
Expand All @@ -349,37 +362,16 @@ public async Task DeleteSubfolder(bool usePolling)

await TestOperation(
dir,
expectedChanges: usePolling ?
[
(subdir, ChangeKind.Delete),
(f1, ChangeKind.Delete),
(f2, ChangeKind.Delete),
(f3, ChangeKind.Delete),
]
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
[
(subdir, ChangeKind.Add),
(subdir, ChangeKind.Delete),
(f1, ChangeKind.Update),
(f1, ChangeKind.Add),
(f1, ChangeKind.Delete),
(f2, ChangeKind.Update),
(f2, ChangeKind.Add),
(f2, ChangeKind.Delete),
(f3, ChangeKind.Update),
(f3, ChangeKind.Add),
(f3, ChangeKind.Delete),
]
: RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
expectedChanges: usePolling || !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
[
(subdir, ChangeKind.Update),
(subdir, ChangeKind.Delete),
(f1, ChangeKind.Delete),
(f2, ChangeKind.Delete),
(f3, ChangeKind.Delete),
]
:
[
(subdir, ChangeKind.Update),
(subdir, ChangeKind.Delete),
(f1, ChangeKind.Delete),
(f2, ChangeKind.Delete),
Expand Down
Loading
Loading