summaryrefslogtreecommitdiffstats
path: root/tools/runner
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2010-02-10 23:07:32 -0800
committerBrian Carlstrom <bdc@google.com>2010-02-11 11:15:32 -0800
commita6bb78929856bd4c735ba055c2cea3261030b82b (patch)
tree9253304636ee3c2b16de41ab7af88feeb7d9622b /tools/runner
parent08384bd645204fc886238c600ef690468d5b8f5f (diff)
downloadlibcore-a6bb78929856bd4c735ba055c2cea3261030b82b.zip
libcore-a6bb78929856bd4c735ba055c2cea3261030b82b.tar.gz
libcore-a6bb78929856bd4c735ba055c2cea3261030b82b.tar.bz2
Make DalvikRunner more resilient to running immediately after device reboot
Changed EnvironmentDevice.prepare to waitForDevice and waitForNonEmptyDirectory("/sdcard") before proceeding to fix problem with running immediately after "fastboot flashall" dalvik/libcore/tools/runner/java/dalvik/runner/EnvironmentDevice.java Added Adb.waitForDevice and Adb.waitForNonEmptyDirectory dalvik/libcore/tools/runner/java/dalvik/runner/Adb.java Added Command.executeWithTimeout based on code refactored from Mode.java dalvik/libcore/tools/runner/java/dalvik/runner/Command.java dalvik/libcore/tools/runner/java/dalvik/runner/Mode.java
Diffstat (limited to 'tools/runner')
-rw-r--r--tools/runner/java/dalvik/runner/Adb.java37
-rw-r--r--tools/runner/java/dalvik/runner/Command.java39
-rw-r--r--tools/runner/java/dalvik/runner/EnvironmentDevice.java2
-rw-r--r--tools/runner/java/dalvik/runner/Mode.java21
4 files changed, 79 insertions, 20 deletions
diff --git a/tools/runner/java/dalvik/runner/Adb.java b/tools/runner/java/dalvik/runner/Adb.java
index 7c1ed64..075ca5f 100644
--- a/tools/runner/java/dalvik/runner/Adb.java
+++ b/tools/runner/java/dalvik/runner/Adb.java
@@ -17,6 +17,8 @@
package dalvik.runner;
import java.io.File;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
/**
* An adb command.
@@ -50,4 +52,39 @@ final class Adb {
new Command("adb", "forward", "tcp:" + localPort, "tcp:" + devicePort)
.execute();
}
+
+ public void waitForDevice() {
+ new Command("adb", "wait-for-device").execute();
+ }
+
+ /**
+ * Loop until we see a non-empty directory on the device. For
+ * example, wait until /sdcard is mounted.
+ */
+ public void waitForNonEmptyDirectory(File path, int timeoutSeconds) {
+ final int millisPerSecond = 1000;
+ final long start = System.currentTimeMillis();
+ final long deadline = start + (millisPerSecond * timeoutSeconds);
+
+ while (true) {
+ final long remainingSeconds = ((deadline - System.currentTimeMillis())
+ / millisPerSecond);
+ Command command = new Command("adb", "shell", "ls", path.getPath());
+ List<String> output;
+ try {
+ output = command.executeWithTimeout(remainingSeconds);
+ } catch (TimeoutException e) {
+ throw new RuntimeException("Timed out after " + timeoutSeconds +
+ " seconds waiting for file " + path, e);
+ }
+ try {
+ Thread.sleep(millisPerSecond);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ if (!output.isEmpty()) {
+ return;
+ }
+ }
+ }
}
diff --git a/tools/runner/java/dalvik/runner/Command.java b/tools/runner/java/dalvik/runner/Command.java
index 9af02a2..4319cf9 100644
--- a/tools/runner/java/dalvik/runner/Command.java
+++ b/tools/runner/java/dalvik/runner/Command.java
@@ -25,6 +25,13 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
/**
@@ -124,6 +131,38 @@ final class Command {
}
}
+ /**
+ * Executes a command with a specified timeout. Output is returned
+ * if the command succeeds. If Otherwise null is returned if the
+ * command timed out.
+ */
+ public List<String> executeWithTimeout(long timeoutSeconds)
+ throws TimeoutException {
+ ExecutorService outputReader
+ = Executors.newFixedThreadPool(1, Threads.daemonThreadFactory());
+ try {
+ start();
+ // run on a different thread to allow a timeout
+ Future<List<String>> future = outputReader.submit(new Callable<List<String>>() {
+ public List<String> call() throws Exception {
+ return gatherOutput();
+ }
+ });
+ return future.get(timeoutSeconds, TimeUnit.SECONDS);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to execute process: " + args, e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while executing process: " + args, e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (isStarted()) {
+ getProcess().destroy(); // to release the output reader
+ }
+ outputReader.shutdown();
+ }
+ }
+
static class Builder {
private final List<String> args = new ArrayList<String>();
private File workingDirectory;
diff --git a/tools/runner/java/dalvik/runner/EnvironmentDevice.java b/tools/runner/java/dalvik/runner/EnvironmentDevice.java
index 90b2889..c44152d 100644
--- a/tools/runner/java/dalvik/runner/EnvironmentDevice.java
+++ b/tools/runner/java/dalvik/runner/EnvironmentDevice.java
@@ -34,6 +34,8 @@ class EnvironmentDevice extends Environment {
}
@Override void prepare() {
+ adb.waitForDevice();
+ adb.waitForNonEmptyDirectory(runnerDir.getParentFile(), 5 * 60);
if (cleanBefore) {
adb.rm(runnerDir);
}
diff --git a/tools/runner/java/dalvik/runner/Mode.java b/tools/runner/java/dalvik/runner/Mode.java
index 0f0163f..c30e023 100644
--- a/tools/runner/java/dalvik/runner/Mode.java
+++ b/tools/runner/java/dalvik/runner/Mode.java
@@ -25,10 +25,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import java.util.regex.Pattern;
@@ -73,9 +69,6 @@ abstract class Mode {
new File("out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar").getAbsoluteFile());
- protected final ExecutorService outputReaders
- = Executors.newFixedThreadPool(1, Threads.daemonThreadFactory());
-
Mode(Environment environment, long timeoutSeconds, File sdkJar) {
this.environment = environment;
this.timeoutSeconds = timeoutSeconds;
@@ -206,14 +199,7 @@ abstract class Mode {
List<String> output = null;
for (final Command command : commands) {
try {
- command.start();
-
- // run on a different thread to allow a timeout
- output = outputReaders.submit(new Callable<List<String>>() {
- public List<String> call() throws Exception {
- return command.gatherOutput();
- }
- }).get(timeoutSeconds, TimeUnit.SECONDS);
+ output = command.executeWithTimeout(timeoutSeconds);
} catch (TimeoutException e) {
testRun.setResult(Result.EXEC_TIMEOUT,
Collections.singletonList("Exceeded timeout! (" + timeoutSeconds + "s)"));
@@ -221,10 +207,6 @@ abstract class Mode {
} catch (Exception e) {
testRun.setResult(Result.ERROR, e);
return;
- } finally {
- if (command.isStarted()) {
- command.getProcess().destroy(); // to release the output reader
- }
}
}
// we only look at the output of the last command
@@ -257,7 +239,6 @@ abstract class Mode {
* Cleans up after all test runs have completed.
*/
void shutdown() {
- outputReaders.shutdown();
environment.shutdown();
}
}