Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e27f7144
Unverified
Commit
e27f7144
authored
Feb 28, 2022
by
Emmanuel Garcia
Committed by
GitHub
Feb 28, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add regression test for #98973 (#99187)
parent
bf1ddbf3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
215 additions
and
0 deletions
+215
-0
.ci.yaml
.ci.yaml
+11
-0
TESTOWNERS
TESTOWNERS
+1
-0
android_choreographer_do_frame_test.dart
...icelab/bin/tasks/android_choreographer_do_frame_test.dart
+10
-0
android_choreographer_do_frame_test.dart
...icelab/lib/tasks/android_choreographer_do_frame_test.dart
+193
-0
No files found.
.ci.yaml
View file @
e27f7144
...
@@ -2378,6 +2378,17 @@ targets:
...
@@ -2378,6 +2378,17 @@ targets:
benchmark
:
"
true"
benchmark
:
"
true"
scheduler
:
luci
scheduler
:
luci
-
name
:
Linux_android android_choreographer_do_frame_test
bringup
:
true
recipe
:
devicelab/devicelab_drone
presubmit
:
false
timeout
:
60
properties
:
tags
:
>
["devicelab","android","linux"]
task_name
:
android_choreographer_do_frame_test
scheduler
:
luci
-
name
:
Mac build_aar_module_test
-
name
:
Mac build_aar_module_test
recipe
:
devicelab/devicelab_drone
recipe
:
devicelab/devicelab_drone
timeout
:
60
timeout
:
60
...
...
TESTOWNERS
View file @
e27f7144
...
@@ -71,6 +71,7 @@
...
@@ -71,6 +71,7 @@
/dev/devicelab/bin/tasks/opacity_peephole_fade_transition_text_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/opacity_peephole_fade_transition_text_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/android_choreographer_do_frame_test.dart @blasten @flutter/engine
## Windows Android DeviceLab tests
## Windows Android DeviceLab tests
/dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @zanderso @flutter/tool
/dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @zanderso @flutter/tool
...
...
dev/devicelab/bin/tasks/android_choreographer_do_frame_test.dart
0 → 100644
View file @
e27f7144
// 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
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/tasks/android_choreographer_do_frame_test.dart'
;
Future
<
void
>
main
()
async
{
await
task
(
androidChoreographerDoFrameTest
());
}
dev/devicelab/lib/tasks/android_choreographer_do_frame_test.dart
0 → 100644
View file @
e27f7144
// 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:convert'
;
import
'dart:io'
;
import
'package:path/path.dart'
as
path
;
import
'../framework/framework.dart'
;
import
'../framework/task_result.dart'
;
import
'../framework/utils.dart'
;
const
List
<
String
>
kSentinelStr
=
<
String
>[
'==== sentinel #1 ===='
,
'==== sentinel #2 ===='
,
'==== sentinel #3 ===='
,
];
// Regression test for https://github.com/flutter/flutter/issues/98973
// This test ensures that Choreographer#doFrame finishes during application startup.
// This test fails if the application hangs during this period.
// https://ui.perfetto.dev/#!/?s=da6628c3a92456ae8fa3f345d0186e781da77e90fc8a64d073e9fee11d1e65
TaskFunction
androidChoreographerDoFrameTest
(
{
String
?
deviceIdOverride
,
Map
<
String
,
String
>?
environment
,
})
{
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_devicelab_android_surface_recreation.'
);
return
()
async
{
try
{
section
(
'Create app'
);
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--platforms'
,
'android'
,
'app'
,
],
environment:
environment
,
);
});
final
File
mainDart
=
File
(
path
.
join
(
tempDir
.
absolute
.
path
,
'app'
,
'lib'
,
'main.dart'
,
));
if
(!
mainDart
.
existsSync
())
{
return
TaskResult
.
failure
(
'
${mainDart.path}
does not exist'
);
}
section
(
'Patch lib/main.dart'
);
await
mainDart
.
writeAsString
(
'''
import '
package:
flutter
/
material
.
dart
';
import '
package:
flutter
/
services
.
dart
';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
print('
$
{
kSentinelStr
[
0
]}
');
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
print('
$
{
kSentinelStr
[
1
]}
');
// If the Android UI thread is blocked, then this Future won'
t
resolve
.
await
SystemChrome
.
setEnabledSystemUIMode
(
SystemUiMode
.
immersiveSticky
);
print
(
'
${kSentinelStr[2]}
'
);
runApp
(
Container
(
decoration:
BoxDecoration
(
color:
const
Color
(
0xff7c94b6
),
),
),
);
}
''', flush: true);
Future<TaskResult> runTestFor(String mode) async {
int nextCompleterIdx = 0;
final Map<String, Completer<void>> sentinelCompleters = <String, Completer<void>>{};
for (final String sentinel in kSentinelStr) {
sentinelCompleters[sentinel] = Completer<void>();
}
section('
Flutter
run
(
mode:
$mode
)
');
await inDirectory(path.join(tempDir.path, '
app
'), () async {
final Process run = await startProcess(
path.join(flutterDirectory.path, '
bin
', '
flutter
'),
flutterCommandArgs('
run
', <String>['
--
$mode
', '
--
verbose
']),
);
int currSentinelIdx = 0;
final StreamSubscription<void> stdout = run.stdout
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.listen((String line) {
if (currSentinelIdx < sentinelCompleters.keys.length &&
line.contains(sentinelCompleters.keys.elementAt(currSentinelIdx))) {
sentinelCompleters.values.elementAt(currSentinelIdx).complete();
currSentinelIdx++;
print('
stdout
(
MATCHED
):
$line
');
} else {
print('
stdout:
$line
');
}
});
final StreamSubscription<void> stderr = run.stderr
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter())
.listen((String line) {
print('
stderr:
$line
');
});
final Completer<void> exitCompleter = Completer<void>();
unawaited(run.exitCode.then((int exitCode) {
exitCompleter.complete();
}));
section('
Wait
for
sentinels
(
mode:
$mode
)
');
for (final Completer<void> completer in sentinelCompleters.values) {
if (nextCompleterIdx == 0) {
// Don'
t
time
out
because
we
don
't know how long it would take to get the first log.
await Future.any<dynamic>(
<Future<dynamic>>[
completer.future,
exitCompleter.future,
],
);
} else {
try {
// Time out since this should not take 1s after the first log was received.
await Future.any<dynamic>(
<Future<dynamic>>[
completer.future.timeout(const Duration(seconds: 1)),
exitCompleter.future,
],
);
} on TimeoutException {
break;
}
}
if (exitCompleter.isCompleted) {
// The process exited.
break;
}
nextCompleterIdx++;
}
section('
Quit
app
(
mode:
$mode
)
');
run.stdin.write('
q
');
await exitCompleter.future;
section('
Stop
listening
to
stdout
and
stderr
(
mode:
$mode
)
');
await stdout.cancel();
await stderr.cancel();
run.kill();
});
if (nextCompleterIdx == sentinelCompleters.values.length) {
return TaskResult.success(null);
}
final String nextSentinel = sentinelCompleters.keys.elementAt(nextCompleterIdx);
return TaskResult.failure('
Expected
sentinel
`
$nextSentinel
`
in
mode
$mode
');
}
final TaskResult debugResult = await runTestFor('
debug
');
if (debugResult.failed) {
return debugResult;
}
final TaskResult profileResult = await runTestFor('
profile
');
if (profileResult.failed) {
return profileResult;
}
final TaskResult releaseResult = await runTestFor('
release
');
if (releaseResult.failed) {
return releaseResult;
}
return TaskResult.success(null);
} finally {
rmTree(tempDir);
}
};
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment