diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index fea54fb..9914dd2 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -4,11 +4,11 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:math' as math;
 
 import 'package:googleapis/bigquery/v2.dart' as bq;
 import 'package:googleapis_auth/auth_io.dart' as auth;
 import 'package:http/http.dart' as http;
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 
 import 'flutter_compact_formatter.dart';
@@ -30,54 +30,21 @@
 final String pub = path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', Platform.isWindows ? 'pub.bat' : 'pub');
 final String pubCache = path.join(flutterRoot, '.pub-cache');
 final String toolRoot = path.join(flutterRoot, 'packages', 'flutter_tools');
-
-/// The arguments to pass to `flutter test` (typically the local engine
-/// configuration) -- prefilled with the arguments passed to test.dart.
 final List<String> flutterTestArgs = <String>[];
 
 final bool useFlutterTestFormatter = Platform.environment['FLUTTER_TEST_FORMATTER'] == 'true';
 final bool canUseBuildRunner = Platform.environment['FLUTTER_TEST_NO_BUILD_RUNNER'] != 'true';
 
-/// The number of Cirrus jobs that run host-only devicelab tests in parallel.
-///
-/// WARNING: if you change this number, also change .cirrus.yml
-/// and make sure it runs _all_ shards.
-const int kDeviceLabShardCount = 6;
-
-/// The number of Cirrus jobs that run Web tests in parallel.
-///
-/// WARNING: if you change this number, also change .cirrus.yml
-/// and make sure it runs _all_ shards.
-///
-/// The last shard also runs the Web plugin tests.
-const int kWebShardCount = 6;
-
-/// Maximum number of Web tests to run in a single `flutter test`. We found that
-/// large batches can get flaky, possibly because we reuse a single instance of
-/// the browser, and after many tests the browser's state gets corrupted.
-const int kWebBatchSize = 20;
-
-/// Tests that we don't run on Web for various reasons.
-//
-// TODO(yjbanov): we're getting rid of these blacklists as part of https://github.com/flutter/flutter/projects/60
-const List<String> kWebTestDirectoryBlacklist = <String>[
-  'cupertino',
-  'examples',
-  'material',
-];
-const List<String> kWebTestFileBlacklist = <String>[
-  'test/widgets/heroes_test.dart',
-  'test/widgets/text_test.dart',
-  'test/widgets/selectable_text_test.dart',
-  'test/widgets/color_filter_test.dart',
-  'test/widgets/editable_text_cursor_test.dart',
-  'test/widgets/shadow_test.dart',
-  'test/widgets/raw_keyboard_listener_test.dart',
-  'test/widgets/editable_text_test.dart',
-  'test/widgets/widget_inspector_test.dart',
-  'test/widgets/draggable_test.dart',
-  'test/widgets/shortcuts_test.dart',
-];
+const Map<String, ShardRunner> _kShards = <String, ShardRunner>{
+  'tests': _runTests,
+  'web_tests': _runWebTests,
+  'tool_tests': _runToolTests,
+  'tool_coverage': _runToolCoverage,
+  'build_tests': _runBuildTests,
+  'coverage': _runCoverage,
+  'integration_tests': _runIntegrationTests,
+  'add2app_test': _runAdd2AppTest,
+};
 
 /// When you call this, you can pass additional arguments to pass custom
 /// arguments to flutter test. For example, you might want to call this
@@ -86,30 +53,31 @@
 ///
 /// To run the tool_tests part, run it with SHARD=tool_tests
 ///
-/// Examples:
+/// For example:
 /// SHARD=tool_tests bin/cache/dart-sdk/bin/dart dev/bots/test.dart
 /// bin/cache/dart-sdk/bin/dart dev/bots/test.dart --local-engine=host_debug_unopt
 Future<void> main(List<String> args) async {
   flutterTestArgs.addAll(args);
-  if (Platform.environment.containsKey(CIRRUS_TASK_NAME))
-    print('Running task: ${Platform.environment[CIRRUS_TASK_NAME]}');
-  print('═' * 80);
-  await _runSmokeTests();
-  print('═' * 80);
-  await selectShard(const <String, ShardRunner>{
-    'add_to_app_tests': _runAddToAppTests,
-    'build_tests': _runBuildTests,
-    'framework_coverage': _runFrameworkCoverage,
-    'framework_tests': _runFrameworkTests,
-    'hostonly_devicelab_tests': _runHostOnlyDeviceLabTests,
-    'tool_coverage': _runToolCoverage,
-    'tool_tests': _runToolTests,
-    'web_tests': _runWebTests,
-  });
+
+  final String shard = Platform.environment['SHARD'];
+  if (shard != null) {
+    if (!_kShards.containsKey(shard)) {
+      print('Invalid shard: $shard');
+      print('The available shards are: ${_kShards.keys.join(", ")}');
+      exit(1);
+    }
+    print('${bold}SHARD=$shard$reset');
+    await _kShards[shard]();
+  } else {
+    for (String currentShard in _kShards.keys) {
+      print('${bold}SHARD=$currentShard$reset');
+      await _kShards[currentShard]();
+      print('');
+    }
+  }
 }
 
 Future<void> _runSmokeTests() async {
-  print('${green}Running smoketests...$reset');
   // Verify that the tests actually return failure on failure and success on
   // success.
   final String automatedTests = path.join(flutterRoot, 'dev', 'automated_tests');
@@ -140,11 +108,10 @@
     script: path.join('test_smoke_test', 'pending_timer_fail_test.dart'),
     expectFailure: true,
     printOutput: false,
-    outputChecker: (CapturedOutput output) {
-      return output.stdout.contains('failingPendingTimerTest')
-        ? null
-        : 'Failed to find the stack trace for the pending Timer.';
-    }
+    outputChecker: (CapturedOutput output) =>
+      output.stdout.contains('failingPendingTimerTest')
+      ? null
+      : 'Failed to find the stack trace for the pending Timer.',
   );
   // We run the remaining smoketests in parallel, because they each take some
   // time to run (e.g. compiling), so we don't want to run them in series,
@@ -186,11 +153,8 @@
   );
 
   // Verify that we correctly generated the version file.
-  final String versionError = await verifyVersion(File(path.join(flutterRoot, 'version')));
-  if (versionError != null) {
-    print(redLine);
-    print(versionError);
-    print(redLine);
+  final bool validVersion = await verifyVersion(path.join(flutterRoot, 'version'));
+  if (!validVersion) {
     exit(1);
   }
 }
@@ -215,7 +179,7 @@
     final http.Client client = await auth.clientViaServiceAccount(accountCredentials, scopes);
     return bq.BigqueryApi(client);
   } catch (e) {
-    print('${red}Failed to get BigQuery API client.$reset');
+    print('Failed to get BigQuery API client.');
     print(e);
     return null;
   }
@@ -239,6 +203,7 @@
 
 Future<void> _runToolTests() async {
   final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
+  await _runSmokeTests();
 
   const String kDotShard = '.shard';
   const String kTest = 'test';
@@ -267,10 +232,11 @@
   await selectSubshard(subshards);
 }
 
-/// Verifies that AOT, APK, and IPA (if on macOS) builds the examples apps
-/// without crashing. It does not actually launch the apps. That happens later
-/// in the devicelab. This is just a smoke-test. In particular, this will verify
-/// we can build when there are spaces in the path name for the Flutter SDK and
+/// Verifies that AOT, APK, and IPA (if on macOS) builds the
+/// examples apps without crashing. It does not actually
+/// launch the apps. That happens later in the devicelab. This is
+/// just a smoke-test. In particular, this will verify we can build
+/// when there are spaces in the path name for the Flutter SDK and
 /// target app.
 Future<void> _runBuildTests() async {
   final Stream<FileSystemEntity> exampleDirectories = Directory(path.join(flutterRoot, 'examples')).list();
@@ -279,11 +245,10 @@
       continue;
     }
     final String examplePath = fileEntity.path;
+
     await _flutterBuildAot(examplePath);
     await _flutterBuildApk(examplePath);
-    if (Platform.isMacOS) {
-      await _flutterBuildIpa(examplePath);
-    }
+    await _flutterBuildIpa(examplePath);
   }
   // Web compilation tests.
   await _flutterBuildDart2js(path.join('dev', 'integration_tests', 'web'), path.join('lib', 'main.dart'));
@@ -291,44 +256,12 @@
   await _flutterBuildDart2js(path.join('dev', 'integration_tests', 'web_compile_tests'),
     path.join('lib', 'dart_io_import.dart'),
   );
-}
 
-Future<void> _flutterBuildAot(String relativePathToApplication) async {
-  print('${green}Testing AOT build$reset for $cyan$relativePathToApplication$reset...');
-  await runCommand(flutter,
-    <String>['build', 'aot', '-v'],
-    workingDirectory: path.join(flutterRoot, relativePathToApplication),
-  );
-}
-
-Future<void> _flutterBuildApk(String relativePathToApplication) async {
-  print('${green}Testing APK --debug build$reset for $cyan$relativePathToApplication$reset...');
-  await runCommand(flutter,
-    <String>['build', 'apk', '--debug', '-v'],
-    workingDirectory: path.join(flutterRoot, relativePathToApplication),
-  );
-}
-
-Future<void> _flutterBuildIpa(String relativePathToApplication) async {
-  assert(Platform.isMacOS);
-  print('${green}Testing IPA build$reset for $cyan$relativePathToApplication$reset...');
-  // Install Cocoapods.  We don't have these checked in for the examples,
-  // and build ios doesn't take care of it automatically.
-  final File podfile = File(path.join(flutterRoot, relativePathToApplication, 'ios', 'Podfile'));
-  if (podfile.existsSync()) {
-    await runCommand('pod',
-      <String>['install'],
-      workingDirectory: podfile.parent.path,
-    );
-  }
-  await runCommand(flutter,
-    <String>['build', 'ios', '--no-codesign', '--debug', '-v'],
-    workingDirectory: path.join(flutterRoot, relativePathToApplication),
-  );
+  print('${bold}DONE: All build tests successful.$reset');
 }
 
 Future<void> _flutterBuildDart2js(String relativePathToApplication, String target, { bool expectNonZeroExit = false }) async {
-  print('${green}Testing Dart2JS build$reset for $cyan$relativePathToApplication$reset...');
+  print('Running Dart2JS build tests...');
   await runCommand(flutter,
     <String>['build', 'web', '-v', '--target=$target'],
     workingDirectory: path.join(flutterRoot, relativePathToApplication),
@@ -337,101 +270,211 @@
       'FLUTTER_WEB': 'true',
     },
   );
+  print('Done.');
 }
 
