diff options
-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(); } } |