diff options
author | Brian Carlstrom <bdc@google.com> | 2010-02-10 23:07:32 -0800 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2010-02-11 11:15:32 -0800 |
commit | a6bb78929856bd4c735ba055c2cea3261030b82b (patch) | |
tree | 9253304636ee3c2b16de41ab7af88feeb7d9622b /tools/runner | |
parent | 08384bd645204fc886238c600ef690468d5b8f5f (diff) | |
download | libcore-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.java | 37 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Command.java | 39 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/EnvironmentDevice.java | 2 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Mode.java | 21 |
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(); } } |