-Future<void> _runAddToAppTests() async {
-  if (Platform.isMacOS) {
-    print('${green}Running add-to-app iOS integration tests$reset...');
-    final String addToAppDir = path.join(flutterRoot, 'dev', 'integration_tests', 'ios_add2app');
-    await runCommand('./build_and_test.sh',
-      <String>[],
-      workingDirectory: addToAppDir,
+Future<void> _flutterBuildAot(String relativePathToApplication) async {
+  print('Running AOT build tests...');
+  await runCommand(flutter,
+    <String>['build', 'aot', '-v'],
+    workingDirectory: path.join(flutterRoot, relativePathToApplication),
+    expectNonZeroExit: false,
+  );
+  print('Done.');
+}
+
+Future<void> _flutterBuildApk(String relativePathToApplication) async {
+  if (
+        (Platform.environment['ANDROID_HOME']?.isEmpty ?? true) &&
+        (Platform.environment['ANDROID_SDK_ROOT']?.isEmpty ?? true)) {
+    return;
+  }
+  print('Running APK build tests...');
+  await runCommand(flutter,
+    <String>['build', 'apk', '--debug', '-v'],
+    workingDirectory: path.join(flutterRoot, relativePathToApplication),
+    expectNonZeroExit: false,
+  );
+  print('Done.');
+}
+
+Future<void> _flutterBuildIpa(String relativePathToApplication) async {
+  if (!Platform.isMacOS) {
+    return;
+  }
+  print('Running IPA build tests...');
+  // Install Cocoapods.  We don't have these checked in for the examples,
+  // and build ios doesn't take care of it automatically.
+  final File podfile = File(path.join(flutterRoot, relativePathToApplication, 'ios', 'Podfile'));
+  if (podfile.existsSync()) {
+    await runCommand('pod',
+      <String>['install'],
+      workingDirectory: podfile.parent.path,
+      expectNonZeroExit: false,
     );
   }
+  await runCommand(flutter,
+    <String>['build', 'ios', '--no-codesign', '--debug', '-v'],
+    workingDirectory: path.join(flutterRoot, relativePathToApplication),
+    expectNonZeroExit: false,
+  );
+  print('Done.');
 }
 
-Future<void> _runFrameworkTests() async {
+Future<void> _runAdd2AppTest() async {
+  if (!Platform.isMacOS) {
+    return;
+  }
+  print('Running Add2App iOS integration tests...');
+  final String add2AppDir = path.join(flutterRoot, 'dev', 'integration_tests', 'ios_add2app');
+  await runCommand('./build_and_test.sh',
+    <String>[],
+    workingDirectory: add2AppDir,
+    expectNonZeroExit: false,
+  );
+  print('Done.');
+}
+
+Future<void> _runTests() async {
   final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
+  await _runSmokeTests();
+  final String subShard = Platform.environment['SUBSHARD'];
 
   Future<void> runWidgets() async {
-    print('${green}Running packages/flutter tests for$reset: ${cyan}test/widgets/$reset');
+    await _runFlutterTest(
+      path.join(flutterRoot, 'packages', 'flutter'),
+      tableData: bigqueryApi?.tabledata,
+      tests: <String>[
+        path.join('test', 'widgets') + path.separator,
+      ],
+    );
+    // Only packages/flutter/test/widgets/widget_inspector_test.dart really
+    // needs to be run with --track-widget-creation but it is nice to run
+    // all of the tests in package:flutter with the flag to ensure that
+    // the Dart kernel transformer triggered by the flag does not break anything.
     await _runFlutterTest(
       path.join(flutterRoot, 'packages', 'flutter'),
       options: <String>['--track-widget-creation'],
       tableData: bigqueryApi?.tabledata,
-      tests: <String>[ path.join('test', 'widgets') + path.separator ],
+      tests: <String>[
+        path.join('test', 'widgets') + path.separator,
+      ],
     );
-    await _runFlutterTest(
-      path.join(flutterRoot, 'packages', 'flutter'),
-      options: <String>['--no-track-widget-creation'],
-      tableData: bigqueryApi?.tabledata,
-      tests: <String>[ path.join('test', 'widgets') + path.separator ],
-    );
-    // Try compiling code outside of the packages/flutter directory with and without --track-widget-creation
-    await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), options: <String>['--track-widget-creation'], tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), options: <String>['--no-track-widget-creation'], tableData: bigqueryApi?.tabledata);
   }
 
-  Future<void> runLibraries() async {
+  Future<void> runFrameworkOthers() async {
     final List<String> tests = Directory(path.join(flutterRoot, 'packages', 'flutter', 'test'))
       .listSync(followLinks: false, recursive: false)
       .whereType<Directory>()
       .where((Directory dir) => dir.path.endsWith('widgets') == false)
-      .map<String>((Directory dir) => path.join('test', path.basename(dir.path)) + path.separator)
+      .map((Directory dir) => path.join('test', path.basename(dir.path)) + path.separator)
       .toList();
-    print('${green}Running packages/flutter tests$reset for: $cyan${tests.join(", ")}$reset');
+
+    print('Running tests for: ${tests.join(';')}');
+
+    await _runFlutterTest(
+      path.join(flutterRoot, 'packages', 'flutter'),
+      tableData: bigqueryApi?.tabledata,
+      tests: tests,
+    );
+    // Only packages/flutter/test/widgets/widget_inspector_test.dart really
+    // needs to be run with --track-widget-creation but it is nice to run
+    // all of the tests in package:flutter with the flag to ensure that
+    // the Dart kernel transformer triggered by the flag does not break anything.
     await _runFlutterTest(
       path.join(flutterRoot, 'packages', 'flutter'),
       options: <String>['--track-widget-creation'],
       tableData: bigqueryApi?.tabledata,
       tests: tests,
     );
-    await _runFlutterTest(
-      path.join(flutterRoot, 'packages', 'flutter'),
-      options: <String>['--no-track-widget-creation'],
-      tableData: bigqueryApi?.tabledata,
-      tests: tests,
-    );
   }
 
-  Future<void> runMisc() async {
-    print('${green}Running package tests$reset for directories other than packages/flutter');
+  Future<void> runExtras() async {
+    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
+    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata);
+    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata);
+    await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
     await _pubRunTest(path.join(flutterRoot, 'dev', 'bots'), tableData: bigqueryApi?.tabledata);
     await _pubRunTest(path.join(flutterRoot, 'dev', 'devicelab'), tableData: bigqueryApi?.tabledata);
     await _pubRunTest(path.join(flutterRoot, 'dev', 'snippets'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'android_semantics_testing'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'dev', 'manual_tests'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'vitool'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'examples', 'catalog'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), tableData: bigqueryApi?.tabledata);
     await _runFlutterTest(path.join(flutterRoot, 'examples', 'stocks'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
-    await _runFlutterTest(
-      path.join(flutterRoot, 'dev', 'integration_tests', 'codegen'),
-      tableData: bigqueryApi?.tabledata,
-      environment: <String, String>{
-        'FLUTTER_EXPERIMENTAL_BUILD': 'true',
-      },
-    );
+    await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), tableData: bigqueryApi?.tabledata);
+    // Regression test to ensure that code outside of package:flutter can run
+    // with --track-widget-creation.
+    await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), options: <String>['--track-widget-creation'], tableData: bigqueryApi?.tabledata);
+    await _runFlutterTest(path.join(flutterRoot, 'examples', 'catalog'), tableData: bigqueryApi?.tabledata);
+    // Smoke test for code generation.
+    await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'codegen'), tableData: bigqueryApi?.tabledata, environment: <String, String>{
+      'FLUTTER_EXPERIMENTAL_BUILD': 'true',
+    });
+  }
+  switch (subShard) {
+    case 'widgets':
+      await runWidgets();
+      break;
+    case 'framework_other':
+      await runFrameworkOthers();
+      break;
+    case 'extras':
+      runExtras();
+      break;
+    default:
+      print('Unknown sub-shard $subShard, running all tests!');
+      await runWidgets();
+      await runFrameworkOthers();
+      await runExtras();
+
   }
 
-  await selectSubshard(<String, ShardRunner>{
-    'widgets': runWidgets,
-    'libraries': runLibraries,
-    'misc': runMisc,
-  });
+  print('${bold}DONE: All tests successful.$reset');
 }
 
