Unverified Commit 360023e2 authored by Ming Lyu (CareF)'s avatar Ming Lyu (CareF) Committed by GitHub

Clean up flutter_gallery__transition_perf (#63609)

parent 8f896c90
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter_devicelab/tasks/gallery.dart';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android;
await task(createGalleryTransitionHybridTest());
}
......@@ -11,14 +11,15 @@ import '../framework/adb.dart';
import '../framework/framework.dart';
import '../framework/utils.dart';
TaskFunction createGalleryTransitionTest({ bool semanticsEnabled = false }) {
TaskFunction createGalleryTransitionTest({bool semanticsEnabled = false}) {
return GalleryTransitionTest(semanticsEnabled: semanticsEnabled);
}
TaskFunction createGalleryTransitionE2ETest({ bool semanticsEnabled = false }) {
TaskFunction createGalleryTransitionE2ETest({bool semanticsEnabled = false}) {
return GalleryTransitionTest(
semanticsEnabled: semanticsEnabled,
testFile: 'transitions_perf_e2e',
testFile: semanticsEnabled
? 'transitions_perf_e2e_with_semantics'
: 'transitions_perf_e2e',
needFullTimeline: false,
timelineSummaryFile: 'e2e_perf_summary',
transitionDurationFile: null,
......@@ -26,6 +27,15 @@ TaskFunction createGalleryTransitionE2ETest({ bool semanticsEnabled = false }) {
);
}
TaskFunction createGalleryTransitionHybridTest({bool semanticsEnabled = false}) {
return GalleryTransitionTest(
semanticsEnabled: semanticsEnabled,
driverFile: semanticsEnabled
? 'transitions_perf_hybrid_with_semantics_test'
: 'transitions_perf_hybrid_test',
);
}
class GalleryTransitionTest {
GalleryTransitionTest({
......@@ -53,18 +63,18 @@ class GalleryTransitionTest {
await inDirectory<void>(galleryDirectory, () async {
await flutter('packages', options: <String>['get']);
final String testDriver = semanticsEnabled
? '${testFile}_with_semantics.dart'
: '$testFile.dart';
final String testDriver = driverFile ?? (semanticsEnabled
? '${testFile}_test'
: '${testFile}_with_semantics_test');
await flutter('drive', options: <String>[
'--profile',
if (needFullTimeline)
'--trace-startup',
'-t',
'test_driver/$testDriver',
if (driverFile != null)
...<String>['--driver', 'test_driver/$driverFile.dart'],
'test_driver/$testFile.dart',
'--driver',
'test_driver/$testDriver.dart',
'-d',
deviceId,
]);
......
......@@ -769,6 +769,16 @@ tasks:
required_agent_capabilities: ["linux/android"]
flaky: true
flutter_gallery__transition_perf_hybrid:
description: >
Measures the performance of screen transitions in Flutter Gallery on
Android where the page transitions are self-driven on device without host
interventions, but the timeline events are still sent to host to be
processed.
stage: devicelab
required_agent_capabilities: ["linux/android"]
flaky: true
flutter_gallery_sksl_warmup__transition_perf:
description: >
Measures the runtime performance of Flutter gallery transitions on Android
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_gallery/demo_lists.dart';
const List<String> kSkippedDemos = <String>[];
/// Scrolls each demo menu item into view, launches it, then returns to the
/// home screen twice.
Future<void> runDemos(List<String> demos, WidgetController controller) async {
final Finder demoList = find.byType(Scrollable);
String currentDemoCategory;
for (final String demo in demos) {
if (kSkippedDemos.contains(demo))
continue;
final String demoName = demo.substring(0, demo.indexOf('@'));
final String demoCategory = demo.substring(demo.indexOf('@') + 1);
print('> $demo');
await controller.pump(const Duration(milliseconds: 250));
if (currentDemoCategory == null) {
await controller.tap(find.text(demoCategory));
await controller.pumpAndSettle();
} else if (currentDemoCategory != demoCategory) {
await controller.tap(find.byTooltip('Back'));
await controller.pumpAndSettle();
await controller.tap(find.text(demoCategory));
await controller.pumpAndSettle();
// Scroll back to the top
await controller.drag(demoList, const Offset(0.0, 10000.0));
await controller.pumpAndSettle(const Duration(milliseconds: 100));
}
currentDemoCategory = demoCategory;
final Finder demoItem = find.text(demoName);
await controller.scrollUntilVisible(demoItem, 48.0);
await controller.pumpAndSettle();
Future<void> pageBack() {
Finder backButton = find.byTooltip('Back');
if (backButton.evaluate().isEmpty) {
backButton = find.byType(CupertinoNavigationBarBackButton);
}
return controller.tap(backButton);
}
for (int i = 0; i < 2; i += 1) {
await controller.tap(demoItem); // Launch the demo
if (kUnsynchronizedDemos.contains(demo)) {
// These tests have animation, pumpAndSettle cannot be used.
// This time is questionable. 400ms is the tested reasonable result.
await controller.pump(const Duration(milliseconds: 400));
await controller.pump();
await pageBack();
} else {
await controller.pumpAndSettle();
// page back
await pageBack();
}
await controller.pumpAndSettle();
}
print('< Success');
}
// Return to the home screen
await controller.tap(find.byTooltip('Back'));
await controller.pumpAndSettle();
}
......@@ -7,18 +7,47 @@ import 'dart:convert' show JsonEncoder;
import 'package:flutter_driver/driver_extension.dart';
import 'package:flutter_gallery/gallery/demos.dart';
import 'package:flutter_gallery/demo_lists.dart';
import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
Future<String> _handleMessages(String message) async {
assert(message == 'demoNames');
return const JsonEncoder.withIndent(' ').convert(
kAllGalleryDemos.map((GalleryDemo demo) => '${demo.title}@${demo.category.name}').toList(),
);
import 'run_demos.dart';
// All of the gallery demos, identified as "title@category".
//
// These names are reported by the test app, see _handleMessages()
// in transitions_perf.dart.
List<String> _allDemos = kAllGalleryDemos.map(
(GalleryDemo demo) => '${demo.title}@${demo.category.name}',
).toList();
Set<String> _unTestedDemos = Set<String>.from(_allDemos);
class _MessageHandler {
static LiveWidgetController controller;
Future<String> call(String message) async {
switch(message) {
case 'demoNames':
return const JsonEncoder.withIndent(' ').convert(_allDemos);
case 'profileDemos':
controller ??= LiveWidgetController(WidgetsBinding.instance);
await runDemos(kProfiledDemos, controller);
_unTestedDemos.removeAll(kProfiledDemos);
return const JsonEncoder.withIndent(' ').convert(kProfiledDemos);
case 'restDemos':
controller ??= LiveWidgetController(WidgetsBinding.instance);
final List<String> restDemos = _unTestedDemos.toList();
await runDemos(restDemos, controller);
return const JsonEncoder.withIndent(' ').convert(restDemos);
default:
throw ArgumentError;
}
}
}
void main() {
enableFlutterDriverExtension(handler: _handleMessages);
enableFlutterDriverExtension(handler: _MessageHandler());
// As in lib/main.dart: overriding https://github.com/flutter/flutter/issues/13736
// for better visual effect at the cost of performance.
runApp(const GalleryApp(testMode: true));
......
......@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -16,6 +13,7 @@ import 'package:flutter_gallery/gallery/demos.dart';
import 'package:flutter_gallery/demo_lists.dart';
import 'e2e_utils.dart';
import 'run_demos.dart';
const List<String> kSkippedDemos = <String>[];
......@@ -27,72 +25,6 @@ List<String> _allDemos = kAllGalleryDemos.map(
(GalleryDemo demo) => '${demo.title}@${demo.category.name}',
).toList();
/// Scrolls each demo menu item into view, launches it, then returns to the
/// home screen twice.
Future<void> runDemos(List<String> demos, WidgetController controller) async {
final Finder demoList = find.byType(Scrollable);
String currentDemoCategory;
for (final String demo in demos) {
if (kSkippedDemos.contains(demo))
continue;
final String demoName = demo.substring(0, demo.indexOf('@'));
final String demoCategory = demo.substring(demo.indexOf('@') + 1);
print('> $demo');
await controller.pump(const Duration(milliseconds: 250));
if (currentDemoCategory == null) {
await controller.tap(find.text(demoCategory));
await controller.pumpAndSettle();
} else if (currentDemoCategory != demoCategory) {
await controller.tap(find.byTooltip('Back'));
await controller.pumpAndSettle();
await controller.tap(find.text(demoCategory));
await controller.pumpAndSettle();
// Scroll back to the top
await controller.drag(demoList, const Offset(0.0, 10000.0));
await controller.pumpAndSettle(const Duration(milliseconds: 100));
}
currentDemoCategory = demoCategory;
final Finder demoItem = find.text(demoName);
await controller.scrollUntilVisible(demoItem, 48.0);
await controller.pumpAndSettle();
Future<void> pageBack() {
Finder backButton = find.byTooltip('Back');
if (backButton.evaluate().isEmpty) {
backButton = find.byType(CupertinoNavigationBarBackButton);
}
return controller.tap(backButton);
}
for (int i = 0; i < 2; i += 1) {
await controller.tap(demoItem); // Launch the demo
if (kUnsynchronizedDemos.contains(demo)) {
// These tests have animation, pumpAndSettle cannot be used.
// This time is questionable. 300ms is the tested reasonable result.
await controller.pump(const Duration(milliseconds: 300));
await controller.pump();
await pageBack();
} else {
await controller.pumpAndSettle();
// page back
await pageBack();
}
await controller.pumpAndSettle();
}
print('< Success');
}
// Return to the home screen
await controller.tap(find.byTooltip('Back'));
await controller.pumpAndSettle();
}
void main([List<String> args = const <String>[]]) {
final bool withSemantics = args.contains('--with_semantics');
final E2EWidgetsFlutterBinding binding =
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'transitions_perf.dart' as transitions_perf;
import 'transitions_perf_test.dart' as transitions_perf_test;
void main() {
transitions_perf.main();
}
void main([List<String> args = const <String>[]]) => transitions_perf_test.main(
<String>['--hybrid', ...args],
);
......@@ -153,6 +153,7 @@ Future<void> runDemos(List<String> demos, FlutterDriver driver) async {
void main([List<String> args = const <String>[]]) {
final bool withSemantics = args.contains('--with_semantics');
final bool hybrid = args.contains('--hybrid');
group('flutter gallery transitions', () {
FlutterDriver driver;
setUpAll(() async {
......@@ -186,7 +187,11 @@ void main([List<String> args = const <String>[]]) {
// Collect timeline data for just a limited set of demos to avoid OOMs.
final Timeline timeline = await driver.traceAction(
() async {
if (hybrid) {
await driver.requestData('profileDemos');
} else {
await runDemos(kProfiledDemos, driver);
}
},
streams: const <TimelineStream>[
TimelineStream.dart,
......@@ -205,8 +210,12 @@ void main([List<String> args = const <String>[]]) {
histogramPath);
// Execute the remaining tests.
if (hybrid) {
await driver.requestData('profileDemos');
} else {
final Set<String> unprofiledDemos = Set<String>.from(_allDemos)..removeAll(kProfiledDemos);
await runDemos(unprofiledDemos.toList(), driver);
}
}, timeout: const Timeout(Duration(minutes: 5)));
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment