mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix flaky complex_layout_scroll_perf__memory & flutter_gallery__memory_nav (#150368)
Initial tap is missing sometimes; either its never delivered or it is delivered before gesture controller is hooked up. 1: Update MemoryTest to have option `requiresTapToStart` guarding the new paths 2: Update the two perf tests that appear to be flaky to output when TAPPED is received 3: Update the MemoryTest to keep tapping while waiting for TAPPED Tested on devicelab: * setting iterations=1 * removing the timeout before READY * running tests in a while loop Before this change, you could get the test to hang often. After this change you'll see "tapping device... [x]" where x is the counter. Fixes https://github.com/flutter/flutter/issues/150096
This commit is contained in:
parent
7960958327
commit
e80bbd929e
@ -23,7 +23,7 @@ Future<void> main() async {
|
|||||||
final Completer<void> ready = Completer<void>();
|
final Completer<void> ready = Completer<void>();
|
||||||
runApp(GestureDetector(
|
runApp(GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
debugPrint('Received tap.');
|
debugPrint('==== MEMORY BENCHMARK ==== TAPPED ====');
|
||||||
ready.complete();
|
ready.complete();
|
||||||
},
|
},
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
@ -32,16 +32,14 @@ Future<void> main() async {
|
|||||||
),
|
),
|
||||||
));
|
));
|
||||||
await SchedulerBinding.instance.endOfFrame;
|
await SchedulerBinding.instance.endOfFrame;
|
||||||
|
|
||||||
/// Wait 50ms to allow the raster thread to actually put up the frame. (The
|
|
||||||
/// endOfFrame future ends when we send the data to the engine, before
|
|
||||||
/// the raster thread has had a chance to rasterize, etc.)
|
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
|
||||||
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
|
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
|
||||||
|
|
||||||
await ready.future; // waits for tap sent by devicelab task
|
await ready.future; // waits for tap sent by devicelab task
|
||||||
debugPrint('Continuing...');
|
debugPrint('Continuing...');
|
||||||
|
|
||||||
|
// Wait out any errant taps due to synchronization
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
||||||
|
|
||||||
// remove onTap handler, enable pointer events for app
|
// remove onTap handler, enable pointer events for app
|
||||||
runApp(GestureDetector(
|
runApp(GestureDetector(
|
||||||
child: const IgnorePointer(
|
child: const IgnorePointer(
|
||||||
|
@ -13,5 +13,6 @@ Future<void> main() async {
|
|||||||
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
'${flutterDirectory.path}/dev/benchmarks/complex_layout',
|
||||||
'test_memory/scroll_perf.dart',
|
'test_memory/scroll_perf.dart',
|
||||||
'com.yourcompany.complexLayout',
|
'com.yourcompany.complexLayout',
|
||||||
|
requiresTapToStart: true,
|
||||||
).run);
|
).run);
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,6 @@ Future<void> main() async {
|
|||||||
'${flutterDirectory.path}/dev/integration_tests/flutter_gallery',
|
'${flutterDirectory.path}/dev/integration_tests/flutter_gallery',
|
||||||
'test_memory/memory_nav.dart',
|
'test_memory/memory_nav.dart',
|
||||||
'io.flutter.demo.gallery',
|
'io.flutter.demo.gallery',
|
||||||
|
requiresTapToStart: true,
|
||||||
).run);
|
).run);
|
||||||
}
|
}
|
||||||
|
@ -1968,11 +1968,12 @@ class CompileTest {
|
|||||||
|
|
||||||
/// Measure application memory usage.
|
/// Measure application memory usage.
|
||||||
class MemoryTest {
|
class MemoryTest {
|
||||||
MemoryTest(this.project, this.test, this.package);
|
MemoryTest(this.project, this.test, this.package, {this.requiresTapToStart = false});
|
||||||
|
|
||||||
final String project;
|
final String project;
|
||||||
final String test;
|
final String test;
|
||||||
final String package;
|
final String package;
|
||||||
|
final bool requiresTapToStart;
|
||||||
|
|
||||||
/// Completes when the log line specified in the last call to
|
/// Completes when the log line specified in the last call to
|
||||||
/// [prepareForNextMessage] is seen by `adb logcat`.
|
/// [prepareForNextMessage] is seen by `adb logcat`.
|
||||||
@ -2061,6 +2062,38 @@ class MemoryTest {
|
|||||||
await receivedNextMessage;
|
await receivedNextMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Taps the application and looks for acknowldgement.
|
||||||
|
///
|
||||||
|
/// This is used by several tests to ensure scrolling gestures are installed.
|
||||||
|
Future<void> tapNotification() async {
|
||||||
|
// Keep "tapping" the device till it responds with the string we expect,
|
||||||
|
// or throw an error instead of tying up the infrastructure for 30 minutes.
|
||||||
|
prepareForNextMessage('TAPPED');
|
||||||
|
bool tapped = false;
|
||||||
|
int tapCount = 0;
|
||||||
|
await Future.any(<Future<void>>[
|
||||||
|
() async {
|
||||||
|
while (true) {
|
||||||
|
if (tapped) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tapCount += 1;
|
||||||
|
print('tapping device... [$tapCount]');
|
||||||
|
await device!.tap(100, 100);
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 100));
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
() async {
|
||||||
|
print('awaiting "tapped" message... (timeout: 10 seconds)');
|
||||||
|
try {
|
||||||
|
await receivedNextMessage?.timeout(const Duration(seconds: 10));
|
||||||
|
} finally {
|
||||||
|
tapped = true;
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/// To change the behavior of the test, override this.
|
/// To change the behavior of the test, override this.
|
||||||
///
|
///
|
||||||
/// Make sure to call recordStart() and recordEnd() once each in that order.
|
/// Make sure to call recordStart() and recordEnd() once each in that order.
|
||||||
@ -2070,10 +2103,11 @@ class MemoryTest {
|
|||||||
Future<void> useMemory() async {
|
Future<void> useMemory() async {
|
||||||
await launchApp();
|
await launchApp();
|
||||||
await recordStart();
|
await recordStart();
|
||||||
|
if (requiresTapToStart) {
|
||||||
|
await tapNotification();
|
||||||
|
}
|
||||||
|
|
||||||
prepareForNextMessage('DONE');
|
prepareForNextMessage('DONE');
|
||||||
print('tapping device...');
|
|
||||||
await device!.tap(100, 100);
|
|
||||||
print('awaiting "done" message...');
|
print('awaiting "done" message...');
|
||||||
await receivedNextMessage;
|
await receivedNextMessage;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ Future<void> main() async {
|
|||||||
final Completer<void> ready = Completer<void>();
|
final Completer<void> ready = Completer<void>();
|
||||||
runApp(GestureDetector(
|
runApp(GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
debugPrint('Received tap.');
|
debugPrint('==== MEMORY BENCHMARK ==== TAPPED ====');
|
||||||
ready.complete();
|
ready.complete();
|
||||||
},
|
},
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
@ -35,12 +35,14 @@ Future<void> main() async {
|
|||||||
),
|
),
|
||||||
));
|
));
|
||||||
await SchedulerBinding.instance.endOfFrame;
|
await SchedulerBinding.instance.endOfFrame;
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
|
||||||
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
|
debugPrint('==== MEMORY BENCHMARK ==== READY ====');
|
||||||
|
|
||||||
await ready.future;
|
await ready.future;
|
||||||
debugPrint('Continuing...');
|
debugPrint('Continuing...');
|
||||||
|
|
||||||
|
// Wait out any errant taps due to synchronization
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
||||||
|
|
||||||
// remove onTap handler, enable pointer events for app
|
// remove onTap handler, enable pointer events for app
|
||||||
runApp(GestureDetector(
|
runApp(GestureDetector(
|
||||||
child: const IgnorePointer(
|
child: const IgnorePointer(
|
||||||
|
Loading…
Reference in New Issue
Block a user