Skip to content

Commit 9ac9049

Browse files
authored
Try with bringup: true debugging why flutter build apk often times out. (#158895)
It would be nice to have somewhere to iterate and experiment with what we can do to either fix frequent timeout problems we have with `flutter build apk` (across platforms, to be clear, though I've just started with Linux) or get more information on why the crashes/timeouts happen. Open to other ways to doing this (though preferably _not_ LED).
1 parent cc6ee0c commit 9ac9049

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

.ci.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,29 @@ targets:
13301330
- bin/**
13311331
- .ci.yaml
13321332

1333+
- name: Linux flutter_build_apk_health_tests
1334+
recipe: flutter/flutter_drone
1335+
# WARNING: Do *NOT* enable. This intended for testing on CI only.
1336+
# Ask matanlurey@ or @gmackall if you have any questions.
1337+
bringup: true
1338+
timeout: 60
1339+
properties:
1340+
add_recipes_cq: "true"
1341+
dependencies: >-
1342+
[
1343+
{"dependency": "android_sdk", "version": "version:35v1"},
1344+
{"dependency": "chrome_and_driver", "version": "version:125.0.6422.141"},
1345+
{"dependency": "clang", "version": "git_revision:5d5aba78dbbee75508f01bcaa69aedb2ab79065a"},
1346+
{"dependency": "cmake", "version": "build_id:8787856497187628321"},
1347+
{"dependency": "goldctl", "version": "git_revision:2387d6fff449587eecbb7e45b2692ca0710b63b9"},
1348+
{"dependency": "ninja", "version": "version:1.9.0"},
1349+
{"dependency": "open_jdk", "version": "version:17"}
1350+
]
1351+
shard: flutter_build_apk_health_tests
1352+
tags: >
1353+
["framework", "hostonly", "shard", "linux"]
1354+
test_timeout_secs: "2700"
1355+
13331356
- name: Linux android_preview_tool_integration_tests
13341357
recipe: flutter/flutter_drone
13351358
timeout: 60

TESTOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@
329329
# coverage @goderbauer @flutter/infra
330330
# customer_testing @Piinks @flutter/framework
331331
# docs @Piinks @flutter/framework
332+
# flutter_build_apk_health_tests @matanlurey @gmackall
332333
# flutter_driver_android_test @matanlurey @johnmccutchan
333334
# flutter_packaging @christopherfujino @flutter/infra
334335
# flutter_plugins @stuartmorgan @flutter/plugin

dev/bots/test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ Future<void> main(List<String> args) async {
132132
'tool_tests': _runToolTests,
133133
'web_tool_tests': _runWebToolTests,
134134
'tool_integration_tests': _runIntegrationToolTests,
135+
'flutter_build_apk_health_tests': _runFlutterBuildApkHealthTests,
135136
'android_preview_tool_integration_tests': androidPreviewIntegrationToolTestsRunner,
136137
'android_java11_tool_integration_tests': androidJava11IntegrationToolTestsRunner,
137138
'tool_host_cross_arch_tests': _runToolHostCrossArchTests,
@@ -234,6 +235,20 @@ Future<void> _runIntegrationToolTests() async {
234235
);
235236
}
236237

238+
Future<void> _runFlutterBuildApkHealthTests() async {
239+
final List<String> allTests = Directory(path.join(_toolsPath, 'test', 'flutter_build_apk.shard'))
240+
.listSync(recursive: true).whereType<File>()
241+
.map<String>((FileSystemEntity entry) => path.relative(entry.path, from: _toolsPath))
242+
.where((String testPath) => path.basename(testPath).endsWith('_test.dart')).toList();
243+
244+
await runDartTest(
245+
_toolsPath,
246+
forceSingleCore: true,
247+
testPaths: selectIndexOfTotalSubshard<String>(allTests),
248+
collectMetrics: true,
249+
);
250+
}
251+
237252
Future<void> _runToolTests() async {
238253
await selectSubshard(<String, ShardRunner>{
239254
'general': _runGeneralToolTests,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `flutter_build_apk.shard`
2+
3+
Integration tests that debug why `flutter build apk` sometimes stalls on CI.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:io' as io;
6+
7+
import 'package:file/file.dart';
8+
9+
import '../integration.shard/test_utils.dart';
10+
import '../src/common.dart';
11+
12+
void main() {
13+
final String flutterRoot = getFlutterRoot();
14+
final String flutterBin = fileSystem.path.join(flutterRoot, 'bin', 'flutter');
15+
16+
late Directory tmpDir;
17+
18+
setUp(() {
19+
tmpDir = fileSystem.systemTempDirectory.createTempSync();
20+
});
21+
22+
tearDown(() {
23+
tryToDelete(tmpDir);
24+
});
25+
26+
Future<void> setGradleLoggingLevel(
27+
String level, {
28+
required Directory projectDir,
29+
}) async {
30+
// Open gradle.properties and append to it.
31+
final Directory androidDir = projectDir.childDirectory('android');
32+
final File gradleDotProperties = androidDir.childFile('gradle.properties');
33+
final io.IOSink sink = gradleDotProperties.openWrite(mode: FileMode.append);
34+
35+
sink.writeln('org.gradle.logging.level=$level');
36+
await sink.flush();
37+
await sink.close();
38+
39+
// For debugging, print the current output.
40+
io.stderr.writeln('${gradleDotProperties.path}:');
41+
io.stderr.writeln(gradleDotProperties.readAsStringSync());
42+
}
43+
44+
// Normally these tests should take about a minute, but sometimes for
45+
// unknown reasons they can take 30m+ and timeout. The intent behind this loop
46+
// is to get more information on what exactly is happening.
47+
for (int i = 1; i <= 10; i++) {
48+
test('flutter build apk | attempt $i of 10', () async {
49+
final String package = 'flutter_build_apk_test_$i';
50+
51+
// Create a new Flutter app.
52+
await expectLater(
53+
processManager.run(
54+
<String>[
55+
flutterBin,
56+
'create',
57+
package,
58+
],
59+
workingDirectory: tmpDir.path,
60+
),
61+
completion(const ProcessResultMatcher()),
62+
reason: 'Should create a new blank Flutter project',
63+
);
64+
65+
// Tweak verbosity of just gradle.
66+
final Directory projectDir = tmpDir.childDirectory(package);
67+
await setGradleLoggingLevel('debug', projectDir: projectDir);
68+
69+
// Build the APK.
70+
final List<String> args = <String>[
71+
flutterBin,
72+
'--verbose',
73+
'build',
74+
'apk',
75+
'--debug',
76+
];
77+
io.stderr.writeln('Running $args...');
78+
79+
final io.Process process = await processManager.start(
80+
args,
81+
workingDirectory: projectDir.path,
82+
mode: io.ProcessStartMode.inheritStdio,
83+
);
84+
await expectLater(process.exitCode, completion(0));
85+
});
86+
}
87+
}

0 commit comments

Comments
 (0)