Skip to content

Commit abebd8b

Browse files
authored
Separate build and test for flutter_gallery__transition_perf task (#103550)
1 parent 1602ea2 commit abebd8b

File tree

2 files changed

+143
-2
lines changed

2 files changed

+143
-2
lines changed

dev/devicelab/bin/tasks/flutter_gallery__transition_perf.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:flutter_devicelab/framework/devices.dart';
66
import 'package:flutter_devicelab/framework/framework.dart';
77
import 'package:flutter_devicelab/tasks/gallery.dart';
88

9-
Future<void> main() async {
9+
Future<void> main(List<String> args) async {
1010
deviceOperatingSystem = DeviceOperatingSystem.android;
11-
await task(createGalleryTransitionTest());
11+
await task(createGalleryTransitionBuildTest(args));
1212
}

dev/devicelab/lib/tasks/gallery.dart

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ import '../framework/devices.dart';
1010
import '../framework/framework.dart';
1111
import '../framework/task_result.dart';
1212
import '../framework/utils.dart';
13+
import 'build_test_task.dart';
14+
15+
final Directory galleryDirectory = dir('${flutterDirectory.path}/dev/integration_tests/flutter_gallery');
16+
17+
/// Temp function during gallery tests transition to build+test model.
18+
///
19+
/// https://github.com/flutter/flutter/issues/103542
20+
TaskFunction createGalleryTransitionBuildTest(List<String> args, {bool semanticsEnabled = false}) {
21+
return GalleryTransitionBuildTest(args, semanticsEnabled: semanticsEnabled);
22+
}
1323

1424
TaskFunction createGalleryTransitionTest({bool semanticsEnabled = false}) {
1525
return GalleryTransitionTest(semanticsEnabled: semanticsEnabled);
@@ -176,6 +186,137 @@ class GalleryTransitionTest {
176186
}
177187
}
178188

189+
class GalleryTransitionBuildTest extends BuildTestTask {
190+
GalleryTransitionBuildTest(
191+
super.args, {
192+
this.semanticsEnabled = false,
193+
this.testFile = 'transitions_perf',
194+
this.needFullTimeline = true,
195+
this.timelineSummaryFile = 'transitions.timeline_summary',
196+
this.timelineTraceFile = 'transitions.timeline',
197+
this.transitionDurationFile = 'transition_durations.timeline',
198+
this.driverFile,
199+
this.measureCpuGpu = true,
200+
this.measureMemory = true,
201+
}) : super(workingDirectory: galleryDirectory);
202+
203+
final bool semanticsEnabled;
204+
final bool needFullTimeline;
205+
final bool measureCpuGpu;
206+
final bool measureMemory;
207+
final String testFile;
208+
final String timelineSummaryFile;
209+
final String? timelineTraceFile;
210+
final String? transitionDurationFile;
211+
final String? driverFile;
212+
213+
final String testOutputDirectory = Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? '${galleryDirectory.path}/build';
214+
215+
@override
216+
List<String> getBuildArgs(DeviceOperatingSystem deviceOperatingSystem) {
217+
return <String>[
218+
'apk',
219+
'--no-android-gradle-daemon',
220+
'--profile',
221+
'-t',
222+
'test_driver/$testFile.dart',
223+
'--target-platform',
224+
'android-arm,android-arm64',
225+
];
226+
}
227+
228+
@override
229+
List<String> getTestArgs(DeviceOperatingSystem deviceOperatingSystem, String deviceId) {
230+
final String testDriver = driverFile ?? (semanticsEnabled ? '${testFile}_with_semantics_test' : '${testFile}_test');
231+
return <String>[
232+
'--profile',
233+
if (needFullTimeline) '--trace-startup',
234+
'-t',
235+
'test_driver/$testFile.dart',
236+
'--use-application-binary=${getApplicationBinaryPath()}',
237+
'--driver',
238+
'test_driver/$testDriver.dart',
239+
'-d',
240+
deviceId,
241+
];
242+
}
243+
244+
@override
245+
Future<TaskResult> parseTaskResult() async {
246+
final Map<String, dynamic> summary = json.decode(
247+
file('$testOutputDirectory/$timelineSummaryFile.json').readAsStringSync(),
248+
) as Map<String, dynamic>;
249+
250+
if (transitionDurationFile != null) {
251+
final Map<String, dynamic> original = json.decode(
252+
file('$testOutputDirectory/$transitionDurationFile.json').readAsStringSync(),
253+
) as Map<String, dynamic>;
254+
final Map<String, List<int>> transitions = <String, List<int>>{};
255+
for (final String key in original.keys) {
256+
transitions[key] = List<int>.from(original[key] as List<dynamic>);
257+
}
258+
summary['transitions'] = transitions;
259+
summary['missed_transition_count'] = _countMissedTransitions(transitions);
260+
}
261+
262+
final bool isAndroid = deviceOperatingSystem == DeviceOperatingSystem.android;
263+
return TaskResult.success(
264+
summary,
265+
detailFiles: <String>[
266+
if (transitionDurationFile != null) '$testOutputDirectory/$transitionDurationFile.json',
267+
if (timelineTraceFile != null) '$testOutputDirectory/$timelineTraceFile.json',
268+
],
269+
benchmarkScoreKeys: <String>[
270+
if (transitionDurationFile != null) 'missed_transition_count',
271+
'average_frame_build_time_millis',
272+
'worst_frame_build_time_millis',
273+
'90th_percentile_frame_build_time_millis',
274+
'99th_percentile_frame_build_time_millis',
275+
'average_frame_rasterizer_time_millis',
276+
'worst_frame_rasterizer_time_millis',
277+
'90th_percentile_frame_rasterizer_time_millis',
278+
'99th_percentile_frame_rasterizer_time_millis',
279+
'average_layer_cache_count',
280+
'90th_percentile_layer_cache_count',
281+
'99th_percentile_layer_cache_count',
282+
'worst_layer_cache_count',
283+
'average_layer_cache_memory',
284+
'90th_percentile_layer_cache_memory',
285+
'99th_percentile_layer_cache_memory',
286+
'worst_layer_cache_memory',
287+
'average_picture_cache_count',
288+
'90th_percentile_picture_cache_count',
289+
'99th_percentile_picture_cache_count',
290+
'worst_picture_cache_count',
291+
'average_picture_cache_memory',
292+
'90th_percentile_picture_cache_memory',
293+
'99th_percentile_picture_cache_memory',
294+
'worst_picture_cache_memory',
295+
if (measureCpuGpu && !isAndroid) ...<String>[
296+
// See https://github.com/flutter/flutter/issues/68888
297+
if (summary['average_cpu_usage'] != null) 'average_cpu_usage',
298+
if (summary['average_gpu_usage'] != null) 'average_gpu_usage',
299+
],
300+
if (measureMemory && !isAndroid) ...<String>[
301+
// See https://github.com/flutter/flutter/issues/68888
302+
if (summary['average_memory_usage'] != null) 'average_memory_usage',
303+
if (summary['90th_percentile_memory_usage'] != null) '90th_percentile_memory_usage',
304+
if (summary['99th_percentile_memory_usage'] != null) '99th_percentile_memory_usage',
305+
],
306+
],
307+
);
308+
}
309+
310+
@override
311+
String getApplicationBinaryPath() {
312+
if (applicationBinaryPath != null) {
313+
return applicationBinaryPath!;
314+
}
315+
316+
return 'build/app/outputs/flutter-apk/app-profile.apk';
317+
}
318+
}
319+
179320
int _countMissedTransitions(Map<String, List<int>> transitions) {
180321
const int kTransitionBudget = 100000; // µs
181322
int count = 0;

0 commit comments

Comments
 (0)