-Future<void> _runFrameworkCoverage() async {
+// TODO(yjbanov): we're getting rid of these blacklists as part of https://github.com/flutter/flutter/projects/60
+const List<String> kWebTestDirectoryBlacklist = <String>[
+  'test/cupertino',
+  'test/examples',
+  'test/material',
+];
+const List<String> kWebTestFileBlacklist = <String>[
+  'test/widgets/heroes_test.dart',
+  'test/widgets/text_test.dart',
+  'test/widgets/selectable_text_test.dart',
+  'test/widgets/color_filter_test.dart',
+  'test/widgets/editable_text_cursor_test.dart',
+  'test/widgets/shadow_test.dart',
+  'test/widgets/raw_keyboard_listener_test.dart',
+  'test/widgets/editable_text_test.dart',
+  'test/widgets/widget_inspector_test.dart',
+  'test/widgets/draggable_test.dart',
+  'test/widgets/shortcuts_test.dart',
+];
+
+Future<void> _runWebTests() async {
+  final Directory flutterPackageDir = Directory(path.join(flutterRoot, 'packages', 'flutter'));
+  final Directory testDir = Directory(path.join(flutterPackageDir.path, 'test'));
+
+  final List<String> directories = testDir
+    .listSync()
+    .whereType<Directory>()
+    .map<String>((Directory dir) => path.relative(dir.path, from: flutterPackageDir.path))
+    .where((String relativePath) => !kWebTestDirectoryBlacklist.contains(relativePath))
+    .toList();
+
+  await _runFlutterWebTest(flutterPackageDir.path, tests: directories);
+  await _runFlutterWebTest(path.join(flutterRoot, 'packages', 'flutter_web_plugins'), tests: <String>['test']);
+}
+
+Future<void> _runCoverage() async {
   final File coverageFile = File(path.join(flutterRoot, 'packages', 'flutter', 'coverage', 'lcov.info'));
   if (!coverageFile.existsSync()) {
     print('${red}Coverage file not found.$reset');
-    print('Expected to find: $cyan${coverageFile.absolute}$reset');
-    print('This file is normally obtained by running `${green}flutter update-packages$reset`.');
+    print('Expected to find: ${coverageFile.absolute}');
+    print('This file is normally obtained by running `flutter update-packages`.');
     exit(1);
   }
   coverageFile.deleteSync();
@@ -440,98 +483,11 @@
   );
   if (!coverageFile.existsSync()) {
     print('${red}Coverage file not found.$reset');
-    print('Expected to find: $cyan${coverageFile.absolute}$reset');
-    print('This file should have been generated by the `${green}flutter test --coverage$reset` script, but was not.');
+    print('Expected to find: ${coverageFile.absolute}');
+    print('This file should have been generated by the `flutter test --coverage` script, but was not.');
     exit(1);
   }
-}
-
-Future<void> _runWebTests() async {
-  final Map<String, ShardRunner> subshards = <String, ShardRunner>{};
-
-  final Directory flutterPackageDirectory = Directory(path.join(flutterRoot, 'packages', 'flutter'));
-  final Directory flutterPackageTestDirectory = Directory(path.join(flutterPackageDirectory.path, 'test'));
-
-  final List<String> allTests = flutterPackageTestDirectory
-    .listSync()
-    .whereType<Directory>()
-    .where((Directory directory) => !kWebTestDirectoryBlacklist.contains(path.basename(directory.path)))
-    .expand((Directory directory) => directory
-      .listSync(recursive: true)
-      .where((FileSystemEntity entity) => entity.path.endsWith('_test.dart'))
-    )
-    .whereType<File>()
-    .map<String>((File file) => path.relative(file.path, from: flutterPackageDirectory.path))
-    .where((String filePath) => !kWebTestFileBlacklist.contains(filePath))
-    .toList()
-    // Finally we shuffle the list because we want the average cost per file to be uniformly
-    // distributed. If the list is not sorted then different shards and batches may have
-    // very different characteristics.
-    // We use a constant seed for repeatability.
-    ..shuffle(math.Random(0));
-
-  assert(kWebShardCount >= 1);
-  final int testsPerShard = (allTests.length / kWebShardCount).ceil();
-  assert(testsPerShard * kWebShardCount >= allTests.length);
-
-  // This for loop computes all but the last shard.
-  for (int index = 0; index < kWebShardCount - 1; index += 1) {
-    subshards['$index'] = () => _runFlutterWebTest(
-      flutterPackageDirectory.path,
-      allTests.sublist(
-        index * testsPerShard,
-        (index + 1) * testsPerShard,
-      ),
-    );
-  }
-
-  // The last shard also runs the flutter_web_plugins tests.
-  //
-  // We make sure the last shard ends in _last so it's easier to catch mismatches
-  // between `.cirrus.yml` and `test.dart`.
-  subshards['${kWebShardCount - 1}_last'] = () async {
-    await _runFlutterWebTest(
-      flutterPackageDirectory.path,
-      allTests.sublist(
-        (kWebShardCount - 1) * testsPerShard,
-        allTests.length,
-      ),
-    );
-    await _runFlutterWebTest(
-      path.join(flutterRoot, 'packages', 'flutter_web_plugins'),
-      <String>['test'],
-    );
-  };
-
-  await selectSubshard(subshards);
-}
-
-Future<void> _runFlutterWebTest(String workingDirectory, List<String> tests) async {
-  final List<String> batch = <String>[];
-  for (int i = 0; i < tests.length; i += 1) {
-    final String testFilePath = tests[i];
-    batch.add(testFilePath);
-    if (batch.length == kWebBatchSize || i == tests.length - 1) {
-      await runCommand(
-        flutter,
-        <String>[
-          'test',
-          if (ciProvider == CiProviders.cirrus)
-            '--concurrency=1',  // do not parallelize on Cirrus, to reduce flakiness
-          '-v',
-          '--platform=chrome',
-          ...?flutterTestArgs,
-          ...batch,
-        ],
-        workingDirectory: workingDirectory,
-        environment: <String, String>{
-          'FLUTTER_WEB': 'true',
-          'FLUTTER_LOW_RESOURCE_MODE': 'true',
-        },
-      );
-      batch.clear();
-    }
-  }
+  print('${bold}DONE: Coverage collection successful.$reset');
 }
 
 Future<void> _pubRunTest(String workingDirectory, {
@@ -540,33 +496,14 @@
   bool useBuildRunner = false,
   bq.TabledataResourceApi tableData,
 }) async {
-  final List<String> args = <String>['run'];
+  final List<String> args = <String>['run', '--verbose'];
   if (useBuildRunner) {
-    final String posixTestPath = path.posix.joinAll(path.split(testPath));
-    args.addAll(<String>[
-      'build_runner',
-      'test',
-      '--build-filter=$posixTestPath/*.dill',
-      '--build-filter=$posixTestPath/**/*.dill',
-      '--',
-    ]);
+    args.addAll(<String>['build_runner', 'test', '--']);
   } else {
     args.add('test');
   }
   args.add(useFlutterTestFormatter ? '-rjson' : '-rcompact');
-  int cpus;
-  final String cpuVariable = Platform.environment['CPU']; // CPU is set in cirrus.yml
-  if (cpuVariable != null) {
-    cpus = int.tryParse(cpuVariable, radix: 10);
-    if (cpus == null) {
-      print('${red}The CPU environment variable, if set, must be set to the integer number of available cores.$reset');
-      print('Actual value: "$cpuVariable"');
-      exit(1);
-    }
-  } else {
-    cpus = 2; // Don't default to 1, otherwise we won't catch race conditions.
-  }
-  args.add('-j$cpus');
+  args.add('-j1'); // TODO(ianh): Scale based on CPUs.
   if (!hasColor)
     args.add('--no-color');
   if (testPath != null)
@@ -610,6 +547,238 @@
   }
 }
 
