mirror of
https://github.com/flutter/flutter
synced 2024-08-25 02:46:31 +00:00
allow passing file path as reference to devicelab task (#6877)
This commit is contained in:
parent
473df6d632
commit
4145f5fcfd
|
@ -7,13 +7,15 @@ This package contains the code for test framework and the tests. More generally
|
|||
the tests are referred to as "tasks" in the API, but since we primarily use it
|
||||
for testing, this document refers to them as "tests".
|
||||
|
||||
If you have access to Google's internal network, you can see the continuous build results from the master branch at
|
||||
<http://go/flutter-dashboard/build.html>. (There is currently no public view of this data, unfortunately.)
|
||||
If you have access to Google's internal network, you can see the continuous
|
||||
build results from the master branch at <http://go/flutter-dashboard/build.html>.
|
||||
(There is currently no public view of this data, unfortunately.)
|
||||
|
||||
# Prerequisites
|
||||
|
||||
You must set the `ANDROID_HOME` environment variable to run tests on Android. If you
|
||||
have a local build of the Flutter engine, then you have a copy of the Android SDK at `.../engine/src/third_party/android_tools/sdk`.
|
||||
You must set the `ANDROID_HOME` environment variable to run tests on Android. If
|
||||
you have a local build of the Flutter engine, then you have a copy of the
|
||||
Android SDK at `.../engine/src/third_party/android_tools/sdk`.
|
||||
|
||||
# Running tests locally
|
||||
|
||||
|
@ -26,10 +28,16 @@ To run a test, use option `-t` (`--task`):
|
|||
|
||||
```sh
|
||||
# from the .../flutter/dev/devicelab directory
|
||||
dart bin/run.dart -t {NAME_OF_TEST}
|
||||
dart bin/run.dart -t {NAME_OR_PATH_OF_TEST}
|
||||
```
|
||||
|
||||
You can see the test names in the `manifest.yaml` file in this directory or by looking in `bin/tasks/`. Do not include the `.dart` file extension. For example, `dart bin/run.dart -t complex_layout__start_up`.
|
||||
Where `NAME_OR_PATH_OF_TEST` can be either of:
|
||||
|
||||
- the _name_ of a task, which you can find in the `manifest.yaml` file in this
|
||||
directory. Example: `complex_layout__start_up`.
|
||||
- the path to a Dart _file_ corresponding to a task, which resides in `bin/tasks`.
|
||||
Tip: most shells support path auto-completion using the Tab key. Example:
|
||||
`bin/tasks/complex_layout__start_up.dart`.
|
||||
|
||||
To run multiple tests, repeat option `-t` (`--task`) multiple times:
|
||||
|
||||
|
@ -54,8 +62,8 @@ Currently there are only two stages defined, `devicelab` and `devicelab_ios`.
|
|||
# Reproducing broken builds locally
|
||||
|
||||
If a commit caused a test to fail,
|
||||
[the dashboard](http://go/flutter-dashboard/build.html) (requires access to the Google network, sorry) might look something
|
||||
like this:
|
||||
[the dashboard](http://go/flutter-dashboard/build.html) (requires access to the
|
||||
Google network, sorry) might look something like this:
|
||||
|
||||
![Broken Test](images/broken-test.png)
|
||||
|
||||
|
|
|
@ -7,11 +7,14 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'package:flutter_devicelab/framework/manifest.dart';
|
||||
import 'package:flutter_devicelab/framework/runner.dart';
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
|
||||
List<String> _taskNames = <String>[];
|
||||
|
||||
/// Runs tasks.
|
||||
///
|
||||
/// The tasks are chosen depending on the command-line options
|
||||
|
@ -28,24 +31,23 @@ Future<Null> main(List<String> rawArgs) async {
|
|||
return null;
|
||||
}
|
||||
|
||||
List<String> taskNames = <String>[];
|
||||
if (args.wasParsed('task')) {
|
||||
taskNames.addAll(args['task']);
|
||||
} else if (args.wasParsed('stage')) {
|
||||
String stageName = args['stage'];
|
||||
List<ManifestTask> tasks = loadTaskManifest().tasks;
|
||||
for (ManifestTask task in tasks) {
|
||||
if (task.stage == stageName)
|
||||
taskNames.add(task.name);
|
||||
}
|
||||
} else if (args.wasParsed('all')) {
|
||||
List<ManifestTask> tasks = loadTaskManifest().tasks;
|
||||
for (ManifestTask task in tasks) {
|
||||
taskNames.add(task.name);
|
||||
if (!args.wasParsed('task')) {
|
||||
if (args.wasParsed('stage')) {
|
||||
String stageName = args['stage'];
|
||||
List<ManifestTask> tasks = loadTaskManifest().tasks;
|
||||
for (ManifestTask task in tasks) {
|
||||
if (task.stage == stageName)
|
||||
_taskNames.add(task.name);
|
||||
}
|
||||
} else if (args.wasParsed('all')) {
|
||||
List<ManifestTask> tasks = loadTaskManifest().tasks;
|
||||
for (ManifestTask task in tasks) {
|
||||
_taskNames.add(task.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (taskNames.isEmpty) {
|
||||
if (_taskNames.isEmpty) {
|
||||
stderr.writeln('Failed to find tasks to run based on supplied options.');
|
||||
exitCode = 1;
|
||||
return null;
|
||||
|
@ -53,7 +55,7 @@ Future<Null> main(List<String> rawArgs) async {
|
|||
|
||||
bool silent = args['silent'];
|
||||
|
||||
for (String taskName in taskNames) {
|
||||
for (String taskName in _taskNames) {
|
||||
section('Running task "$taskName"');
|
||||
Map<String, dynamic> result = await runTask(taskName, silent: silent);
|
||||
|
||||
|
@ -73,9 +75,27 @@ final ArgParser _argParser = new ArgParser()
|
|||
abbr: 't',
|
||||
allowMultiple: true,
|
||||
splitCommas: true,
|
||||
help: 'Name of the task to run. This option may be repeated to '
|
||||
'specify multiple tasks. A task selected by name does not have to be '
|
||||
'defined in manifest.yaml. It only needs a Dart executable in bin/tasks.',
|
||||
help: 'Either:\n'
|
||||
' - the name of a task defined in manifest.yaml. Example: complex_layout__start_up.\n'
|
||||
' - the path to a Dart file corresponding to a task, which resides in bin/tasks. Example: bin/tasks/complex_layout__start_up.dart.\n'
|
||||
'\n'
|
||||
'This option may be repeated to specify multiple tasks.',
|
||||
callback: (List<String> value) {
|
||||
for (String nameOrPath in value) {
|
||||
List<String> fragments = path.split(nameOrPath);
|
||||
bool isDartFile = fragments.last.endsWith('.dart');
|
||||
|
||||
if (fragments.length == 1 && !isDartFile) {
|
||||
// Not a path
|
||||
_taskNames.add(nameOrPath);
|
||||
} else if (!isDartFile || fragments.length != 3 || !_listsEqual(<String>['bin', 'tasks'], fragments.take(2).toList())) {
|
||||
// Unsupported executable location
|
||||
throw new FormatException('Invalid value for option -t (--task): $nameOrPath');
|
||||
} else {
|
||||
_taskNames.add(path.withoutExtension(fragments.last));
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
..addOption(
|
||||
'stage',
|
||||
|
@ -106,3 +126,14 @@ final ArgParser _argParser = new ArgParser()
|
|||
negatable: true,
|
||||
defaultsTo: false,
|
||||
);
|
||||
|
||||
bool _listsEqual(List<dynamic> a, List<dynamic> b) {
|
||||
if (a.length != b.length) return false;
|
||||
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,23 +21,31 @@ void main() {
|
|||
return scriptProcess.exitCode;
|
||||
}
|
||||
|
||||
test('Exits with code 0 when succeeds', () async {
|
||||
test('exits with code 0 when succeeds', () async {
|
||||
expect(await runScript(<String>['smoke_test_success']), 0);
|
||||
});
|
||||
|
||||
test('Exits with code 1 when task throws', () async {
|
||||
test('accepts file paths', () async {
|
||||
expect(await runScript(<String>['bin/tasks/smoke_test_success.dart']), 0);
|
||||
});
|
||||
|
||||
test('rejects invalid file paths', () async {
|
||||
expect(await runScript(<String>['lib/framework/adb.dart']), 1);
|
||||
});
|
||||
|
||||
test('exits with code 1 when task throws', () async {
|
||||
expect(await runScript(<String>['smoke_test_throws']), 1);
|
||||
});
|
||||
|
||||
test('Exits with code 1 when fails', () async {
|
||||
test('exits with code 1 when fails', () async {
|
||||
expect(await runScript(<String>['smoke_test_failure']), 1);
|
||||
});
|
||||
|
||||
test('Exits with code 1 when fails to connect', () async {
|
||||
test('exits with code 1 when fails to connect', () async {
|
||||
expect(await runScript(<String>['smoke_test_setup_failure']), 1);
|
||||
}, skip: true); // https://github.com/flutter/flutter/issues/5901
|
||||
|
||||
test('Exits with code 1 when results are mixed', () async {
|
||||
test('exits with code 1 when results are mixed', () async {
|
||||
expect(
|
||||
await runScript(<String>[
|
||||
'smoke_test_failure',
|
||||
|
|
Loading…
Reference in a new issue