Skip to content

Commit ad9ff58

Browse files
authored
Merge pull request #74014 from dibarbet/fix_lsp_references_flakiness
Fix flakiness in LSP references tests due to non-deterministic ordering
2 parents e102ec2 + b77ed2e commit ad9ff58

File tree

3 files changed

+46
-41
lines changed

3 files changed

+46
-41
lines changed

src/LanguageServer/ProtocolUnitTests/DocumentChanges/DocumentChangesTests.WithFindAllReferences.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics;
56
using System.Linq;
7+
using System.Text.Json;
68
using System.Threading.Tasks;
79
using Microsoft.CodeAnalysis.LanguageServer.UnitTests.References;
810
using Roslyn.LanguageServer.Protocol;
@@ -40,15 +42,15 @@ void M2()
4042

4143
var originalDocument = testLspServer.GetCurrentSolution().Projects.Single().Documents.Single();
4244

43-
var findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<VSInternalReferenceItem>(testLspServer, locationTyped);
45+
var findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped);
4446
Assert.Single(findResults);
4547

4648
Assert.Equal("A", findResults[0].ContainingType);
4749

4850
// Declare a local inside A.M()
4951
await DidChange(testLspServer, locationTyped.Uri, (5, 0, "var i = someInt + 1;\r\n"));
5052

51-
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<VSInternalReferenceItem>(testLspServer, locationTyped);
53+
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped);
5254
Assert.Equal(2, findResults.Length);
5355

5456
Assert.Equal("A", findResults[0].ContainingType);
@@ -57,7 +59,7 @@ void M2()
5759
// Declare a field in B
5860
await DidChange(testLspServer, locationTyped.Uri, (10, 0, "int someInt = A.someInt + 1;\r\n"));
5961

60-
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<VSInternalReferenceItem>(testLspServer, locationTyped);
62+
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped);
6163
Assert.Equal(3, findResults.Length);
6264

6365
Assert.Equal("A", findResults[0].ContainingType);
@@ -67,7 +69,7 @@ void M2()
6769
// Declare a local inside B.M2()
6870
await DidChange(testLspServer, locationTyped.Uri, (13, 0, "var j = someInt + A.someInt;\r\n"));
6971

70-
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<VSInternalReferenceItem>(testLspServer, locationTyped);
72+
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped);
7173
Assert.Equal(4, findResults.Length);
7274

7375
Assert.Equal("A", findResults[0].ContainingType);
@@ -83,7 +85,7 @@ void M2()
8385
// updated document, so if we regress and get lucky, we still know about it.
8486
await DidClose(testLspServer, locationTyped.Uri);
8587

86-
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<VSInternalReferenceItem>(testLspServer, locationTyped);
88+
findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped);
8789
Assert.Single(findResults);
8890

8991
Assert.Equal("A", findResults[0].ContainingType);

src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerFeaturesTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ void M2()
4545
}";
4646
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, new LSP.ClientCapabilities());
4747

48-
var results = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync<LSP.Location>(testLspServer, testLspServer.GetLocations("caret").First());
48+
var results = await FindAllReferencesHandlerTests.RunFindAllReferencesNonVSAsync(testLspServer, testLspServer.GetLocations("caret").First());
4949
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Select(result => result));
5050
}
5151
}

src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,13 @@ void M2()
4646
}";
4747
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
4848

49-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
49+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
5050
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Select(result => result.Location));
5151

52-
// Results are returned in a non-deterministic order, so we order them by location
53-
var orderedResults = results.OrderBy(r => r.Location, new OrderLocations()).ToArray();
54-
Assert.Equal("A", orderedResults[0].ContainingType);
55-
Assert.Equal("B", orderedResults[2].ContainingType);
56-
Assert.Equal("M", orderedResults[1].ContainingMember);
57-
Assert.Equal("M2", orderedResults[3].ContainingMember);
52+
Assert.Equal("A", results[0].ContainingType);
53+
Assert.Equal("B", results[2].ContainingType);
54+
Assert.Equal("M", results[1].ContainingMember);
55+
Assert.Equal("M2", results[3].ContainingMember);
5856

5957
AssertValidDefinitionProperties(results, 0, Glyph.FieldPublic);
6058
AssertHighlightCount(results, expectedDefinitionCount: 1, expectedWrittenReferenceCount: 0, expectedReferenceCount: 3);
@@ -84,7 +82,7 @@ void M2()
8482

8583
using var progress = BufferedProgress.Create<object>(null);
8684

87-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First(), progress);
85+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First(), progress);
8886

8987
Assert.Null(results);
9088

@@ -99,12 +97,10 @@ void M2()
9997

10098
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Select(result => result.Location));
10199

102-
// Results are returned in a non-deterministic order, so we order them by location
103-
var orderedResults = results.OrderBy(r => r.Location, new OrderLocations()).ToArray();
104-
Assert.Equal("A", orderedResults[0].ContainingType);
105-
Assert.Equal("B", orderedResults[2].ContainingType);
106-
Assert.Equal("M", orderedResults[1].ContainingMember);
107-
Assert.Equal("M2", orderedResults[3].ContainingMember);
100+
Assert.Equal("A", results[0].ContainingType);
101+
Assert.Equal("B", results[2].ContainingType);
102+
Assert.Equal("M", results[1].ContainingMember);
103+
Assert.Equal("M2", results[3].ContainingMember);
108104

109105
AssertValidDefinitionProperties(results, 0, Glyph.FieldPublic);
110106
AssertHighlightCount(results, expectedDefinitionCount: 1, expectedWrittenReferenceCount: 0, expectedReferenceCount: 3);
@@ -132,7 +128,7 @@ void M2()
132128
}";
133129
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
134130

135-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
131+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
136132
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Select(result => result.Location));
137133

