Skip to content

Commit 5e216d4

Browse files
authored
Simplify devicelab logic and fix tests (#139122)
- fix flutter/flutter#53707 by having the test not expect a timeout but instead actually look for the retry message - simplify the `--task` option to only accept task names rather than also accepting paths - remove some obsolete options that referred to the manifest which no longer seems to exist
1 parent c532865 commit 5e216d4

File tree

6 files changed

+59
-61
lines changed

6 files changed

+59
-61
lines changed

dev/devicelab/README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,11 @@ To run a test, use option `-t` (`--task`):
6666

6767
```sh
6868
# from the .../flutter/dev/devicelab directory
69-
../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t {NAME_OR_PATH_OF_TEST}
69+
../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t {NAME_OF_TEST}
7070
```
7171

72-
Where `NAME_OR_PATH_OF_TEST` can be either of:
73-
74-
* the _name_ of a task, which is a file's basename in `bin/tasks`. Example:
75-
`complex_layout__start_up`.
76-
* the path to a Dart _file_ corresponding to a task, which resides in
77-
`bin/tasks`. Tip: most shells support path auto-completion using the Tab key.
78-
Example: `bin/tasks/complex_layout__start_up.dart`.
72+
Where `NAME_OR_PATH_OF_TEST` is the name of a task, which is a file's
73+
basename in `bin/tasks`. Example: `complex_layout__start_up`.
7974

8075
To run multiple tests, repeat option `-t` (`--task`) multiple times:
8176

@@ -261,4 +256,4 @@ Take gallery tasks for example:
261256
1. Linux android
262257
- Separating PR: https://github.com/flutter/flutter/pull/103550
263258
- Switching PR: https://github.com/flutter/flutter/pull/110533
264-
2. Mac iOS: https://github.com/flutter/flutter/pull/111164
259+
2. Mac iOS: https://github.com/flutter/flutter/pull/111164

dev/devicelab/bin/run.dart

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:flutter_devicelab/framework/ab.dart';
1010
import 'package:flutter_devicelab/framework/runner.dart';
1111
import 'package:flutter_devicelab/framework/task_result.dart';
1212
import 'package:flutter_devicelab/framework/utils.dart';
13-
import 'package:path/path.dart' as path;
1413

1514
/// Runs tasks.
1615
///
@@ -235,29 +234,12 @@ ArgParser createArgParser(List<String> taskNames) {
235234
..addMultiOption(
236235
'task',
237236
abbr: 't',
238-
help: 'Either:\n'
239-
' - the name of a task defined in manifest.yaml.\n'
240-
' Example: complex_layout__start_up.\n'
241-
' - the path to a Dart file corresponding to a task,\n'
242-
' which resides in bin/tasks.\n'
243-
' Example: bin/tasks/complex_layout__start_up.dart.\n'
237+
help: 'Name of a Dart file in bin/tasks.\n'
238+
' Example: complex_layout__start_up\n'
244239
'\n'
245240
'This option may be repeated to specify multiple tasks.',
246-
callback: (List<String> value) {
247-
for (final String nameOrPath in value) {
248-
final List<String> fragments = path.split(nameOrPath);
249-
final bool isDartFile = fragments.last.endsWith('.dart');
250-
251-
if (fragments.length == 1 && !isDartFile) {
252-
// Not a path
253-
taskNames.add(nameOrPath);
254-
} else if (!isDartFile || !path.equals(path.dirname(nameOrPath), path.join('bin', 'tasks'))) {
255-
// Unsupported executable location
256-
throw FormatException('Invalid value for option -t (--task): $nameOrPath');
257-
} else {
258-
taskNames.add(path.withoutExtension(fragments.last));
259-
}
260-
}
241+
callback: (List<String> tasks) {
242+
taskNames.addAll(tasks);
261243
},
262244
)
263245
..addOption(
@@ -339,14 +321,6 @@ ArgParser createArgParser(List<String> taskNames) {
339321
'the location based on the value of the --flutter-root option.',
340322
)
341323
..addOption('luci-builder', help: '[Flutter infrastructure] Name of the LUCI builder being run on.')
342-
..addFlag(
343-
'match-host-platform',
344-
defaultsTo: true,
345-
help: 'Only run tests that match the host platform (e.g. do not run a\n'
346-
'test with a `required_agent_capabilities` value of "mac/android"\n'
347-
'on a windows host). Each test publishes its '
348-
'`required_agent_capabilities`\nin the `manifest.yaml` file.',
349-
)
350324
..addOption(
351325
'results-file',
352326
help: '[Flutter infrastructure] File path for test results. If passed with\n'

dev/devicelab/bin/tasks/smoke_test_setup_failure.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
/// By not calling `task()` the VM service extension is not registered and
88
/// therefore will not accept requests to run tasks. When the runner attempts to
99
/// connect and run the test it will receive a "method not found" error from the
10-
/// VM service, will likely retry and finally time out.
10+
/// VM service, will likely retry forever.
11+
///
12+
/// The test in ../../test/run_test.dart runs this task until it detects
13+
/// the retry message and then aborts the task.
1114
Future<void> main() async {}

dev/devicelab/lib/framework/runner.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ Future<TaskResult> runTask(
171171
final String taskExecutable = 'bin/tasks/$taskName.dart';
172172

173173
if (!file(taskExecutable).existsSync()) {
174-
throw 'Executable Dart file not found: $taskExecutable';
174+
print('Executable Dart file not found: $taskExecutable');
175+
exit(1);
175176
}
176177

177178
if (useEmulator) {
@@ -288,7 +289,13 @@ Future<ConnectionResult> _connectToRunnerIsolate(Uri vmServiceUri) async {
288289
return ConnectionResult(client, isolate);
289290
} catch (error) {
290291
if (stopwatch.elapsed > const Duration(seconds: 10)) {
291-
print('VM service still not ready after ${stopwatch.elapsed}: $error\nContinuing to retry...');
292+
print(
293+
'VM service still not ready. It is possible the target has failed.\n'
294+
'Latest connection error:\n'
295+
' $error\n'
296+
'Continuing to retry...\n',
297+
);
298+
stopwatch.reset();
292299
}
293300
await Future<void>.delayed(const Duration(milliseconds: 50));
294301
}

dev/devicelab/test/run_test.dart

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:convert';
56
import 'dart:io';
67

78
import 'package:flutter_devicelab/framework/utils.dart' show rm;
@@ -12,45 +13,54 @@ import 'common.dart';
1213

1314
void main() {
1415
const ProcessManager processManager = LocalProcessManager();
16+
final String dart = path.absolute(
17+
path.join('..', '..', 'bin', 'cache', 'dart-sdk', 'bin', 'dart'));
1518

1619
group('run.dart script', () {
17-
Future<ProcessResult> runScript(List<String> testNames,
20+
// The tasks here refer to files in ../bin/tasks/*.dart
21+
22+
Future<ProcessResult> runScript(List<String> taskNames,
1823
[List<String> otherArgs = const <String>[]]) async {
19-
final String dart = path.absolute(
20-
path.join('..', '..', 'bin', 'cache', 'dart-sdk', 'bin', 'dart'));
2124
final ProcessResult scriptProcess = processManager.runSync(<String>[
2225
dart,
2326
'bin/run.dart',
2427
'--no-terminate-stray-dart-processes',
2528
...otherArgs,
26-
for (final String testName in testNames) ...<String>['-t', testName],
29+
for (final String testName in taskNames) ...<String>['-t', testName],
2730
]);
2831
return scriptProcess;
2932
}
3033

3134
Future<void> expectScriptResult(
32-
List<String> testNames,
35+
List<String> taskNames,
3336
int expectedExitCode,
3437
{String? deviceId}
3538
) async {
36-
final ProcessResult result = await runScript(testNames, <String>[
39+
final ProcessResult result = await runScript(taskNames, <String>[
3740
if (deviceId != null) ...<String>['-d', deviceId],
3841
]);
39-
expect(result.exitCode, expectedExitCode,
40-
reason:
41-
'[ stderr from test process ]\n\n${result.stderr}\n\n[ end of stderr ]'
42-
'\n\n[ stdout from test process ]\n\n${result.stdout}\n\n[ end of stdout ]');
42+
expect(
43+
result.exitCode,
44+
expectedExitCode,
45+
reason:
46+
'[ stderr from test process ]\n'
47+
'\n'
48+
'${result.stderr}\n'
49+
'\n'
50+
'[ end of stderr ]\n'
51+
'\n'
52+
'[ stdout from test process ]\n'
53+
'\n'
54+
'${result.stdout}\n'
55+
'\n'
56+
'[ end of stdout ]',
57+
);
4358
}
4459

4560
test('exits with code 0 when succeeds', () async {
4661
await expectScriptResult(<String>['smoke_test_success'], 0);
4762
});
4863

49-
test('accepts file paths', () async {
50-
await expectScriptResult(
51-
<String>['bin/tasks/smoke_test_success.dart'], 0);
52-
});
53-
5464
test('rejects invalid file paths', () async {
5565
await expectScriptResult(<String>['lib/framework/adb.dart'], 1);
5666
});
@@ -63,9 +73,18 @@ void main() {
6373
await expectScriptResult(<String>['smoke_test_failure'], 1);
6474
});
6575

66-
test('exits with code 1 when fails to connect', () async {
67-
await expectScriptResult(<String>['smoke_test_setup_failure'], 1);
68-
}, skip: true); // https://github.com/flutter/flutter/issues/53707
76+
test('prints a message after a few seconds when failing to connect (this test takes >10s)', () async {
77+
final Process process = await processManager.start(<String>[
78+
dart,
79+
'bin/run.dart',
80+
'--no-terminate-stray-dart-processes',
81+
'-t', 'smoke_test_setup_failure',
82+
]);
83+
await process.stdout.transform(utf8.decoder).where(
84+
(String line) => line.contains('VM service still not ready. It is possible the target has failed')
85+
).first;
86+
expect(process.kill(), isTrue);
87+
});
6988

7089
test('exits with code 1 when results are mixed', () async {
7190
await expectScriptResult(

packages/flutter_goldens_client/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ dartdoc:
1919
# Exclude this package from the hosted API docs.
2020
nodoc: true
2121

22-
# PUBSPEC CHECKSUM: 1c2e
22+
# PUBSPEC CHECKSUM: 1c2e

0 commit comments

Comments
 (0)