Fix one cause of timeouts in tests

Change-Id: I8514c7a1e89c69bbbf11882fa734903cd7c7569c
Reviewed-on: https://dart-review.googlesource.com/68430
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 87d0440..3a522d6 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -157,12 +157,15 @@
 
   @failingTest
   @override
-  test_errorInPart() async => super.test_errorInPart();
+  test_errorInPart() => super.test_errorInPart();
 
   @override
-  test_fileDoesNotExist() async => super.test_fileDoesNotExist();
+  test_fileDoesNotExist() => super.test_fileDoesNotExist();
+
+  @failingTest
+  @override
+  test_hasErrors() => super.test_hasErrors();
 
   @override
-  test_removeContextAfterRequest() async =>
-      super.test_removeContextAfterRequest();
+  test_removeContextAfterRequest() => super.test_removeContextAfterRequest();
 }
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index a6c2125..e4b0eb8 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -262,8 +262,9 @@
    * Completes with a successful [Response] for the given [request].
    * Otherwise fails.
    */
-  Future<Response> waitResponse(Request request) async {
-    return serverChannel.sendRequest(request);
+  Future<Response> waitResponse(Request request,
+      {bool throwOnError = true}) async {
+    return serverChannel.sendRequest(request, throwOnError: throwOnError);
   }
 }
 
diff --git a/pkg/analysis_server/test/edit/postfix_completion_test.dart b/pkg/analysis_server/test/edit/postfix_completion_test.dart
index 7e9dcce..844ac9b 100644
--- a/pkg/analysis_server/test/edit/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/edit/postfix_completion_test.dart
@@ -79,7 +79,7 @@
     var params = new EditGetPostfixCompletionParams(testFile, key, offset);
     var request =
         new Request('0', "edit.isPostfixCompletionApplicable", params.toJson());
-    Response response = await waitResponse(request);
+    Response response = await waitResponse(request, throwOnError: false);
     var isApplicable =
         new EditIsPostfixCompletionApplicableResult.fromResponse(response);
     if (!isApplicable.value) {
@@ -87,7 +87,7 @@
     }
     request = new EditGetPostfixCompletionParams(testFile, key, offset)
         .toRequest('1');
-    response = await waitResponse(request);
+    response = await waitResponse(request, throwOnError: false);
     var result = new EditGetPostfixCompletionResult.fromResponse(response);
     change = result.change;
   }
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index eb6a7d8f..438f6d1c 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -611,6 +611,11 @@
 
   @failingTest
   @override
+  test_resetOnAnalysisSetChanged_overlay() =>
+      super.test_resetOnAnalysisSetChanged_overlay();
+
+  @failingTest
+  @override
   test_resetOnAnalysisSetChanged_watch_otherFile() =>
       super.test_resetOnAnalysisSetChanged_watch_otherFile();
 
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index c1915b3..55727eb 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -260,4 +260,9 @@
 class SortMembersTest_UseCFE extends SortMembersTest {
   @override
   bool get useCFE => true;
+
+  @failingTest
+  @override
+  test_OK_directives_withAnnotation() =>
+      super.test_OK_directives_withAnnotation();
 }
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_test.dart
index a4912ac..ee09be3d 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -18,7 +19,7 @@
 
 @reflectiveTest
 class GetErrorsTest extends AbstractAnalysisServerIntegrationTest {
-  test_getErrors() {
+  test_getErrors() async {
     String pathname = sourcePath('test.dart');
     String text = r'''
 main() {
@@ -26,13 +27,9 @@
 }''';
     writeFile(pathname, text);
     standardAnalysisSetup();
-    Future finishTest() {
-      return sendAnalysisGetErrors(pathname).then((result) {
-        expect(result.errors, equals(currentAnalysisErrors[pathname]));
-      });
-    }
-
-    return analysisFinished.then((_) => finishTest());
+    await analysisFinished;
+    AnalysisGetErrorsResult result = await sendAnalysisGetErrors(pathname);
+    expect(result.errors, equals(currentAnalysisErrors[pathname]));
   }
 }
 
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index d39d097..15a77db 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -51,6 +51,7 @@
       new StreamController<Response>.broadcast();
   StreamController<Notification> notificationController =
       new StreamController<Notification>(sync: true);
+  Completer<Response> errorCompleter;
 
   List<Response> responsesReceived = [];
   List<Notification> notificationsReceived = [];
@@ -81,6 +82,11 @@
       return;
     }
     notificationsReceived.add(notification);
