Some test cleanup for flutter_tools. (#90227)

diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index dc7e475..3973376 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -278,6 +278,8 @@
     testPaths: <String>[path.join('test', 'general.shard')],
     enableFlutterToolAsserts: false,
     // Detect unit test time regressions (poor time delay handling, etc).
+    // This overrides the 15 minute default for tools tests.
+    // See the README.md and dart_test.yaml files in the flutter_tools package.
     perTestTimeout: const Duration(seconds: 2),
   );
 }
@@ -295,8 +297,6 @@
     path.join(flutterRoot, 'packages', 'flutter_tools'),
     forceSingleCore: true,
     testPaths: <String>[path.join('test', 'web.shard')],
-    enableFlutterToolAsserts: true,
-    perTestTimeout: const Duration(minutes: 3),
     includeLocalEngineEnv: true,
   );
 }
diff --git a/packages/flutter_tools/README.md b/packages/flutter_tools/README.md
index 156cfa4..e46de50 100644
--- a/packages/flutter_tools/README.md
+++ b/packages/flutter_tools/README.md
@@ -39,17 +39,30 @@
 As with other parts of the Flutter repository, all changes in behavior [must be
 tested](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#write-test-find-bug).
 Tests live under the `test/` subdirectory.
-- Hermetic unit tests of tool internals go under `test/general.shard`.
-- Tests of tool commands go under `test/commands.shard`. Hermetic tests go under
-  its `hermetic/` subdirectory. Non-hermetic tests go under its `permeable`
-  sub-directory. Avoid adding tests here and prefer writing either a unit test or a full
-  integration test.
-- Integration tests (e.g. tests that run the tool in a subprocess) go under
-  `test/integration.shard`.
 
-In general, the tests for the code in a file called `file.dart` should go in a
-file called `file_test.dart` in the subdirectory that matches the behavior of
-the test.
+- Hermetic unit tests of tool internals go under `test/general.shard`
+  and must run in significantly less than two seconds.
+
+- Tests of tool commands go under `test/commands.shard`. Hermetic
+  tests go under its `hermetic/` subdirectory. Non-hermetic tests go
+  under its `permeable` sub-directory. Avoid adding tests here and
+  prefer writing either a unit test or a full integration test.
+
+- Integration tests (e.g. tests that run the tool in a subprocess) go
+  under `test/integration.shard`.
+
+- Slow web-related tests go in the `test/web.shard` directory.
+
+In general, the tests for the code in a file called `file.dart` should
+go in a file called `file_test.dart` in the subdirectory that matches
+the behavior of the test.
+
+The `dart_test.yaml` file configures the timeout for these tests to be
+15 minutes. The `test.dart` script that is used in CI overrides this
+to two seconds for the `test/general.shard` directory, to catch
+behaviour that is unexpectedly slow.
+
+Please avoid setting any other timeouts.
 
 #### Using local engine builds in integration tests
 
@@ -73,29 +86,26 @@
 $ flutter test test/general.shard
 ```
 
-The tests in `test/integration.shard` are slower to run than the tests in
-`test/general.shard`. Depending on your development computer, you might
-want to increase timeouts and limit concurrency. Generally it is easier to run
-these on CI, or to manually verify the behavior you are changing instead of running
-the test.
+The tests in `test/integration.shard` are slower to run than the tests
+in `test/general.shard`. Depending on your development computer, you
+might want to limit concurrency. Generally it is easier to run these
+on CI, or to manually verify the behavior you are changing instead of
+running the test.
 
-The integration tests also require the `FLUTTER_ROOT` environment variable
-to be set. The full invocation to run everything might therefore look something like:
+The integration tests also require the `FLUTTER_ROOT` environment
+variable to be set. The full invocation to run everything might
+therefore look something like:
 
 ```shell
 $ FLUTTER_ROOT=~/path/to/flutter-sdk
-$ flutter test --timeout 2x --concurrency 1
+$ flutter test --concurrency 1
 ```
 
-This will take about an hour to complete.
+This may take some time (on the order of an hour). The unit tests
+alone take much less time (on the order of a minute).
 
-To run only the tests in `test/general.shard` (which takes about a minute),
-in this directory run:
-```shell
-$ flutter test test/general.shard
-```
+You can run the tests in a specific file, e.g.:
 
-To run the tests in a specific file, run:
 ```shell
 $ flutter test test/general.shard/utils_test.dart
 ```
diff --git a/packages/flutter_tools/dart_test.yaml b/packages/flutter_tools/dart_test.yaml
index 807c298..f437c0f 100644
--- a/packages/flutter_tools/dart_test.yaml
+++ b/packages/flutter_tools/dart_test.yaml
@@ -6,6 +6,9 @@
 # overloaded. For this reason, we set the test timeout to
 # significantly more than it would be by default, and we never set the
 # timeouts in the tests themselves.
+#
+# For the `test/general.shard` specifically, the `dev/bots/test.dart` script
+# overrides this, reducing it to only 2000ms. Unit tests must run fast!
 timeout: 15m
 
 tags:
diff --git a/packages/flutter_tools/test/integration.shard/deferred_components_test.dart b/packages/flutter_tools/test/integration.shard/deferred_components_test.dart
index 3ea5c84..08359d9 100644
--- a/packages/flutter_tools/test/integration.shard/deferred_components_test.dart
+++ b/packages/flutter_tools/test/integration.shard/deferred_components_test.dart
@@ -62,7 +62,7 @@
     expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
 
     expect(result.exitCode, 0);
-  }, timeout: const Timeout(Duration(minutes: 5)));
+  });
 
   testWithoutContext('simple build appbundle all targets succeeds', () async {
     final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
@@ -105,7 +105,7 @@
     expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
 
     expect(result.exitCode, 0);
-  }, timeout: const Timeout(Duration(minutes: 5)));
+  });
 
   testWithoutContext('simple build appbundle no-deferred-components succeeds', () async {
     final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
@@ -151,7 +151,7 @@
     expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
 
     expect(result.exitCode, 0);
-  }, timeout: const Timeout(Duration(minutes: 5)));
+  });
 
   testWithoutContext('simple build appbundle mismatched golden no-validate-deferred-components succeeds', () async {
     final DeferredComponentsProject project = DeferredComponentsProject(MismatchedGoldenDeferredComponentsConfig());
@@ -198,7 +198,7 @@
     expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
 
     expect(result.exitCode, 0);
-  }, timeout: const Timeout(Duration(minutes: 5)));
+  });
 
   testWithoutContext('simple build appbundle missing android dynamic feature module fails', () async {
     final DeferredComponentsProject project = DeferredComponentsProject(NoAndroidDynamicFeatureModuleDeferredComponentsConfig());
diff --git a/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart b/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart
index 8d191c3..af48dc7 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart
@@ -104,5 +104,5 @@
       continuePollingValue: '',
       matches: equals(vmServiceUri),
     );
-  }, timeout: const Timeout.factor(4));
+  });
 }
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_null_unsafe_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_null_unsafe_test.dart
index 3fe0f7a..483d8eb 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_null_unsafe_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_null_unsafe_test.dart
@@ -78,6 +78,6 @@
         if (targetPlatform == 'ios') '--no-codesign',
       ], workingDirectory: projectRoot.path);
       expect(result.exitCode, 0);
-    }, timeout: const Timeout(Duration(minutes: 3)));
+    });
   }
 }
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
index b75a00e..2dbb1b3 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
@@ -71,6 +71,6 @@
         contains("A value of type 'String' can't be assigned to a variable of type 'int'."),
       );
       expect(result.exitCode, 1);
-    }, timeout: const Timeout(Duration(minutes: 3)));
+    });
   }
 }
diff --git a/packages/flutter_tools/test/integration.shard/flutter_run_test.dart b/packages/flutter_tools/test/integration.shard/flutter_run_test.dart
index 0ad60ee..0b3c65a 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_run_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_run_test.dart
@@ -69,5 +69,5 @@
       continuePollingValue: '',
       matches: isNotEmpty,
     );
-  }, timeout: const Timeout.factor(4));
+  });
 }
diff --git a/packages/flutter_tools/test/integration.shard/gradle_non_android_plugin_test.dart b/packages/flutter_tools/test/integration.shard/gradle_non_android_plugin_test.dart
index 52fd6ee..a992223 100644
--- a/packages/flutter_tools/test/integration.shard/gradle_non_android_plugin_test.dart
+++ b/packages/flutter_tools/test/integration.shard/gradle_non_android_plugin_test.dart
@@ -90,5 +90,5 @@
       'app-release.apk',
     );
     expect(fileSystem.file(exampleAppApk), exists);
-  }, timeout: const Timeout(Duration(minutes: 5)));
+  });
 }
diff --git a/packages/flutter_tools/test/integration.shard/macos_content_validation_test.dart b/packages/flutter_tools/test/integration.shard/macos_content_validation_test.dart
index 9e1ed8c..f047814 100644
--- a/packages/flutter_tools/test/integration.shard/macos_content_validation_test.dart
+++ b/packages/flutter_tools/test/integration.shard/macos_content_validation_test.dart
@@ -145,8 +145,6 @@
         ...getLocalEngineArguments(),
         'clean',
       ], workingDirectory: workingDirectory);
-    }, skip: !platform.isMacOS, // [intended] only makes sense for macos platform.
-       timeout: const Timeout(Duration(minutes: 5)),
-    );
+    }, skip: !platform.isMacOS); // [intended] only makes sense for macos platform.
   }
 }
diff --git a/packages/flutter_tools/test/integration.shard/overall_experience_test.dart b/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
index 36dc030..c2c0154 100644
--- a/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
+++ b/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
@@ -25,10 +25,7 @@
 // @dart = 2.8
 // This file is ready to transition, just uncomment /*?*/, /*!*/, and /*late*/.
 
-// TODO(gspencergoog): Remove this tag once this test's state leaks/test
-// dependencies have been fixed.
-// https://github.com/flutter/flutter/issues/85160
-// Fails with "flutter test --test-randomize-ordering-seed=1000"
+// This file intentionally assumes the tests run in order.
 @Tags(<String>['no-shuffle'])
 
 import 'dart:async';
@@ -40,7 +37,7 @@
 import 'package:process/process.dart';
 
 import '../src/common.dart';
-import 'test_utils.dart' show fileSystem, platform;
+import 'test_utils.dart' show fileSystem;
 
 const ProcessManager processManager = LocalProcessManager();
 final String flutterRoot = getFlutterRoot();
@@ -189,7 +186,7 @@
   List<Transition> transitions, {
   bool debug = false,
   bool logging = true,
-  Duration expectedMaxDuration = const Duration(minutes: 10), // must be less than test timeout of 15 minutes!
+  Duration expectedMaxDuration = const Duration(minutes: 10), // must be less than test timeout of 15 minutes! See ../../dart_test.yaml.
 }) async {
   final Stopwatch clock = Stopwatch()..start();
   final Process process = await processManager.start(
@@ -358,7 +355,7 @@
     } finally {
       tryToDelete(fileSystem.directory(tempDirectory));
     }
-  }, skip: platform.isWindows); // https://github.com/flutter/flutter/issues/87924
+  }, skip: Platform.isWindows); // [intended] Windows doesn't support sending signals so we don't care if it can store the PID.
 
   testWithoutContext('flutter run handle SIGUSR1/2', () async {
     final String tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_overall_experience_test.').resolveSymbolicLinksSync();
@@ -622,5 +619,5 @@
       '',
       'Application finished.',
     ]);
-  }, skip: Platform.isWindows); // TODO(zanderso): Re-enable when this test is reliable on device lab, https://github.com/flutter/flutter/issues/81556
+  });
 }
diff --git a/packages/flutter_tools/test/src/common.dart b/packages/flutter_tools/test/src/common.dart
index 529fd9e..79c9192 100644
--- a/packages/flutter_tools/test/src/common.dart
+++ b/packages/flutter_tools/test/src/common.dart
@@ -148,7 +148,6 @@
 @isTest
 void test(String description, FutureOr<void> Function() body, {
   String? testOn,
-  Timeout? timeout,
   dynamic skip,
   List<String>? tags,
   Map<String, dynamic>? onPlatform,
@@ -162,12 +161,14 @@
       });
       return body();
     },
-    timeout: timeout,
     skip: skip,
     tags: tags,
     onPlatform: onPlatform,
     retry: retry,
     testOn: testOn,
+    // We don't support "timeout"; see ../../dart_test.yaml which
+    // configures all tests to have a 15 minute timeout which should
+    // definitely be enough.
   );
 }
 
@@ -182,7 +183,6 @@
 @isTest
 void testWithoutContext(String description, FutureOr<void> Function() body, {
   String? testOn,
-  Timeout? timeout,
   dynamic skip,
   List<String>? tags,
   Map<String, dynamic>? onPlatform,
@@ -194,12 +194,14 @@
         contextKey: const _NoContext(),
       });
     },
-    timeout: timeout,
     skip: skip,
     tags: tags,
     onPlatform: onPlatform,
     retry: retry,
     testOn: testOn,
+    // We don't support "timeout"; see ../../dart_test.yaml which
+    // configures all tests to have a 15 minute timeout which should
+    // definitely be enough.
   );
 }
 
diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart
index c224a27..38abdae 100644
--- a/packages/flutter_tools/test/src/context.dart
+++ b/packages/flutter_tools/test/src/context.dart
@@ -62,7 +62,6 @@
   Map<Type, Generator> overrides = const <Type, Generator>{},
   bool initializeFlutterRoot = true,
   String testOn,
-  Timeout timeout,
   bool skip, // should default to `false`, but https://github.com/dart-lang/test/issues/545 doesn't allow this
 }) {
   if (overrides[FileSystem] != null && overrides[ProcessManager] == null) {
@@ -167,7 +166,10 @@
       // BotDetector implementation in the overrides.
       BotDetector: overrides[BotDetector] ?? () => const FakeBotDetector(true),
     });
-  }, testOn: testOn, skip: skip, timeout: timeout);
+  }, testOn: testOn, skip: skip);
+  // We don't support "timeout"; see ../../dart_test.yaml which
+  // configures all tests to have a 15 minute timeout which should
+  // definitely be enough.
 }
 
 void _printBufferedErrors(AppContext testContext) {
diff --git a/packages/flutter_tools/test/general.shard/web/chrome_test.dart b/packages/flutter_tools/test/web.shard/chrome_test.dart
similarity index 98%
rename from packages/flutter_tools/test/general.shard/web/chrome_test.dart
rename to packages/flutter_tools/test/web.shard/chrome_test.dart
index b4d4d96..10b1c25 100644
--- a/packages/flutter_tools/test/general.shard/web/chrome_test.dart
+++ b/packages/flutter_tools/test/web.shard/chrome_test.dart
@@ -12,9 +12,9 @@
 import 'package:flutter_tools/src/base/platform.dart';
 import 'package:flutter_tools/src/web/chrome.dart';
 
-import '../../src/common.dart';
-import '../../src/fake_process_manager.dart';
-import '../../src/fakes.dart';
+import '../src/common.dart';
+import '../src/fake_process_manager.dart';
+import '../src/fakes.dart';
 
 const List<String> kChromeArgs = <String>[
   '--disable-background-timer-throttling',
@@ -547,7 +547,7 @@
       contains('Unable to connect to Chrome debug port:'),
     );
     expect(logger.errorText, contains('SocketException'));
-  }, timeout: const Timeout.factor(2));
+  });
 }
 
 Future<Chromium> _testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {