Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: tools/testing/dart/android.dart

Issue 1940853002: Add support for timeouts when using AdbPrecompilationCommand (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/testing/dart/test_runner.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library android; 5 library android;
6 6
7 import "dart:async"; 7 import "dart:async";
8 import "dart:convert" show LineSplitter, UTF8; 8 import "dart:convert" show LineSplitter, UTF8;
9 import "dart:core"; 9 import "dart:core";
10 import "dart:collection"; 10 import "dart:collection";
11 import "dart:io"; 11 import "dart:io";
12 12
13 import "path.dart"; 13 import "path.dart";
14 import "utils.dart"; 14 import "utils.dart";
15 15
16 class AdbCommandResult { 16 class AdbCommandResult {
17 final String command; 17 final String command;
18 final String stdout; 18 final String stdout;
19 final String stderr; 19 final String stderr;
20 final int exitCode; 20 final int exitCode;
21 final bool timedOut;
21 22
22 AdbCommandResult(this.command, this.stdout, this.stderr, this.exitCode); 23 AdbCommandResult(this.command, this.stdout, this.stderr, this.exitCode,
24 this.timedOut);
23 25
24 void throwIfFailed() { 26 void throwIfFailed() {
25 if (exitCode != 0) { 27 if (exitCode != 0) {
26 var error = "Running: $command failed:" 28 var error = "Running: $command failed:"
27 "stdout: \n $stdout" 29 "stdout:\n ${stdout.trim()}\n"
28 "stderr: \n $stderr" 30 "stderr:\n ${stderr.trim()}\n"
29 "exitCode: \n $exitCode"; 31 "exitCode: $exitCode\n"
32 "timedOut: $timedOut";
30 throw new Exception(error); 33 throw new Exception(error);
31 } 34 }
32 } 35 }
33 } 36 }
34 37
35 /** 38 /**
36 * [_executeCommand] will write [stdin] to the standard input of the created 39 * [_executeCommand] will write [stdin] to the standard input of the created
37 * process and will return a tuple (stdout, stderr). 40 * process and will return a tuple (stdout, stderr).
38 * 41 *
39 * If the exit code of the process was nonzero it will complete with an error. 42 * If the exit code of the process was nonzero it will complete with an error.
40 * If starting the process failed, it will complete with an error as well. 43 * If starting the process failed, it will complete with an error as well.
41 */ 44 */
42 Future<AdbCommandResult> _executeCommand( 45 Future<AdbCommandResult> _executeCommand(
43 String executable, List<String> args, [String stdin = ""]) { 46 String executable, List<String> args,
47 [String stdin = "", Duration timeout]) {
Bill Hesse 2016/05/02 11:54:17 Should these now be named, not positional, optiona
kustermann 2016/05/02 11:59:40 Done.
44 Future<String> getOutput(Stream<List<int>> stream) { 48 Future<String> getOutput(Stream<List<int>> stream) {
45 return stream 49 return stream
46 .transform(UTF8.decoder) 50 .transform(UTF8.decoder)
47 .toList() 51 .toList()
48 .then((data) => data.join("")); 52 .then((data) => data.join(""));
49 } 53 }
50 54
51 return Process.start(executable, args).then((Process process) async { 55 return Process.start(executable, args).then((Process process) async {
52 if (stdin != null && stdin != '') { 56 if (stdin != null && stdin != '') {
53 process.stdin.write(stdin); 57 process.stdin.write(stdin);
54 } 58 }
55 process.stdin.close(); 59 process.stdin.close();
56 60
61 Timer timer;
62 bool timedOut = false;
63 if (timeout != null) {
64 timer = new Timer(timeout, () {
65 timedOut = true;
66 process.kill(ProcessSignal.SIGTERM);
67 timer = null;
68 });
69 }
70
57 var results = await Future.wait([ 71 var results = await Future.wait([
58 getOutput(process.stdout), 72 getOutput(process.stdout),
59 getOutput(process.stderr), 73 getOutput(process.stderr),
60 process.exitCode 74 process.exitCode
61 ]); 75 ]);
76 if (timer != null) timer.cancel();
77
62 String command = "$executable ${args.join(' ')}"; 78 String command = "$executable ${args.join(' ')}";
63 return new AdbCommandResult(command, results[0], results[1], results[2]); 79 return new AdbCommandResult(
80 command, results[0], results[1], results[2], timedOut);
64 }); 81 });
65 } 82 }
66 83
67 /** 84 /**
68 * Helper class to loop through all adb ports. 85 * Helper class to loop through all adb ports.
69 * 86 *
70 * The ports come in pairs: 87 * The ports come in pairs:
71 * - even number: console connection 88 * - even number: console connection
72 * - odd number: adb connection 89 * - odd number: adb connection
73 * Note that this code doesn't check if the ports are used. 90 * Note that this code doesn't check if the ports are used.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 298 }
282 299
283 /** 300 /**
284 * Kill all background processes. 301 * Kill all background processes.
285 */ 302 */
286 Future killAll() { 303 Future killAll() {
287 var arguments = ['shell', 'am', 'kill-all']; 304 var arguments = ['shell', 'am', 'kill-all'];
288 return _adbCommand(arguments); 305 return _adbCommand(arguments);
289 } 306 }
290 307
291 Future<AdbCommandResult> runAdbCommand(List<String> adbArgs) { 308 Future<AdbCommandResult> runAdbCommand(List<String> adbArgs,
292 return _executeCommand("adb", _deviceSpecificArgs(adbArgs)); 309 {Duration timeout}) {
310 return _executeCommand("adb", _deviceSpecificArgs(adbArgs), '', timeout);
293 } 311 }
294 312
295 Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs) async { 313 Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs,
314 {Duration timeout}) async {
296 const MARKER = 'AdbShellExitCode: '; 315 const MARKER = 'AdbShellExitCode: ';
297 316
298 // The exitcode of 'adb shell ...' can be 0 even though the command failed 317 // The exitcode of 'adb shell ...' can be 0 even though the command failed
299 // with a non-zero exit code. We therefore explicitly print it to stdout and 318 // with a non-zero exit code. We therefore explicitly print it to stdout and
300 // search for it. 319 // search for it.
301 320
302 var args = ['shell', 321 var args = ['shell',
303 "${shellArgs.join(' ')} ; echo $MARKER \$?"]; 322 "${shellArgs.join(' ')} ; echo $MARKER \$?"];
304 AdbCommandResult result = await _executeCommand( 323 AdbCommandResult result = await _executeCommand(
305 "adb", _deviceSpecificArgs(args)); 324 "adb", _deviceSpecificArgs(args), '', timeout);
306 int exitCode = result.exitCode; 325 int exitCode = result.exitCode;
307 var lines = result 326 var lines = result
308 .stdout.split('\n') 327 .stdout.split('\n')
309 .where((line) => line.trim().length > 0) 328 .where((line) => line.trim().length > 0)
310 .toList(); 329 .toList();
311 if (lines.length > 0) { 330 if (lines.length > 0) {
312 int index = lines.last.indexOf(MARKER); 331 int index = lines.last.indexOf(MARKER);
313 assert(index >= 0); 332 if (index >= 0) {
314 exitCode = int.parse(lines.last.substring(index + MARKER.length).trim()); 333 exitCode = int.parse(
334 lines.last.substring(index + MARKER.length).trim());
335 } else {
336 // In case of timeouts, for example, we won't get the exitcode marker.
337 assert(result.exitCode != 0);
338 }
315 } 339 }
316 return new AdbCommandResult( 340 return new AdbCommandResult(
317 result.command, result.stdout, result.stderr, exitCode); 341 result.command, result.stdout, result.stderr, exitCode,
342 result.timedOut);
318 } 343 }
319 344
320 Future<AdbCommandResult> _adbCommand(List<String> adbArgs) async { 345 Future<AdbCommandResult> _adbCommand(List<String> adbArgs) async {
321 var result = await _executeCommand("adb", _deviceSpecificArgs(adbArgs)); 346 var result = await _executeCommand("adb", _deviceSpecificArgs(adbArgs));
322 result.throwIfFailed(); 347 result.throwIfFailed();
323 return result; 348 return result;
324 } 349 }
325 350
326 List<String> _deviceSpecificArgs(List<String> adbArgs) { 351 List<String> _deviceSpecificArgs(List<String> adbArgs) {
327 if (_deviceId != null) { 352 if (_deviceId != null) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 425
401 void releaseDevice(AdbDevice device) { 426 void releaseDevice(AdbDevice device) {
402 if (_waiter.length > 0) { 427 if (_waiter.length > 0) {
403 Completer completer = _waiter.removeFirst(); 428 Completer completer = _waiter.removeFirst();
404 completer.complete(device); 429 completer.complete(device);
405 } else { 430 } else {
406 _idleDevices.add(device); 431 _idleDevices.add(device);
407 } 432 }
408 } 433 }
409 } 434 }
OLDNEW
« no previous file with comments | « no previous file | tools/testing/dart/test_runner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698