@@ -10,6 +10,16 @@ import '../framework/devices.dart';
10
10
import '../framework/framework.dart' ;
11
11
import '../framework/task_result.dart' ;
12
12
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
+ }
13
23
14
24
TaskFunction createGalleryTransitionTest ({bool semanticsEnabled = false }) {
15
25
return GalleryTransitionTest (semanticsEnabled: semanticsEnabled);
@@ -176,6 +186,137 @@ class GalleryTransitionTest {
176
186
}
177
187
}
178
188
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
+
179
320
int _countMissedTransitions (Map <String , List <int >> transitions) {
180
321
const int kTransitionBudget = 100000 ; // µs
181
322
int count = 0 ;
0 commit comments