Skip to content

Commit 2c1b352

Browse files
authored
add retry logic to the analyze test (#313)
I have been noticing a bunch of flakes on this test due to a race condition of the analyzer picking up the new files and us asking for errors. This allows us to retry with a back off until we see the error show up, allowing the test to pass quickly after the error does appear.
1 parent e8c89a4 commit 2c1b352

File tree

2 files changed

+42
-31
lines changed

2 files changed

+42
-31
lines changed

pkgs/dart_mcp_server/test/test_harness.dart

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ import 'package:test/test.dart';
2626
import 'package:test_process/test_process.dart';
2727
import 'package:unified_analytics/unified_analytics.dart';
2828

29+
Future<T> callWithRetry<T>(
30+
FutureOr<T> Function() fn, {
31+
int maxTries = 5,
32+
}) async {
33+
var tryCount = 0;
34+
while (true) {
35+
try {
36+
return await fn();
37+
} catch (_) {
38+
if (tryCount++ >= maxTries) rethrow;
39+
}
40+
await Future<void>.delayed(Duration(milliseconds: 100 * tryCount));
41+
}
42+
}
43+
2944
/// A full environment for integration testing the MCP server.
3045
///
3146
/// - Runs the counter app at `test_fixtures/counter_app` using `flutter run`.
@@ -187,17 +202,10 @@ class TestHarness {
187202
CallToolRequest request, {
188203
int maxTries = 5,
189204
bool expectError = false,
190-
}) async {
191-
var tryCount = 0;
192-
while (true) {
193-
try {
194-
return await callTool(request, expectError: expectError);
195-
} catch (_) {
196-
if (tryCount++ >= maxTries) rethrow;
197-
}
198-
await Future<void>.delayed(Duration(milliseconds: 100 * tryCount));
199-
}
200-
}
205+
}) => callWithRetry(
206+
() => callTool(request, expectError: expectError),
207+
maxTries: maxTries,
208+
);
201209

202210
/// Calls [getPrompt] on the [mcpServerConnection].
203211
Future<GetPromptResult> getPrompt(GetPromptRequest request) =>

pkgs/dart_mcp_server/test/tools/analyzer_test.dart

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -309,27 +309,30 @@ void main() {
309309
],
310310
},
311311
);
312-
final result = await testHarness.callToolWithRetry(request, maxTries: 10);
313-
expect(result.isError, isNot(true));
314-
expect(result.content, hasLength(2));
315-
expect(
316-
result.content,
317-
containsAll([
318-
isA<TextContent>().having(
319-
(t) => t.text,
320-
'text',
321-
contains(
322-
"The argument type 'String' can't be assigned to the "
323-
"parameter type 'num'.",
312+
// It may take a bit for the errors to show up.
313+
await callWithRetry(() async {
314+
final result = await testHarness.callTool(request);
315+
expect(result.isError, isNot(true));
316+
expect(result.content, hasLength(2));
317+
expect(
318+
result.content,
319+
containsAll([
320+
isA<TextContent>().having(
321+
(t) => t.text,
322+
'text',
323+
contains(
324+
"The argument type 'String' can't be assigned to the "
325+
"parameter type 'num'.",
326+
),
324327
),
325-
),
326-
isA<TextContent>().having(
327-
(t) => t.text,
328-
'text',
329-
contains("Undefined name 'foo'"),
330-
),
331-
]),
332-
);
328+
isA<TextContent>().having(
329+
(t) => t.text,
330+
'text',
331+
contains("Undefined name 'foo'"),
332+
),
333+
]),
334+
);
335+
}, maxTries: 10);
333336
});
334337

335338
test('can look up symbols in a workspace', () async {

0 commit comments

Comments
 (0)