138134
var textElement = results[0].Text as ClassifiedTextElement;
@@ -141,11 +137,9 @@ void M2()
141137

142138
Assert.Equal("class A", actualText);
143139

144-
// Results are returned in a non-deterministic order, so we order them by location
145-
var orderedResults = results.OrderBy(r => r.Location, new OrderLocations()).ToArray();
146-
Assert.Equal("B", orderedResults[1].ContainingType);
147-
Assert.Equal("B", orderedResults[2].ContainingType);
148-
Assert.Equal("M2", orderedResults[2].ContainingMember);
140+
Assert.Equal("B", results[1].ContainingType);
141+
Assert.Equal("B", results[2].ContainingType);
142+
Assert.Equal("M2", results[2].ContainingMember);
149143

150144
AssertValidDefinitionProperties(results, 0, Glyph.ClassInternal);
151145
AssertHighlightCount(results, expectedDefinitionCount: 1, expectedWrittenReferenceCount: 0, expectedReferenceCount: 2);
@@ -175,15 +169,13 @@ void M2()
175169

176170
await using var testLspServer = await CreateTestLspServerAsync(markups, mutatingLspWorkspace, new InitializationOptions { ClientCapabilities = CapabilitiesWithVSExtensions });
177171

178-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
172+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
179173
AssertLocationsEqual(testLspServer.GetLocations("reference"), results.Select(result => result.Location));
180174

181-
// Results are returned in a non-deterministic order, so we order them by location
182-
var orderedResults = results.OrderBy(r => r.Location, new OrderLocations()).ToArray();
183-
Assert.Equal("A", orderedResults[0].ContainingType);
184-
Assert.Equal("B", orderedResults[2].ContainingType);
185-
Assert.Equal("M", orderedResults[1].ContainingMember);
186-
Assert.Equal("M2", orderedResults[3].ContainingMember);
175+
Assert.Equal("A", results[0].ContainingType);
176+
Assert.Equal("B", results[2].ContainingType);
177+
Assert.Equal("M", results[1].ContainingMember);
178+
Assert.Equal("M2", results[3].ContainingMember);
187179

188180
AssertValidDefinitionProperties(results, 0, Glyph.FieldPublic);
189181
AssertHighlightCount(results, expectedDefinitionCount: 1, expectedWrittenReferenceCount: 0, expectedReferenceCount: 3);
@@ -199,7 +191,7 @@ public async Task TestFindAllReferencesAsync_InvalidLocation(bool mutatingLspWor
199191
}";
200192
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
201193

202-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
194+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
203195
Assert.Empty(results);
204196
}
205197

@@ -218,7 +210,7 @@ void M()
218210
}";
219211
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
220212

221-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
213+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
222214
Assert.NotNull(results[0].Location.Uri);
223215
AssertHighlightCount(results, expectedDefinitionCount: 0, expectedWrittenReferenceCount: 0, expectedReferenceCount: 1);
224216
}
@@ -240,7 +232,7 @@ void M()
240232
";
241233
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
242234

243-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
235+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
244236

245237
// Namespace source definitions and references should have locations:
246238
Assert.True(results.All(r => r.Location != null));
@@ -267,7 +259,7 @@ void M()
267259
";
268260
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
269261

270-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
262+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
271263
AssertHighlightCount(results, expectedDefinitionCount: 1, expectedWrittenReferenceCount: 1, expectedReferenceCount: 1);
272264
}
273265

@@ -279,7 +271,7 @@ public async Task TestFindAllReferencesAsync_StaticClassification(bool mutatingL
279271
";
280272
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, CapabilitiesWithVSExtensions);
281273

282-
var results = await RunFindAllReferencesAsync<LSP.VSInternalReferenceItem>(testLspServer, testLspServer.GetLocations("caret").First());
274+
var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First());
283275

284276
// Ensure static definitions and references are only classified once
285277
var textRuns = ((ClassifiedTextElement)results.First().Text).Runs;
@@ -295,11 +287,22 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr
295287
PartialResultToken = progress
296288
};
297289

298-
internal static async Task<T[]> RunFindAllReferencesAsync<T>(TestLspServer testLspServer, LSP.Location caret, IProgress<object> progress = null)
290+
internal static async Task<LSP.VSInternalReferenceItem[]> RunFindAllReferencesAsync(TestLspServer testLspServer, LSP.Location caret, IProgress<object> progress = null)
291+
{
292+
var results = await testLspServer.ExecuteRequestAsync<LSP.ReferenceParams, LSP.VSInternalReferenceItem[]>(LSP.Methods.TextDocumentReferencesName,
293+
CreateReferenceParams(caret, progress), CancellationToken.None);
294+
// Results are returned in a non-deterministic order, so we order them by location
295+
var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray();
296+
return orderedResults;
297+
}
298+
299+
internal static async Task<LSP.Location[]> RunFindAllReferencesNonVSAsync(TestLspServer testLspServer, LSP.Location caret, IProgress<object> progress = null)
299300
{
300-
var results = await testLspServer.ExecuteRequestAsync<LSP.ReferenceParams, T[]>(LSP.Methods.TextDocumentReferencesName,
301+
var results = await testLspServer.ExecuteRequestAsync<LSP.ReferenceParams, LSP.Location[]>(LSP.Methods.TextDocumentReferencesName,
301302
CreateReferenceParams(caret, progress), CancellationToken.None);
302-
return results?.Cast<T>()?.ToArray();
303+
// Results are returned in a non-deterministic order, so we order them by location
304+
var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray();
305+
return orderedResults;
303306
}
304307

305308
private static void AssertValidDefinitionProperties(LSP.VSInternalReferenceItem[] referenceItems, int definitionIndex, Glyph definitionGlyph)

0 commit comments

Comments
 (0)