+void deleteFile(String path) {
+  // There's a race condition here but in theory we're not racing anyone
+  // while this script runs, so should be ok.
+  final File file = File(path);
+  if (file.existsSync())
+    file.deleteSync();
+}
+
+enum CiProviders {
+  cirrus,
+  luci,
+}
+
+CiProviders _getCiProvider() {
+  if (Platform.environment['CIRRUS_CI'] == 'true') {
+    return CiProviders.cirrus;
+  }
+  if (Platform.environment['LUCI_CONTEXT'] != null) {
+    return CiProviders.luci;
+  }
+  return null;
+}
+
+String _getCiProviderName() {
+  switch(_getCiProvider()) {
+    case CiProviders.cirrus:
+      return 'cirrusci';
+    case CiProviders.luci:
+      return 'luci';
+  }
+  return 'unknown';
+}
+
+int _getPrNumber() {
+  switch(_getCiProvider()) {
+    case CiProviders.cirrus:
+      return Platform.environment['CIRRUS_PR'] == null
+          ? -1
+          : int.tryParse(Platform.environment['CIRRUS_PR']);
+    case CiProviders.luci:
+      return -1; // LUCI doesn't know about this.
+  }
+  return -1;
+}
+
+Future<String> _getAuthors() async {
+  final String exe = Platform.isWindows ? '.exe' : '';
+  final String author = await runAndGetStdout(
+    'git$exe', <String>['-c', 'log.showSignature=false', 'log', _getGitHash(), '--pretty="%an <%ae>"'],
+    workingDirectory: flutterRoot,
+  ).first;
+  return author;
+}
+
+String _getCiUrl() {
+  switch(_getCiProvider()) {
+    case CiProviders.cirrus:
+      return 'https://cirrus-ci.com/task/${Platform.environment['CIRRUS_TASK_ID']}';
+    case CiProviders.luci:
+      return 'https://ci.chromium.org/p/flutter/g/framework/console'; // TODO(dnfield): can we get a direct link to the actual build?
+  }
+  return '';
+}
+
+String _getGitHash() {
+  switch(_getCiProvider()) {
+    case CiProviders.cirrus:
+      return Platform.environment['CIRRUS_CHANGE_IN_REPO'];
+    case CiProviders.luci:
+      return 'HEAD'; // TODO(dnfield): Set this in the env for LUCI.
+  }
+  return '';
+}
+
+Future<void> _processTestOutput(
+  FlutterCompactFormatter formatter,
+  Stream<String> testOutput,
+  bq.TabledataResourceApi tableData,
+) async {
+  final Timer heartbeat = Timer.periodic(const Duration(seconds: 30), (Timer timer) {
+    print('Processing...');
+  });
+
+  await testOutput.forEach(formatter.processRawOutput);
+  heartbeat.cancel();
+  formatter.finish();
+  if (tableData == null || formatter.tests.isEmpty) {
+    return;
+  }
+  final bq.TableDataInsertAllRequest request = bq.TableDataInsertAllRequest();
+  final String authors = await _getAuthors();
+  request.rows = List<bq.TableDataInsertAllRequestRows>.from(
+    formatter.tests.map<bq.TableDataInsertAllRequestRows>((TestResult result) =>
+      bq.TableDataInsertAllRequestRows.fromJson(<String, dynamic> {
+        'json': <String, dynamic>{
+          'source': <String, dynamic>{
+            'provider': _getCiProviderName(),
+            'url': _getCiUrl(),
+            'platform': <String, dynamic>{
+              'os': Platform.operatingSystem,
+              'version': Platform.operatingSystemVersion,
+            },
+          },
+          'test': <String, dynamic>{
+            'name': result.name,
+            'result': result.status.toString(),
+            'file': result.path,
+            'line': result.line,
+            'column': result.column,
+            'time': result.totalTime,
+          },
+          'git': <String, dynamic>{
+            'author': authors,
+            'pull_request': _getPrNumber(),
+            'commit': _getGitHash(),
+            'organization': 'flutter',
+            'repository': 'flutter',
+          },
+          'error': result.status != TestStatus.failed ? null : <String, dynamic>{
+            'message': result.errorMessage,
+            'stack_trace': result.stackTrace,
+          },
+          'information': result.messages,
+        },
+      }),
+    ),
+    growable: false,
+  );
+  final bq.TableDataInsertAllResponse response = await tableData.insertAll(request, 'flutter-infra', 'tests', 'ci');
+  if (response.insertErrors != null && response.insertErrors.isNotEmpty) {
+    print('${red}BigQuery insert errors:');
+    print(response.toJson());
+    print(reset);
+  }
+}
+
+class EvalResult {
+  EvalResult({
+    this.stdout,
+    this.stderr,
+    this.exitCode = 0,
+  });
+
+  final String stdout;
+  final String stderr;
+  final int exitCode;
+}
+
+/// The number of Cirrus jobs that run web tests in parallel.
+///
+/// WARNING: if you change this number, also change .cirrus.yml
+/// and make sure it runs _all_ shards.
+const int _kWebShardCount = 6;
+
+Future<void> _runFlutterWebTest(String workingDirectory, {
+  List<String> tests,
+}) async {
+  List<String> allTests = <String>[];
+  for (String testDirPath in tests) {
+    final Directory testDir = Directory(path.join(workingDirectory, testDirPath));
+    allTests.addAll(
+      testDir.listSync(recursive: true)
+        .whereType<File>()
+        .where((File file) => file.path.endsWith('_test.dart'))
+        .map<String>((File file) => path.relative(file.path, from: workingDirectory))
+        .where((String filePath) => !kWebTestFileBlacklist.contains(filePath)),
+    );
+  }
+
+  // If a shard is specified only run tests in that shard.
+  final int webShard = int.tryParse(Platform.environment['WEB_SHARD'] ?? 'n/a');
+  if (webShard != null) {
+    if (webShard >= _kWebShardCount) {
+      throw 'WEB_SHARD must be <= _kWebShardCount, but was $webShard';
+    }
+    final List<String> shard = <String>[];
+    for (int i = webShard; i < allTests.length; i += _kWebShardCount) {
+      shard.add(allTests[i]);
+    }
+    allTests = shard;
+  }
+
+  print(allTests.join('\n'));
+  print('${allTests.length} tests total');
+
+  // Maximum number of tests to run in a single `flutter test`. We found that
+  // large batches can get flaky, possibly because we reuse a single instance
+  // of the browser, and after many tests the browser's state gets corrupted.
+  const int kBatchSize = 20;
+  List<String> batch = <String>[];
+  for (int i = 0; i < allTests.length; i += 1) {
+    final String testFilePath = allTests[i];
+    batch.add(testFilePath);
+    if (batch.length == kBatchSize || i == allTests.length - 1) {
+      await _runFlutterWebTestBatch(workingDirectory, batch: batch);
+      batch = <String>[];
+    }
+  }
+}
+
+Future<void> _runFlutterWebTestBatch(String workingDirectory, {
+  List<String> batch,
+}) async {
+  final List<String> args = <String>[
+    'test',
+    if (_getCiProvider() == CiProviders.cirrus)
+      '--concurrency=1',  // do not parallelize on Cirrus to reduce flakiness
+    '-v',
+    '--platform=chrome',
+    ...?flutterTestArgs,
+    ...batch,
+  ];
+
+  // TODO(jonahwilliams): fix relative path issues to make this unecessary.
+  final Directory oldCurrent = Directory.current;
+  Directory.current = Directory(path.join(flutterRoot, 'packages', 'flutter'));
+  try {
+    await runCommand(
+      flutter,
+      args,
+      workingDirectory: workingDirectory,
+      expectFlaky: false,
+      environment: <String, String>{
+        'FLUTTER_WEB': 'true',
+        'FLUTTER_LOW_RESOURCE_MODE': 'true',
+      },
+    );
+  } finally {
+    Directory.current = oldCurrent;
+  }
+}
+
 Future<void> _runFlutterTest(String workingDirectory, {
   String script,
   bool expectFailure = false,
@@ -621,7 +790,8 @@
   Map<String, String> environment,
   List<String> tests = const <String>[],
 }) async {
-  assert(!printOutput || outputChecker == null, 'Output either can be printed or checked but not both');
+  assert(!printOutput || outputChecker == null,
+      'Output either can be printed or checked but not both');
 
   final List<String> args = <String>[
     'test',
@@ -630,15 +800,16 @@
   ];
 
   final bool shouldProcessOutput = useFlutterTestFormatter && !expectFailure && !options.contains('--coverage');
-  if (shouldProcessOutput)
+  if (shouldProcessOutput) {
     args.add('--machine');
+  }
 
   if (script != null) {
     final String fullScriptPath = path.join(workingDirectory, script);
     if (!FileSystemEntity.isFileSync(fullScriptPath)) {
-      print('${red}Could not find test$reset: $green$fullScriptPath$reset');
-      print('Working directory: $cyan$workingDirectory$reset');
-      print('Script: $green$script$reset');
+      print('Could not find test: $fullScriptPath');
+      print('Working directory: $workingDirectory');
+      print('Script: $script');
       if (!printOutput)
         print('This is one of the tests that does not normally print output.');
       if (skip)
@@ -705,290 +876,110 @@
   }
 }
 
-Map<String, String> _initGradleEnvironment() {
-  final String androidSdkRoot = (Platform.environment['ANDROID_HOME']?.isEmpty ?? true)
-      ? Platform.environment['ANDROID_SDK_ROOT']
-      : Platform.environment['ANDROID_HOME'];
-  if (androidSdkRoot == null || androidSdkRoot.isEmpty) {
-    print('${red}Could not find Android SDK; set ANDROID_SDK_ROOT (or ANDROID_HOME).$reset');
-    exit(1);
+// the optional `file` argument is an override for testing
+@visibleForTesting
+Future<bool> verifyVersion(String filename, [File file]) async {
+  final RegExp pattern = RegExp(r'^\d+\.\d+\.\d+(\+hotfix\.\d+)?(-pre\.\d+)?$');
+  file ??= File(filename);
+  final String version = await file.readAsString();
+  if (!file.existsSync()) {
+    print('$redLine');
+    print('The version logic failed to create the Flutter version file.');
+    print('$redLine');
+    return false;
   }
-  return <String, String>{
-    'ANDROID_HOME': androidSdkRoot,
-    'ANDROID_SDK_ROOT': androidSdkRoot,
-  };
+  if (version == '0.0.0-unknown') {
+    print('$redLine');
+    print('The version logic failed to determine the Flutter version.');
+    print('$redLine');
+    return false;
+  }
+  if (!version.contains(pattern)) {
+    print('$redLine');
+    print('The version logic generated an invalid version string: "$version".');
+    print('$redLine');
+    return false;
+  }
+  return true;
 }
 
-final Map<String, String> gradleEnvironment = _initGradleEnvironment();
+Future<void> _runIntegrationTests() async {
+  final String subShard = Platform.environment['SUBSHARD'];
 
-Future<void> _runHostOnlyDeviceLabTests() async {
-  if (Platform.isWindows) {
-    // TODO(ianh): remove when https://github.com/flutter/flutter/issues/36311 fixed by https://github.com/flutter/flutter/pull/42709
-    return;
+  switch (subShard) {
+    case 'gradle1':
+    case 'gradle2':
+      // This runs some gradle integration tests if the subshard is Android.
+      await _androidGradleTests(subShard);
+      break;
+    default:
+      await _runDevicelabTest('dartdocs');
+
+      if (Platform.isLinux) {
+        await _runDevicelabTest('flutter_create_offline_test_linux');
+      } else if (Platform.isWindows) {
+        await _runDevicelabTest('flutter_create_offline_test_windows');
+      } else if (Platform.isMacOS) {
+        await _runDevicelabTest('flutter_create_offline_test_mac');
+        await _runDevicelabTest('plugin_lint_mac');
+// TODO(jmagman): Re-enable once flakiness is resolved.
+//        await _runDevicelabTest('module_test_ios');
+      }
   }
-
-  // Please don't add more tests here. We should not be using the devicelab
-  // logic to run tests outside devicelab, that's just confusing.
-  // Instead, create tests that are not devicelab tests, and run those.
-
-  // TODO(ianh): Move the tests that are not running on devicelab any more out
-  // of the device lab directory.
-
-  // List the tests to run.
-  // We split these into subshards. The tests are randomly distributed into
-  // those subshards so as to get a uniform distribution of costs, but the
-  // seed is fixed so that issues are reproducible.
-  final List<ShardRunner> tests = <ShardRunner>[
-    // Keep this in alphabetical order.
-    () => _runDevicelabTest('build_aar_module_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('build_aar_module_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    if (Platform.isMacOS) () => _runDevicelabTest('flutter_create_offline_test_mac'),
-    if (Platform.isLinux) () => _runDevicelabTest('flutter_create_offline_test_linux'),
-    if (Platform.isWindows) () => _runDevicelabTest('flutter_create_offline_test_windows'),
-    // TODO(ianh): Fails on macOS looking for "dexdump", https://github.com/flutter/flutter/issues/42494
-    if (!Platform.isMacOS) () => _runDevicelabTest('gradle_jetifier_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    if (!Platform.isMacOS) () => _runDevicelabTest('gradle_jetifier_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('gradle_non_android_plugin_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('gradle_non_android_plugin_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('gradle_plugin_bundle_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('gradle_plugin_bundle_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('gradle_plugin_fat_apk_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('gradle_plugin_fat_apk_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('gradle_plugin_light_apk_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('gradle_plugin_light_apk_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('gradle_r8_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('gradle_r8_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('module_host_with_custom_build_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('module_host_with_custom_build_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    () => _runDevicelabTest('module_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('module_test', environment: gradleEnvironment, testEmbeddingV2: true),
-    // TODO(jmagman): Re-enable once flakiness is resolved, https://github.com/flutter/flutter/issues/37525
-    // if (Platform.isMacOS) () => _runDevicelabTest('module_test_ios'),
-    if (Platform.isMacOS) () => _runDevicelabTest('plugin_lint_mac'),
-    () => _runDevicelabTest('plugin_test', environment: gradleEnvironment, testEmbeddingV2: false),
-    () => _runDevicelabTest('plugin_test', environment: gradleEnvironment, testEmbeddingV2: true),
-  ]..shuffle(math.Random(0));
-
-  final int testsPerShard = tests.length ~/ kDeviceLabShardCount;
-  final Map<String, ShardRunner> subshards = <String, ShardRunner>{};
-
-  for (int subshard = 0; subshard < kDeviceLabShardCount; subshard += 1) {
-    String last = '';
-    List<ShardRunner> sublist;
-    if (subshard < kDeviceLabShardCount - 1) {
-      sublist = tests.sublist(subshard * testsPerShard, (subshard + 1) * testsPerShard);
-    } else {
-      sublist = tests.sublist(subshard * testsPerShard, tests.length);
-      // We make sure the last shard ends in _last so it's easier to catch mismatches
-      // between `.cirrus.yml` and `test.dart`.
-      last = '_last';
-    }
-    subshards['$subshard$last'] = () async {
-      for (ShardRunner test in sublist)
-        await test();
-    };
-  }
-
-  await selectSubshard(subshards);
 }
 
-Future<void> _runDevicelabTest(String testName, {
-  Map<String, String> environment,
-  bool testEmbeddingV2 = false,
-}) async {
+Future<void> _runDevicelabTest(String testName, {Map<String, String> env}) async {
   await runCommand(
     dart,
     <String>['bin/run.dart', '-t', testName],
     workingDirectory: path.join(flutterRoot, 'dev', 'devicelab'),
-    environment: <String, String>{
-      ...?environment,
-      if (testEmbeddingV2)
-        'ENABLE_ANDROID_EMBEDDING_V2': 'true',
-    },
+    environment: env,
   );
 }
 
-void deleteFile(String path) {
-  // This is technically a race condition but nobody else should be running
-  // while this script runs, so we should be ok. (Sadly recursive:true does not
-  // obviate the need for existsSync, at least on Windows.)
-  final File file = File(path);
-  if (file.existsSync())
-    file.deleteSync();
+String get androidSdkRoot {
+  final String androidSdkRoot = (Platform.environment['ANDROID_HOME']?.isEmpty ?? true)
+      ? Platform.environment['ANDROID_SDK_ROOT']
+      : Platform.environment['ANDROID_HOME'];
+  if (androidSdkRoot == null || androidSdkRoot.isEmpty) {
+    return null;
+  }
+  return androidSdkRoot;
 }
 
-enum CiProviders {
-  cirrus,
-  luci,
-}
-
-Future<void> _processTestOutput(
-  FlutterCompactFormatter formatter,
-  Stream<String> testOutput,
-  bq.TabledataResourceApi tableData,
-) async {
-  final Timer heartbeat = Timer.periodic(const Duration(seconds: 30), (Timer timer) {
-    print('Processing...');
-  });
-
-  await testOutput.forEach(formatter.processRawOutput);
-  heartbeat.cancel();
-  formatter.finish();
-  if (tableData == null || formatter.tests.isEmpty) {
+Future<void> _androidGradleTests(String subShard) async {
+  // TODO(dnfield): gradlew is crashing on the cirrus image and it's not clear why.
+  if (androidSdkRoot == null || Platform.isWindows) {
+    print('No Android SDK detected or on Windows, skipping Android gradle test.');
     return;
   }
-  final bq.TableDataInsertAllRequest request = bq.TableDataInsertAllRequest();
-  final String authors = await _getAuthors();
-  request.rows = List<bq.TableDataInsertAllRequestRows>.from(
-    formatter.tests.map<bq.TableDataInsertAllRequestRows>((TestResult result) =>
-      bq.TableDataInsertAllRequestRows.fromJson(<String, dynamic> {
-        'json': <String, dynamic>{
-          'source': <String, dynamic>{
-            'provider': ciProviderName,
-            'url': ciUrl,
-            'platform': <String, dynamic>{
-              'os': Platform.operatingSystem,
-              'version': Platform.operatingSystemVersion,
-            },
-          },
-          'test': <String, dynamic>{
-            'name': result.name,
-            'result': result.status.toString(),
-            'file': result.path,
-            'line': result.line,
-            'column': result.column,
-            'time': result.totalTime,
-          },
-          'git': <String, dynamic>{
-            'author': authors,
-            'pull_request': prNumber,
-            'commit': gitHash,
-            'organization': 'flutter',
-            'repository': 'flutter',
-          },
-          'error': result.status != TestStatus.failed ? null : <String, dynamic>{
-            'message': result.errorMessage,
-            'stack_trace': result.stackTrace,
-          },
-          'information': result.messages,
-        },
-      }),
-    ),
-    growable: false,
-  );
-  final bq.TableDataInsertAllResponse response = await tableData.insertAll(request, 'flutter-infra', 'tests', 'ci');
-  if (response.insertErrors != null && response.insertErrors.isNotEmpty) {
-    print('${red}BigQuery insert errors:');
-    print(response.toJson());
-    print(reset);
+  final Map<String, String> defaultEnv = <String, String>{
+    'ANDROID_HOME': androidSdkRoot,
+    'ANDROID_SDK_ROOT': androidSdkRoot,
+    'ENABLE_ANDROID_EMBEDDING_V2': Platform.environment['ENABLE_ANDROID_EMBEDDING_V2'] ?? '',
+  };
+  if (subShard == 'gradle1') {
+    await _runDevicelabTest('gradle_plugin_light_apk_test', env: defaultEnv);
+    await _runDevicelabTest('gradle_plugin_fat_apk_test', env: defaultEnv);
+    await _runDevicelabTest('gradle_r8_test', env: defaultEnv);
+    await _runDevicelabTest('gradle_non_android_plugin_test', env: defaultEnv);
+    await _runDevicelabTest('gradle_jetifier_test', env: defaultEnv);
+  }
+  if (subShard == 'gradle2') {
+    await _runDevicelabTest('gradle_plugin_bundle_test', env: defaultEnv);
+    await _runDevicelabTest('module_test', env: defaultEnv);
+    await _runDevicelabTest('module_host_with_custom_build_test', env: defaultEnv);
+    await _runDevicelabTest('build_aar_module_test', env: defaultEnv);
+    await _runDevicelabTest('plugin_test', env: defaultEnv);
   }
 }
 
-CiProviders get ciProvider {
-  if (Platform.environment['CIRRUS_CI'] == 'true') {
-    return CiProviders.cirrus;
-  }
-  if (Platform.environment['LUCI_CONTEXT'] != null) {
-    return CiProviders.luci;
-  }
-  return null;
-}
+Future<void> selectShard(Map<String, ShardRunner> shards) => _runFromList(shards, 'SHARD', 'shard');
+Future<void> selectSubshard(Map<String, ShardRunner> subshards) => _runFromList(subshards, 'SUBSHARD', 'subshard');
 
-String get ciProviderName {
-  switch (ciProvider) {
-    case CiProviders.cirrus:
-      return 'cirrusci';
-    case CiProviders.luci:
-      return 'luci';
-  }
-  return 'unknown';
-}
-
-int get prNumber {
-  switch (ciProvider) {
-    case CiProviders.cirrus:
-      return Platform.environment['CIRRUS_PR'] == null
-          ? -1
-          : int.tryParse(Platform.environment['CIRRUS_PR']);
-    case CiProviders.luci:
-      return -1; // LUCI doesn't know about this.
-  }
-  return -1;
-}
-
-Future<String> _getAuthors() async {
-  final String exe = Platform.isWindows ? '.exe' : '';
-  final String author = await runAndGetStdout(
-    'git$exe', <String>['-c', 'log.showSignature=false', 'log', gitHash, '--pretty="%an <%ae>"'],
-    workingDirectory: flutterRoot,
-  ).first;
-  return author;
-}
-
-String get ciUrl {
-  switch (ciProvider) {
-    case CiProviders.cirrus:
-      return 'https://cirrus-ci.com/task/${Platform.environment['CIRRUS_TASK_ID']}';
-    case CiProviders.luci:
-      return 'https://ci.chromium.org/p/flutter/g/framework/console'; // TODO(dnfield): can we get a direct link to the actual build?
-  }
-  return '';
-}
-
-String get gitHash {
-  switch(ciProvider) {
-    case CiProviders.cirrus:
-      return Platform.environment['CIRRUS_CHANGE_IN_REPO'];
-    case CiProviders.luci:
-      return 'HEAD'; // TODO(dnfield): Set this in the env for LUCI.
-  }
-  return '';
-}
-
-/// Checks the given file's contents to determine if they match the allowed
-/// pattern for version strings.
-///
-/// Returns null if the contents are good. Returns a string if they are bad.
-/// The string is an error message.
-Future<String> verifyVersion(File file) async {
-  final RegExp pattern = RegExp(r'^\d+\.\d+\.\d+(\+hotfix\.\d+)?(-pre\.\d+)?$');
-  final String version = await file.readAsString();
-  if (!file.existsSync())
-    return 'The version logic failed to create the Flutter version file.';
-  if (version == '0.0.0-unknown')
-    return 'The version logic failed to determine the Flutter version.';
-  if (!version.contains(pattern))
-    return 'The version logic generated an invalid version string: "$version".';
-  return null;
-}
-
-/// If the CIRRUS_TASK_NAME environment variable exists, we use that to determine
-/// the shard and subshard (parsing it in the form shard-subshard-platform, ignoring
-/// the platform).
-///
-/// However, for local testing you can just set the SHARD and SUBSHARD
-/// environment variables. For example, to run all the framework tests you can
-/// just set SHARD=framework_tests. To run specifically the third subshard of
-/// the Web tests you can set SHARD=web_tests SUBSHARD=2 (it's zero-based).
-Future<void> selectShard(Map<String, ShardRunner> shards) => _runFromList(shards, 'SHARD', 'shard', 0);
-Future<void> selectSubshard(Map<String, ShardRunner> subshards) => _runFromList(subshards, 'SUBSHARD', 'subshard', 1);
-
-const String CIRRUS_TASK_NAME = 'CIRRUS_TASK_NAME';
-
-Future<void> _runFromList(Map<String, ShardRunner> items, String key, String name, int positionInTaskName) async {
-  String item = Platform.environment[key];
-  if (item == null && Platform.environment.containsKey(CIRRUS_TASK_NAME)) {
-    final List<String> parts = Platform.environment[CIRRUS_TASK_NAME].split('-');
-    assert(positionInTaskName < parts.length);
-    item = parts[positionInTaskName];
-  }
-  if (item == null) {
-    for (String currentItem in items.keys) {
-      print('$bold$key=$currentItem$reset');
-      await items[currentItem]();
-      print('');
-    }
-  } else {
+Future<void> _runFromList(Map<String, ShardRunner> items, String key, String name) async {
+  final String item = Platform.environment[key];
+  if (item != null) {
     if (!items.containsKey(item)) {
       print('${red}Invalid $name: $item$reset');
       print('The available ${name}s are: ${items.keys.join(", ")}');
@@ -996,5 +987,11 @@
     }
     print('$bold$key=$item$reset');
     await items[item]();
+  } else {
+    for (String currentItem in items.keys) {
+      print('$bold$key=$currentItem$reset');
+      await items[currentItem]();
+      print('');
+    }
   }
 }