+    if (errorCompleter != null && notification.event == 'server.error') {
+      errorCompleter.completeError(
+          new ServerError(notification.params['message']),
+          new StackTrace.fromString(notification.params['stackTrace']));
+    }
     // Wrap send notification in future to simulate websocket
     // TODO(scheglov) ask Dan why and decide what to do
 //    new Future(() => notificationController.add(notification));
@@ -88,16 +94,22 @@
   }
 
   /**
-   * Simulate request/response pair.
+   * Send the given [request] to the server and return a future that will
+   * complete when a response associated with the [request] has been received.
+   * The value of the future will be the received response. If [throwOnError] is
+   * `true` (the default) then the returned future will throw an exception if a
+   * server error is reported before the response has been received.
    */
-  Future<Response> sendRequest(Request request) {
+  Future<Response> sendRequest(Request request, {bool throwOnError = true}) {
+    // TODO(brianwilkerson) Attempt to remove the `throwOnError` parameter and
+    // have the default behavior be the only behavior.
     // No further requests should be sent after the connection is closed.
     if (_closed) {
       throw new Exception('sendRequest after connection closed');
     }
     // Wrap send request in future to simulate WebSocket.
     new Future(() => requestController.add(request));
-    return waitForResponse(request);
+    return waitForResponse(request, throwOnError: throwOnError);
   }
 
   @override
@@ -111,10 +123,28 @@
     new Future(() => responseController.add(response));
   }
 
-  Future<Response> waitForResponse(Request request) {
+  /**
+   * Return a future that will complete when a response associated with the
+   * given [request] has been received. The value of the future will be the
+   * received response. If [throwOnError] is `true` (the default) then the
+   * returned future will throw an exception if a server error is reported
+   * before the response has been received.
+   * 
+   * Unlike [sendRequest], this method assumes that the [request] has already
+   * been sent to the server.
+   */
+  Future<Response> waitForResponse(Request request,
+      {bool throwOnError = true}) {
+    // TODO(brianwilkerson) Attempt to remove the `throwOnError` parameter and
+    // have the default behavior be the only behavior.
     String id = request.id;
-    return responseController.stream
-        .firstWhere((response) => response.id == id);
+    Future<Response> response =
+        responseController.stream.firstWhere((response) => response.id == id);
+    if (throwOnError) {
+      errorCompleter ??= new Completer<Response>();
+      return Future.any([response, errorCompleter.future]);
+    }
+    return response;
   }
 }
 
@@ -194,6 +224,16 @@
   bool exists() => null;
 }
 
+class ServerError implements Exception {
+  final message;
+
+  ServerError(this.message);
+
+  String toString() {
+    return "Server Error: $message";
+  }
+}
+
 class StringTypedMock {
   String _toString;
 
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index d764570..d707da7 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -1086,8 +1086,7 @@
   @failingTest
   @override
   test_class_extendsTypeB() {
-    fail('Timeout');
-//    return callFailingTest(super.test_class_extendsTypeB);
+    return callFailingTest(super.test_class_extendsTypeB);
   }
 
   @failingTest
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index 244e7c8..931d87e7 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -92,19 +92,18 @@
     });
   }
 
-  static Future requestHandler_futureException() {
+  static Future requestHandler_futureException() async {
     SocketServer server = _createSocketServer();
     MockServerChannel channel = new MockServerChannel();
     server.createAnalysisServer(channel);
     _MockRequestHandler handler = new _MockRequestHandler(true);
     server.analysisServer.handlers = [handler];
     var request = new ServerGetVersionParams().toRequest('0');
-    return channel.sendRequest(request).then((Response response) {
-      expect(response.id, equals('0'));
-      expect(response.error, isNull);
-      channel.expectMsgCount(responseCount: 1, notificationCount: 2);
-      expect(channel.notificationsReceived[1].event, SERVER_NOTIFICATION_ERROR);
-    });
+    Response response = await channel.sendRequest(request, throwOnError: false);
+    expect(response.id, equals('0'));
+    expect(response.error, isNull);
+    channel.expectMsgCount(responseCount: 1, notificationCount: 2);
+    expect(channel.notificationsReceived[1].event, SERVER_NOTIFICATION_ERROR);
   }
 
   static SocketServer _createSocketServer() {
diff --git a/pkg/pkg.status b/pkg/pkg.status
index d6724a8..bc3a62d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -226,6 +226,9 @@
 async/test/stream_zip_test: SkipSlow # Times out. Issue 22050
 collection/test/unmodifiable_collection_test: SkipSlow # Times out. Issue 22050
 
+[ $compiler == none && !$preview_dart_2 ]
+analysis_server/test/analysis/get_errors_test: Fail
+
 [ $runtime == vm && $system == windows ]
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
 analysis_server/test/benchmarks_test: RuntimeError # Issue 32355