Experiment with tester on the flutter_tools general shard (#60490)
Use tester (disclaimer, written by me) to unit test the flutter tools general shard. Since these tests are designed to be hermetic, the single compilation/single isolate model offers a tremendous speedup over the default pub run test workflow. On previous linux shard, test execution alone took 10:30, while now it takes only 1:30.
diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index d9a9f6e..0aa9d99 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -302,8 +302,6 @@
}
Future<void> _runToolTests() async {
- final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
-
const String kDotShard = '.shard';
const String kTest = 'test';
final String toolsPath = path.join(flutterRoot, 'packages', 'flutter_tools');
@@ -321,14 +319,21 @@
final String suffix = Platform.isWindows && subshard == 'commands'
? 'permeable'
: '';
- await _pubRunTest(
- toolsPath,
- testPaths: <String>[path.join(kTest, '$subshard$kDotShard', suffix)],
- tableData: bigqueryApi?.tabledata,
- enableFlutterToolAsserts: true,
- // Detect unit test time regressions (poor time delay handling, etc).
- perTestTimeout: (subshard == 'general') ? const Duration(seconds: 2) : null,
- );
+ // Try out tester on unit test shard
+ if (subshard == 'general') {
+ await _pubRunTester(
+ toolsPath,
+ testPaths: <String>[path.join(kTest, '$subshard$kDotShard', suffix)],
+ // Detect unit test time regressions (poor time delay handling, etc).
+ perTestTimeout: (subshard == 'general') ? 15 : null,
+ );
+ } else {
+ await _pubRunTest(
+ toolsPath,
+ testPaths: <String>[path.join(kTest, '$subshard$kDotShard', suffix)],
+ enableFlutterToolAsserts: true,
+ );
+ }
},
);
@@ -925,6 +930,67 @@
);
}
+const String _supportedTesterVersion = '0.0.1-dev9';
+
+Future<void> _pubRunTester(String workingDirectory, {
+ List<String> testPaths,
+ bool forceSingleCore = false,
+ int perTestTimeout,
+}) async {
+ 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.
+ }
+ // Integration tests that depend on external processes like chrome
+ // can get stuck if there are multiple instances running at once.
+ if (forceSingleCore) {
+ cpus = 1;
+ }
+ final List<String> args = <String>[
+ 'global',
+ 'activate',
+ 'tester',
+ _supportedTesterVersion
+ ];
+ final Map<String, String> pubEnvironment = <String, String>{
+ 'FLUTTER_ROOT': flutterRoot,
+ };
+ if (Directory(pubCache).existsSync()) {
+ pubEnvironment['PUB_CACHE'] = pubCache;
+ }
+ await runCommand(
+ pub,
+ args,
+ workingDirectory: workingDirectory,
+ environment: pubEnvironment,
+ );
+ await runCommand(
+ pub,
+ <String>[
+ 'global',
+ 'run',
+ 'tester',
+ '-j$cpus',
+ '--ci',
+ if (perTestTimeout != null)
+ '--timeout=$perTestTimeout'
+ else
+ '--timeout=-1',
+ ...testPaths,
+ ],
+ workingDirectory: workingDirectory,
+ environment: pubEnvironment,
+ );
+}
+
Future<void> _pubRunTest(String workingDirectory, {
List<String> testPaths,
bool enableFlutterToolAsserts = true,