22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5+ import 'dart:async' ;
56import 'dart:io' ;
67
78import 'package:test/test.dart' ;
@@ -23,16 +24,43 @@ void main() {
2324 });
2425
2526 test ('logs traffic to a file' , () async {
26- expect (
27- await File (logDescriptor.io.path).readAsLines (),
28- containsAll ([
29- allOf (startsWith ('<<<' ), contains ('"method":"initialize"' )),
30- allOf (startsWith ('>>>' ), contains ('"serverInfo"' )),
31- allOf (startsWith ('<<<' ), contains ('"notifications/initialized"' )),
32- ]),
27+ // It may take a bit for all the lines to show up in the log.
28+ await doWithRetries (
29+ () async => expect (
30+ await File (logDescriptor.io.path).readAsLines (),
31+ containsAll ([
32+ allOf (startsWith ('<<<' ), contains ('"method":"initialize"' )),
33+ allOf (startsWith ('>>>' ), contains ('"serverInfo"' )),
34+ allOf (startsWith ('<<<' ), contains ('"notifications/initialized"' )),
35+ ]),
36+ ),
3337 );
38+
3439 // Ensure the file handle is released before the file is cleaned up.
3540 await testHarness.serverConnectionPair.serverConnection.shutdown ();
41+
42+ // Wait for the process to release the file.
43+ await doWithRetries (() => File (logDescriptor.io.path).delete ());
3644 });
3745 });
3846}
47+
48+ /// Performs [action] up to [maxRetries] times, backing off an extra 50ms
49+ /// between each attempt.
50+ FutureOr <T > doWithRetries <T >(
51+ FutureOr <T > Function () action, {
52+ int maxRetries = 5 ,
53+ }) async {
54+ var count = 0 ;
55+ while (true ) {
56+ try {
57+ return await action ();
58+ } catch (_) {
59+ if (count == maxRetries) {
60+ rethrow ;
61+ }
62+ }
63+ count++ ;
64+ await Future <void >.delayed (Duration (milliseconds: 50 * count));
65+ }
66+ }
0 commit comments