Fix BackgroundDocumentGenerator flaky tests.

- Some time spans were too aggressive for parsing a Razor file on a slow environment.
- Fixed an obvious race where we'd expect 0 pending notifications when it was possible to be in the process of clearing notifications.

#2506
This commit is contained in:
N. Taylor Mullen 2018-07-27 12:03:30 -07:00
parent 676543b8c9
commit 38e145389e
2 changed files with 19 additions and 3 deletions

View File

@ -56,6 +56,9 @@ namespace Microsoft.CodeAnalysis.Razor
// Used in unit tests to ensure we can know when background work finishes.
public ManualResetEventSlim NotifyBackgroundWorkStarting { get; set; }
// Used in unit tests to ensure we can know when background has captured its current workload.
public ManualResetEventSlim NotifyBackgroundCapturedWorkload { get; set; }
// Used in unit tests to ensure we can control when background work completes.
public ManualResetEventSlim BlockBackgroundWorkCompleting { get; set; }
@ -93,6 +96,14 @@ namespace Microsoft.CodeAnalysis.Razor
}
}
private void OnBackgroundCapturedWorkload()
{
if (NotifyBackgroundCapturedWorkload != null)
{
NotifyBackgroundCapturedWorkload.Set();
}
}
public override void Initialize(ProjectSnapshotManagerBase projectManager)
{
if (projectManager == null)
@ -161,6 +172,8 @@ namespace Microsoft.CodeAnalysis.Razor
_files.Clear();
}
OnBackgroundCapturedWorkload();
for (var i = 0; i < work.Length; i++)
{
var document = work[i];

View File

@ -95,7 +95,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
queue.BlockBackgroundWorkStart.Set();
queue.BlockBackgroundWorkCompleting.Set();
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(1)));
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3)));
Assert.False(queue.IsScheduledOrRunning, "Queue should not have restarted");
Assert.False(queue.HasPendingNotifications, "Queue should have processed all notifications");
@ -120,6 +120,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
Delay = TimeSpan.FromMilliseconds(1),
BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false),
NotifyBackgroundWorkStarting = new ManualResetEventSlim(initialState: false),
NotifyBackgroundCapturedWorkload = new ManualResetEventSlim(initialState: false),
BlockBackgroundWorkCompleting = new ManualResetEventSlim(initialState: false),
NotifyBackgroundWorkCompleted = new ManualResetEventSlim(initialState: false),
};
@ -136,6 +137,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
await Task.Run(() => queue.NotifyBackgroundWorkStarting.Wait(TimeSpan.FromSeconds(1)));
Assert.True(queue.IsScheduledOrRunning, "Worker should be processing now");
await Task.Run(() => queue.NotifyBackgroundCapturedWorkload.Wait(TimeSpan.FromSeconds(1)));
Assert.False(queue.HasPendingNotifications, "Worker should have taken all notifications");
queue.Enqueue(project, project.GetDocument(Documents[1].FilePath));
@ -144,7 +147,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
// Allow work to complete, which should restart the timer.
queue.BlockBackgroundWorkCompleting.Set();
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(1)));
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3)));
queue.NotifyBackgroundWorkCompleted.Reset();
// It should start running again right away.
@ -155,7 +158,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
queue.BlockBackgroundWorkStart.Set();
queue.BlockBackgroundWorkCompleting.Set();
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(1)));
await Task.Run(() => queue.NotifyBackgroundWorkCompleted.Wait(TimeSpan.FromSeconds(3)));
Assert.False(queue.IsScheduledOrRunning, "Queue should not have restarted");
Assert.False(queue.HasPendingNotifications, "Queue should have processed all notifications");