Add more tests for async*/await-for operations.

Change-Id: I2c8ffb8a6738b8dee43cfdf85be0c54d2735b6cc
Reviewed-on: https://dart-review.googlesource.com/c/85391
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/tests/language_2/async_star/async_star_await_for_test.dart b/tests/language_2/async_star/async_star_await_for_test.dart
new file mode 100644
index 0000000..0493a1f
--- /dev/null
+++ b/tests/language_2/async_star/async_star_await_for_test.dart
@@ -0,0 +1,376 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that `await for` and `async*` interact correctly.
+
+// An `await for` must pause its subscription immediately
+// if the `await for` body does anything asynchronous
+// (any `await`, `await for`, or pausing at a `yield`/`yield*`)
+// A pause happening synchronously in an event delivery
+// must pause the `sync*` method at the `yield` sending the event.
+// A break happening synchronously in an event delivery,
+// or while paused at a `yield`, must exit at that `yield`.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+Stream<int> stream(List<String> log) async* {
+  log.add("^");
+  try {
+    log.add("?1");
+    yield 1;
+    log.add("?2");
+    yield 2;
+    log.add("?3");
+    yield 3;
+  } finally {
+    log.add(r"$");
+  }
+}
+
+Stream<int> consume(List<String> log,
+    {int breakAt = -1,
+    int yieldAt = -1,
+    int yieldStarAt = -1,
+    int pauseAt = -1}) async* {
+  // Create stream.
+  var s = stream(log);
+  log.add("(");
+  // The "consume loop".
+  await for (var event in s) {
+    // Should be acting synchronously wrt. the delivery of the event.
+    // The source stream should be at the yield now.
+    log.add("!$event");
+    if (event == pauseAt) {
+      log.add("p$event[");
+      // Async operation causes subscription to pause.
+      // Nothing should happen in the source stream
+      // until the end of the loop body where the subscription is resumed.
+      await Future.delayed(Duration(microseconds: 1));
+      log.add("]");
+    }
+    if (event == yieldAt) {
+      log.add("y$event[");
+      // Yield may cause subscription to pause or cancel.
+      // This loop should stay at the yield until the event has been delieverd.
+      // If the receiver pauses or cancels, we delay or break the loop here.
+      yield event;
+      log.add("]");
+    }
+    if (event == yieldStarAt) {
+      log.add("Y$event[");
+      // Yield* will always cause the subscription for this loop to pause.
+      // If the listener pauses, this stream is paused. If the listener cancels,
+      // this stream is cancelled, and the yield* acts like return, cancelling
+      // the loop subscription and waiting for the cancel future.
+      yield* Stream<int>.fromIterable([event]);
+      log.add("]");
+    }
+    if (event == breakAt) {
+      log.add("b$event");
+      // Breaks the loop. This cancels the loop subscription and waits for the
+      // cancel future.
+      break;
+    }
+  }
+  // Done event from stream or cancel future has completed.
+  log.add(")");
+}
+
+main() async {
+  asyncStart();
+
+  // Just run the loop over the stream. The consume stream emits no events.
+  {
+    var log = <String>[];
+    await for (var _ in consume(log)) {
+      throw "unreachable";
+    }
+    await Future.delayed(Duration(milliseconds: 1));
+    var trace = log.join("");
+    Expects.equals(r"(^?1!1?2!2?3!3$)", trace, "straight through");
+  }
+
+  // Pause at 1, then resume.
+  // Consume loop forces a pause when it receives the 1 event.
+  // Nothing should happen until that pause is resumed.
+  {
+    var log = <String>[];
+    await for (var _ in consume(log, pauseAt: 1)) {
+      throw "unreachable";
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "pause at 1";
+    if (trace.contains("p1[?2")) {
+      message += " (did not pause in time)";
+    }
+    Expects.equals(r"(^?1!1p1[]?2!2?3!3$)", trace, message);
+  }
+
+  // Break at 1.
+  // Consume loop breaks after receiving the 1 event.
+  // The consume stream emits no events.
+  {
+    var log = <String>[];
+    await for (var _ in consume(log, breakAt: 1)) {
+      throw "unreachable";
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "break at 1";
+    if (trace.contains("b1?2")) {
+      message += " (did not cancel in time)";
+    }
+    Expects.equals(r"(^?1!1b1$)", trace, message);
+  }
+
+  // Pause then break at 1.
+  // Consume loop pauses after receiving the 1 event,
+  // then breaks before resuming. It should still be at the yield.
+  // The consume stream emits no events.
+  {
+    var log = <String>[];
+    await for (var _ in consume(log, pauseAt: 1, breakAt: 1)) {
+      throw "unreachable";
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "pause then break at 1";
+    if (trace.contains("p1[?2")) {
+      message += " (did not pause in time)";
+    }
+    if (trace.contains("b1?2")) {
+      message += " (did not cancel in time)";
+    }
+    Expects.equals(r"(^?1!1p1[]b1$)", trace, message);
+  }
+
+  // Yield at 1.
+  // The consume loop re-emits the 1 event.
+  // The test loop should receive that event while the consume loop is still
+  // at the yield statement.
+  // The consume loop may or may not pause, it should make no difference.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldAt: 1)) {
+      log.add("e$s");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield at 1";
+    if (trace.contains("y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    Expects.equals(r"(^?1!1y1[e1]?2!2?3!3$)", trace, message);
+  }
+
+  // Yield at 1, then pause at yield.
+  // The consume loop re-emits the 1 event.
+  // The test loop should receive that event while the consume loop is still
+  // at the yield statement.
+  // The test loop then pauses.
+  // Nothing should happen in either the original yield
+  // or the consume-function yield until the test loop ends.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldAt: 1)) {
+      log.add("e$s<");
+      // Force pause at yield.
+      await Future.delayed(Duration(milliseconds: 1));
+      log.add(">");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield at 1, pause at yield";
+    if (trace.contains("y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    if (trace.contains("e1<?2")) {
+      message += " (did not pause in time)";
+    }
+    Expects.equals(r"(^?1!1y1[e1<>]?2!2?3!3$)", trace, message);
+  }
+
+  // Yield at 1, then break at yield.
+  // The consume loop re-emits the 1 event.
+  // The test loop should receive that event while the consume loop is still
+  // at the yield statement.
+  // The test loop then breaks. That makes the consume loop yield return,
+  // breaking the consume loop, which makes the source yield return.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldAt: 1)) {
+      log.add("e${s}B$s");
+      break; // Force break at yield*.
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield at 1, break at yield";
+    if (trace.contains("y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    if (trace.contains("B1?2")) {
+      message += " (did not break in time)";
+    }
+    Expects.equals(r"(^?1!1y1[e1B1$)", trace, message);
+  }
+
+  // Yield* at 1.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`, which again happens before the source
+  // stream continues from its `yield`.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1)) {
+      log.add("e$s");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* at 1";
+    if (trace.contains("Y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    Expects.equals(r"(^?1!1Y1[e1]?2!2?3!3$)", trace, message);
+  }
+
+  // Yield* at 1, pause at yield.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`. The test loop then force a pause.
+  // Nothing further should happen during that pause.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1)) {
+      log.add("e$s<");
+      await Future.delayed(Duration(milliseconds: 1)); // force pause.
+      log.add(">");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* then pause at 1";
+    if (trace.contains("Y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    if (trace.contains("e1<?2")) {
+      message += " (did not pause in time)";
+    }
+    Expects.equals(r"(^?1!1Y1[e1<>]?2!2?3!3$)", trace, message);
+  }
+
+  // Yield* at 1, then break at 1.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`.
+  // When the consume loop continues, it breaks,
+  // forcing the waiting source yield to return.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1, breakAt: 1)) {
+      log.add("e$s");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* then pause at 1";
+    if (trace.contains("Y1[?2")) {
+      message += " (did not wait for delivery)";
+    }
+    Expects.equals(r"(^?1!1Y1[e1]b1$)", trace, message);
+  }
+
+  // Yield* at 1, pause at yield, then break at 1.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`. After the `yield*`, the consume loop breaks.
+  // This forces the waiting source yield to return.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1, breakAt: 1)) {
+      log.add("e$s<");
+      await Future.delayed(Duration(milliseconds: 1)); // force pause.
+      log.add(">");
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* then pause at 1";
+    Expects.equals(r"(^?1!1Y1[e1<>]b1$)", trace, message);
+  }
+
+  // Yield* at 1, break at yield.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`. The test loop then breaks,
+  // forcing the two waiting yields to return.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1)) {
+      log.add("e${s}B$s");
+      break;
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* then break at 1";
+    if (trace.contains("Y1[?2")) {
+      message += " (did not deliver event in time)";
+    }
+    if (trace.contains("e1?2")) {
+      message += " (did not cancel in time)";
+    }
+    Expects.equals(r"(^?1!1Y1[e1B1$)", trace, message);
+  }
+
+  // Yield* at 1, pause at yield, then break at yield.
+  // The consume loop re-emits a stream containing the 1 event.
+  // The test loop should receive that event before the consume loop
+  // continues from the `yield*`. The test loop then forces a pause,
+  // and then breaks before that pause is resumed.
+  // This forces the two waiting yields to return.
+  {
+    var log = <String>[];
+    await for (var s in consume(log, yieldStarAt: 1)) {
+      log.add("e$s<");
+      await Future.delayed(Duration(milliseconds: 1)); // force pause.
+      log.add(">B$s");
+      break; // And break.
+    }
+    await Future.delayed(Duration(milliseconds: 10));
+    var trace = log.join("");
+    String message = "yield* then pause then break at 1";
+    Expects.equals(r"(^?1!1Y1[e1<>B1$)", trace, message);
+  }
+
+  Expects.summarize();
+  asyncEnd();
+}
+
+class Expects {
+  static var _errors = [];
+  static int _tests = 0;
+  static void summarize() {
+    if (_errors.isNotEmpty) {
+      var buffer = StringBuffer();
+      for (var es in _errors) {
+        buffer.writeln("FAILURE:");
+        buffer.writeln(es[0]); // error
+        buffer.writeln(es[1]); // stack trace
+      }
+      ;
+      buffer.writeln("Expectations failed: ${_errors.length}"
+          ", succeeded: ${_tests - _errors.length}");
+      throw ExpectException(buffer.toString());
+    }
+  }
+
+  static void equals(o1, o2, String message) {
+    _tests++;
+    try {
+      Expect.equals(o1, o2, message);
+    } on ExpectException catch (e) {
+      var stack = StackTrace.current;
+      _errors.add([e, stack]);
+    }
+  }
+}
diff --git a/tests/language_2/async_star/async_star_cancel_test.dart b/tests/language_2/async_star/async_star_cancel_test.dart
new file mode 100644
index 0000000..c23c6ba
--- /dev/null
+++ b/tests/language_2/async_star/async_star_cancel_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that stream cancellation is checked immediately after delivering the
+// event, and before continuing after the yield.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() async {
+  asyncStart();
+  var log = [];
+  Stream<int> f() async* {
+    try {
+      log.add("-1");
+      yield 1;
+      log.add("-2");
+      yield 2;
+    } finally {
+      log.add("x");
+    }
+  }
+
+  var completer = Completer();
+  var s;
+  s = f().listen((e) {
+    log.add("+$e");
+    // The `cancel` operation makes all `yield` operations act as returns.
+    // It should make the `finally` block in `f` log an "x",
+    // and nothing else.
+    completer.complete(s.cancel());
+  }, onError: (e) {
+    // Should never be reached, but if it does, we'll make the await
+    // below terminate.
+    completer.complete(new Future.sync(() {
+      Expect.fail("$e");
+    }));
+  }, onDone: () {
+    completer.complete(null);
+  });
+  await completer.future;
+  Expect.listEquals(["-1", "+1", "x"], log, "cancel");
+  asyncEnd();
+}
diff --git a/tests/language_2/async_star/async_star_invalid_test.dart b/tests/language_2/async_star/async_star_invalid_test.dart
new file mode 100644
index 0000000..529cf25
--- /dev/null
+++ b/tests/language_2/async_star/async_star_invalid_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that various invalid uses of `yield` are disallowed.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+var yield = 42;
+
+main() async {
+  asyncStart();
+  Stream<String> f() async* {
+    // Invalid syntax.
+    yield ("a", "b"); //# 01: compile-time error
+    yield yield "twice"; //# 02: compile-time error
+
+    // Valid but curious syntax.
+    yield throw "throw"; //# 03: runtime error
+
+    // Type error.
+    yield* "one"; //# 04: compile-time error
+
+    label: yield "ok";
+  }
+  var completer = Completer();
+  f().listen(completer.complete, onError: completer.completeError,
+      onDone: () {
+        if (!completer.isCompleted) completer.completeError("not ok?");
+      });
+  Expect.equals("ok", await completer.future);
+  asyncEnd();
+}
diff --git a/tests/language_2/async_star/async_star_test.dart b/tests/language_2/async_star/async_star_test.dart
new file mode 100644
index 0000000..819039e
--- /dev/null
+++ b/tests/language_2/async_star/async_star_test.dart
@@ -0,0 +1,195 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() async {
+  asyncStart();
+  // Normal operations.
+  {
+    Stream<int> f() async* {
+      yield 1;
+      yield 2;
+      yield 3;
+    }
+
+    Expect.listEquals([1, 2, 3], await f().toList(), "basic1");
+  }
+
+  {
+    Stream<int> f() async* {
+      yield 1;
+      yield 2;
+      yield 3;
+    }
+
+    var log = [];
+    var completer = Completer();
+    f().listen(log.add,
+        onError: (e) {
+          // Shouldn't be reached.
+          completer.complete(new Future.sync(() {
+            Expect.fail("$e");
+          }));
+        },
+        onDone: () => completer.complete(null));
+    await completer.future;
+    Expect.listEquals([1, 2, 3], log, "basic2");
+  }
+
+  {
+    var log = [];
+    Stream<int> f() async* {
+      log.add("-1");
+      yield 1;
+      log.add("-2");
+      yield 2;
+    }
+
+    await f().forEach((e) {
+      log.add("+$e");
+    });
+    Expect.listEquals(["-1", "+1", "-2", "+2"], log, "basic3");
+  }
+
+  {
+    var log = [];
+    Stream<int> f() async* {
+      log.add("-1");
+      yield 1;
+      log.add("-2");
+      yield 2;
+    }
+
+    await for (var e in f()) {
+      log.add("+$e");
+    }
+    Expect.listEquals(["-1", "+1", "-2", "+2"], log, "basic4");
+  }
+
+  // async
+  {
+    Stream<int> f() async* {
+      yield 1;
+      await Future(() {});
+      yield 2;
+      await Future(() {});
+      yield 3;
+    }
+
+    Expect.listEquals([1, 2, 3], await f().toList(), "async");
+  }
+
+  // Yield*
+  {
+    Stream<int> f(n) async* {
+      yield n;
+      if (n == 0) return;
+      yield* f(n - 1);
+      yield n;
+    }
+
+    Expect.listEquals([3, 2, 1, 0, 1, 2, 3], await f(3).toList(), "yield*");
+  }
+
+  // Errors
+  {
+    var log = [];
+    Stream<int> f() async* {
+      yield 1;
+      throw "error";
+    }
+
+    await f().handleError((e) {
+      log.add(e);
+    }).forEach(log.add);
+    Expect.listEquals([1, "error"], log, "error");
+  }
+
+  {
+    var log = [];
+    Stream<int> f() async* {
+      yield 1;
+      yield* Future<int>.error("error").asStream(); // Emits error as error.
+      yield 3;
+    }
+
+    await f().handleError((e) {
+      log.add(e);
+    }).forEach(log.add);
+    Expect.listEquals([1, "error", 3], log, "error2");
+  }
+
+  // Pause is checked after delivering event.
+  {
+    var log = [];
+    Stream<int> f() async* {
+      log.add("-1");
+      yield 1;
+      log.add("-2");
+      yield 2;
+    }
+
+    var completer = Completer();
+    var s;
+    s = f().listen((e) {
+      log.add("+$e");
+      s.pause(Future(() {}));
+      log.add("++$e");
+    }, onError: (e) {
+      completer.complete(new Future.sync(() {
+        Expect.fail("$e");
+      }));
+    }, onDone: () => completer.complete(null));
+    await completer.future;
+    Expect.listEquals(["-1", "+1", "++1", "-2", "+2", "++2"], log, "pause");
+  }
+
+  // Await for-loop pauses between events.
+  {
+    var log = [];
+    Stream<int> f() async* {
+      log.add("-1");
+      yield 1;
+      log.add("-2");
+      yield 2;
+    }
+
+    await for (var e in f()) {
+      log.add("+$e");
+      await Future(() {}); // One timer tick.
+      log.add("++$e");
+    }
+    Expect.listEquals(["-1", "+1", "++1", "-2", "+2", "++2"], log, "looppause");
+  }
+
+  // Await for-loop break works immediately.
+  {
+    var log = [];
+    Stream<int> f() async* {
+      try {
+        log.add("-1");
+        yield 1;
+        log.add("-2");
+        yield 2;
+        log.add("-3");
+        yield 3;
+      } finally {
+        log.add("x");
+      }
+    }
+
+    await for (var e in f()) {
+      log.add("+$e");
+      await Future(() {}); // One timer tick, pauses function at yield.
+      log.add("++$e");
+      if (e == 2) break;
+    }
+    Expect.listEquals(
+        ["-1", "+1", "++1", "-2", "+2", "++2", "x"], log, "loop-pause-break");
+  }
+  asyncEnd();
+}
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index a2102b3..1edba47 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -5,6 +5,8 @@
 
 [ $compiler == dart2js ]
 arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
 bit_operations_test: RuntimeError, OK # non JS number semantics
 bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index feca149..9e924cf 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -12,6 +12,9 @@
 accessor_conflict_import_test: CompileTimeError # Issue 25626
 additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
 assertion_test: RuntimeError # Issue 30326; Expect.equals(expected: <1>, actual: <0>) fails.
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
 async_star_test/01: RuntimeError
 async_star_test/03: RuntimeError
 async_star_test/04: RuntimeError
@@ -158,6 +161,8 @@
 void/void_type_usage_test/final_local_for_in2: MissingCompileTimeError
 
 [ $compiler == dartdevk ]
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
 built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 30450, test name contains hyphen
 built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 30450, test name contains hyphen
 built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 30450, test name contains hyphen
@@ -317,6 +322,7 @@
 [ $compiler == dartdevc || $compiler == dartdevk ]
 arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 async_covariant_type_test: RuntimeError # Check too late
+async_star/async_star_await_for_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError # Issue 29920; Uncaught Expect.listEquals(list length, expected: <4>, actual: <3>) fails: Next element <*3>
 async_star_pause_test: RuntimeError # Uncaught Expect.listEquals(at index 2, expected: <0+>, actual: <0!>) fails
 async_star_test/02: RuntimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index b514980..bd08604 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -359,6 +359,10 @@
 vm/precompiled_static_initializer_test: Pass, Slow
 
 [ $compiler == dartkp && $mode == product && $runtime == dart_precompiled && $strong ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_invalid_test/none: RuntimeError
+async_star/async_star_test: RuntimeError
 vm/type_vm_test/28: MissingRuntimeError
 vm/type_vm_test/29: MissingRuntimeError
 vm/type_vm_test/30: MissingRuntimeError
@@ -406,6 +410,13 @@
 assertion_initializer_const_error2_test/cc11: Crash
 async_await_test: RuntimeError
 async_return_types_test/nestedFuture: Fail
+async_star/async_star_cancel_test: DartkCrash
+async_star/async_star_invalid_test/01: DartkCrash
+async_star/async_star_invalid_test/02: DartkCrash
+async_star/async_star_invalid_test/03: DartkCrash
+async_star/async_star_invalid_test/04: DartkCrash
+async_star/async_star_invalid_test/none: DartkCrash
+async_star/async_star_test: DartkCrash
 compile_time_constant_checked_test/02: MissingCompileTimeError
 covariance_type_parameter_test/01: RuntimeError
 covariance_type_parameter_test/02: RuntimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index c813c7b..d70b100 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -13,6 +13,15 @@
 [ $compiler != dart2analyzer && $runtime == dart_precompiled ]
 mixin_mixin2_test: Skip
 
+[ $compiler == precompiler && $runtime == dart_precompiled ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_invalid_test/01: MissingCompileTimeError
+async_star/async_star_invalid_test/02: MissingCompileTimeError
+async_star/async_star_invalid_test/04: MissingCompileTimeError
+async_star/async_star_invalid_test/none: RuntimeError
+async_star/async_star_test: RuntimeError
+
 [ $runtime == dart_precompiled && $minified ]
 cyclic_type_test/*: Skip
 enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index b696b0f..47d27f2 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -18,6 +18,9 @@
 set_literals/*: Skip
 
 [ $runtime == vm ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
 set_literals/*: Skip
 
 [ $arch == arm64 && $runtime == vm ]