提交 ff7264f0 编写于 作者: K Kevin Pilch-Bisson

Attempt to diagnose the flakiness in TestTagsChangesForEntireFile

I'm unable to figure out what is going wrong here. My best guess is that
a second workspace event happens before the text changes that causes
classification to refresh while still on the original snapshot.

This adds some additional diagnostics to our test to try to identify that.

Also changes CheckPoint.Release to CheckPoint.TryRelease, so that it's
possible to observe if someone else already caused the checkpoint task to
complete.

Related to #9723.
上级 a42fae6f
......@@ -35,21 +35,35 @@ public async Task TestTagsChangedForEntireFile()
null,
new SyntacticClassificationTaggerProvider(null, null, null));
SnapshotSpan span = default(SnapshotSpan);
var expectedLength = subjectBuffer.CurrentSnapshot.Length;
var actualVersionNumber = int.MaxValue;
var actualLength = int.MaxValue;
var didRelease = false;
tagComputer.TagsChanged += (s, e) =>
{
span = e.Span;
checkpoint.Release();
actualVersionNumber = e.Span.Snapshot.Version.VersionNumber;
actualLength = e.Span.Length;
didRelease = checkpoint.TryRelease();
};
await checkpoint.Task;
Assert.Equal(1, actualVersionNumber);
Assert.Equal(expectedLength, actualLength);
Assert.True(didRelease);
checkpoint = new Checkpoint();
// Now apply an edit that require us to reclassify more that just the current line
subjectBuffer.Insert(document.CursorPosition.Value, "\"");
var snapshot = subjectBuffer.Insert(document.CursorPosition.Value, "\"");
expectedLength = snapshot.Length;
// NOTE: TagsChanged is raised on the UI thread, so there is no race between
// assigning expected here and verifying in the event handler, because the
// event handler can't run until we await.
await checkpoint.Task;
Assert.Equal(subjectBuffer.CurrentSnapshot.Length, span.Length);
Assert.Equal(2, actualVersionNumber);
Assert.Equal(expectedLength, actualLength);
Assert.True(didRelease);
}
}
}
......
......@@ -1466,7 +1466,7 @@ class C
' before the model computation has finished. Then, allow the
' computation to complete. There should still be no session.
state.SendBackspace()
slowProvider.checkpoint.Release()
slowProvider.checkpoint.TryRelease()
Await state.AssertNoCompletionSession()
End Using
End Function
......
......@@ -92,17 +92,17 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Dim checkpoint2 = New Checkpoint
Dim checkpoint3 = New Checkpoint
token.Setup(Sub(t) t.Dispose()).Callback(Sub() checkpoint3.Release())
token.Setup(Sub(t) t.Dispose()).Callback(Sub() checkpoint3.TryRelease())
modelComputation.ChainTaskAndNotifyControllerWhenFinished(Function(m, c)
checkpoint1.Release()
checkpoint1.TryRelease()
checkpoint2.Task.Wait()
c.ThrowIfCancellationRequested()
Return Task.FromResult(model)
End Function)
Await checkpoint1.Task
modelComputation.Stop()
checkpoint2.Release()
checkpoint2.TryRelease()
Await checkpoint3.Task
controller.Verify(Sub(c) c.OnModelUpdated(model), Times.Never)
......
......@@ -153,7 +153,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Sub() GetMocks(controller).Buffer.Insert(0, " ")))
Dim handled = dispatcher.InvokeAsync(Function() controller.TryHandleUpKey()) ' Send the controller an up key, which should block on the computation
checkpoint.Release() ' Allow slowprovider to finish
checkpoint.TryRelease() ' Allow slowprovider to finish
Await handled.Task.ConfigureAwait(False)
' We expect 2 calls to the presenter (because we had an existing presentation session when we started the second computation).
......
......@@ -11,11 +11,9 @@ namespace Roslyn.Test.Utilities
public class Checkpoint
{
private readonly TaskCompletionSource<object> _tcs = new TaskCompletionSource<object>();
public Task Task { get { return _tcs.Task; } }
public void Release()
{
_tcs.TrySetResult(null);
}
public Task Task => _tcs.Task;
public bool TryRelease() => _tcs.TrySetResult(null);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册