Index: tools/testing/dart/android.dart |
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart |
index e6ab95e27258e0afe4f5c43ba3da162b9de0dd2b..b68d000a8a52d1f7a03aaefc4783369eaf9b1adf 100644 |
--- a/tools/testing/dart/android.dart |
+++ b/tools/testing/dart/android.dart |
@@ -18,15 +18,18 @@ class AdbCommandResult { |
final String stdout; |
final String stderr; |
final int exitCode; |
+ final bool timedOut; |
- AdbCommandResult(this.command, this.stdout, this.stderr, this.exitCode); |
+ AdbCommandResult(this.command, this.stdout, this.stderr, this.exitCode, |
+ this.timedOut); |
void throwIfFailed() { |
if (exitCode != 0) { |
var error = "Running: $command failed:" |
- "stdout: \n $stdout" |
- "stderr: \n $stderr" |
- "exitCode: \n $exitCode"; |
+ "stdout:\n ${stdout.trim()}\n" |
+ "stderr:\n ${stderr.trim()}\n" |
+ "exitCode: $exitCode\n" |
+ "timedOut: $timedOut"; |
throw new Exception(error); |
} |
} |
@@ -40,7 +43,8 @@ class AdbCommandResult { |
* If starting the process failed, it will complete with an error as well. |
*/ |
Future<AdbCommandResult> _executeCommand( |
- String executable, List<String> args, [String stdin = ""]) { |
+ String executable, List<String> args, |
+ [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.
|
Future<String> getOutput(Stream<List<int>> stream) { |
return stream |
.transform(UTF8.decoder) |
@@ -54,13 +58,26 @@ Future<AdbCommandResult> _executeCommand( |
} |
process.stdin.close(); |
+ Timer timer; |
+ bool timedOut = false; |
+ if (timeout != null) { |
+ timer = new Timer(timeout, () { |
+ timedOut = true; |
+ process.kill(ProcessSignal.SIGTERM); |
+ timer = null; |
+ }); |
+ } |
+ |
var results = await Future.wait([ |
getOutput(process.stdout), |
getOutput(process.stderr), |
process.exitCode |
]); |
+ if (timer != null) timer.cancel(); |
+ |
String command = "$executable ${args.join(' ')}"; |
- return new AdbCommandResult(command, results[0], results[1], results[2]); |
+ return new AdbCommandResult( |
+ command, results[0], results[1], results[2], timedOut); |
}); |
} |
@@ -288,11 +305,13 @@ class AdbDevice { |
return _adbCommand(arguments); |
} |
- Future<AdbCommandResult> runAdbCommand(List<String> adbArgs) { |
- return _executeCommand("adb", _deviceSpecificArgs(adbArgs)); |
+ Future<AdbCommandResult> runAdbCommand(List<String> adbArgs, |
+ {Duration timeout}) { |
+ return _executeCommand("adb", _deviceSpecificArgs(adbArgs), '', timeout); |
} |
- Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs) async { |
+ Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs, |
+ {Duration timeout}) async { |
const MARKER = 'AdbShellExitCode: '; |
// The exitcode of 'adb shell ...' can be 0 even though the command failed |
@@ -302,7 +321,7 @@ class AdbDevice { |
var args = ['shell', |
"${shellArgs.join(' ')} ; echo $MARKER \$?"]; |
AdbCommandResult result = await _executeCommand( |
- "adb", _deviceSpecificArgs(args)); |
+ "adb", _deviceSpecificArgs(args), '', timeout); |
int exitCode = result.exitCode; |
var lines = result |
.stdout.split('\n') |
@@ -310,11 +329,17 @@ class AdbDevice { |
.toList(); |
if (lines.length > 0) { |
int index = lines.last.indexOf(MARKER); |
- assert(index >= 0); |
- exitCode = int.parse(lines.last.substring(index + MARKER.length).trim()); |
+ if (index >= 0) { |
+ exitCode = int.parse( |
+ lines.last.substring(index + MARKER.length).trim()); |
+ } else { |
+ // In case of timeouts, for example, we won't get the exitcode marker. |
+ assert(result.exitCode != 0); |
+ } |
} |
return new AdbCommandResult( |
- result.command, result.stdout, result.stderr, exitCode); |
+ result.command, result.stdout, result.stderr, exitCode, |
+ result.timedOut); |
} |
Future<AdbCommandResult> _adbCommand(List<String> adbArgs) async { |