diff options
author | Brian Carlstrom <bdc@google.com> | 2010-02-28 01:39:10 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-02-28 01:39:10 -0800 |
commit | d7b9bef3430ed3c84bc5f5c68ffa7e1a55941f86 (patch) | |
tree | ff1bc46551b18da633ac0e675c21e0dbceaff1ee /tools | |
parent | 2b59f638601abd5f1b3c2a40968bb040abe584d9 (diff) | |
parent | 6f78e81857bffbf6b749f25e55e7be77c4995f56 (diff) | |
download | libcore-d7b9bef3430ed3c84bc5f5c68ffa7e1a55941f86.zip libcore-d7b9bef3430ed3c84bc5f5c68ffa7e1a55941f86.tar.gz libcore-d7b9bef3430ed3c84bc5f5c68ffa7e1a55941f86.tar.bz2 |
am d1ad6ae8: DalvikRunner --tee option to send output to a file or stdout at runtime
Merge commit 'd1ad6ae8509d5890a7175a1dcd0a3f7fceb75d23' into dalvik-dev
* commit 'd1ad6ae8509d5890a7175a1dcd0a3f7fceb75d23':
DalvikRunner --tee option to send output to a file or stdout at runtime
Diffstat (limited to 'tools')
-rw-r--r-- | tools/runner/java/dalvik/runner/ActivityMode.java | 62 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Adb.java | 26 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Command.java | 13 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/DalvikRunner.java | 27 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/DeviceDalvikVm.java | 5 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/JavaVm.java | 7 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Mode.java | 34 | ||||
-rw-r--r-- | tools/runner/java/dalvik/runner/Vm.java | 23 |
8 files changed, 132 insertions, 65 deletions
diff --git a/tools/runner/java/dalvik/runner/ActivityMode.java b/tools/runner/java/dalvik/runner/ActivityMode.java index b2b4a3b..163c72a 100644 --- a/tools/runner/java/dalvik/runner/ActivityMode.java +++ b/tools/runner/java/dalvik/runner/ActivityMode.java @@ -19,10 +19,12 @@ package dalvik.runner; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Set; +import java.util.concurrent.TimeoutException; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; @@ -36,11 +38,11 @@ final class ActivityMode extends Mode { private static final String TEST_ACTIVITY_CLASS = "dalvik.runner.TestActivity"; - ActivityMode(Integer debugPort, long timeoutSeconds, File sdkJar, File localTemp, + ActivityMode(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee, File localTemp, boolean cleanBefore, boolean cleanAfter, File deviceRunnerDir) { super(new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, localTemp, deviceRunnerDir), - timeoutSeconds, sdkJar); + timeoutSeconds, sdkJar, tee); } private EnvironmentDevice getEnvironmentDevice() { @@ -148,11 +150,21 @@ final class ActivityMode extends Mode { return dex; } + /** + * According to android.content.pm.PackageParser, package name + * "must have at least one '.' separator" Since the qualified name + * may not contain a dot, we prefix containing one to ensure we + * are compliant. + */ + private static String packageName(TestRun testRun) { + return "DalvikRunner." + testRun.getQualifiedName(); + } + private File createApk (TestRun testRun, File dex) { String androidManifest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + - " package=\"" + testRun.getQualifiedName() + "\">\n" + + " package=\"" + packageName(testRun) + "\">\n" + " <uses-permission android:name=\"android.permission.INTERNET\" />\n" + " <application>\n" + " <activity android:name=\"" + TEST_ACTIVITY_CLASS + "\">\n" + @@ -202,7 +214,7 @@ final class ActivityMode extends Mode { private void installApk(TestRun testRun, File apkSigned) { // install the local apk ona the device - getEnvironmentDevice().adb.uninstall(testRun.getQualifiedName()); + getEnvironmentDevice().adb.uninstall(packageName(testRun)); getEnvironmentDevice().adb.install(apkSigned); } @@ -211,40 +223,20 @@ final class ActivityMode extends Mode { properties.setProperty(TestProperties.DEVICE_RUNNER_DIR, getEnvironmentDevice().runnerDir.getPath()); } - @Override protected List<Command> buildCommands(TestRun testRun) { - List<Command> commands = new ArrayList<Command>(); - commands.add(new Command.Builder() - .args("adb") - .args("shell") - .args("am") - .args("start") - .args("-a") - .args("android.intent.action.MAIN") - .args("-n") - .args(testRun.getQualifiedName() + "/" + TEST_ACTIVITY_CLASS).build()); + @Override protected List<String> runTestCommand(TestRun testRun) + throws TimeoutException { + new Command( + "adb", "shell", "am", "start", + "-a","android.intent.action.MAIN", + "-n", (packageName(testRun) + "/" + TEST_ACTIVITY_CLASS)).executeWithTimeout(timeoutSeconds); File resultDir = new File(getEnvironmentDevice().runnerDir, testRun.getQualifiedName()); File resultFile = new File(resultDir, TestProperties.RESULT_FILE); - /* - * The follow bash script waits for the result file to - * exist. It polls once a second to see if it is there with - * "adb shell ls". The "tr" is to remove the carriage return - * and newline from the adb output. When it does exist, we - * "adb shell cat" it so we can see the SUCCESS/FAILURE - * results that are expected by Mode.runTest. - */ - // TODO: move loop to Java - commands.add(new Command.Builder() - .args("bash") - .args("-c") - .args( - "while [ ! \"`adb shell ls " + resultFile + " | tr -d '\\r\\n'`\" = " + - " \"" + resultFile + "\" ] ; do " + - " sleep 1; " + - "done; " + - "adb shell cat " + resultFile).build()); - - return commands; + getEnvironmentDevice().adb.waitForFile(resultFile, timeoutSeconds); + return new Command.Builder() + .args("adb", "shell", "cat", resultFile.getPath()) + .tee(tee) + .build().executeWithTimeout(timeoutSeconds); } @Override void cleanup(TestRun testRun) { diff --git a/tools/runner/java/dalvik/runner/Adb.java b/tools/runner/java/dalvik/runner/Adb.java index 075ca5f..0ab14ec 100644 --- a/tools/runner/java/dalvik/runner/Adb.java +++ b/tools/runner/java/dalvik/runner/Adb.java @@ -58,10 +58,22 @@ final class Adb { } /** + * Loop until we see a file on the device. For example, wait + * result.txt appears. + */ + public void waitForFile(File file, long timeoutSeconds) { + waitFor(true, file, timeoutSeconds); + } + + /** * 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) { + public void waitForNonEmptyDirectory(File path, long timeoutSeconds) { + waitFor(false, path, timeoutSeconds); + } + + private void waitFor(boolean file, File path, long timeoutSeconds) { final int millisPerSecond = 1000; final long start = System.currentTimeMillis(); final long deadline = start + (millisPerSecond * timeoutSeconds); @@ -82,8 +94,16 @@ final class Adb { } catch (InterruptedException e) { throw new RuntimeException(e); } - if (!output.isEmpty()) { - return; + if (file) { + // for files, we expect one line of output that matches the filename + if (output.size() == 1 && output.get(0).equals(path.getPath())) { + return; + } + } else { + // for a non empty directory, we just want any output + if (!output.isEmpty()) { + return; + } } } } diff --git a/tools/runner/java/dalvik/runner/Command.java b/tools/runner/java/dalvik/runner/Command.java index 4319cf9..88ba38e 100644 --- a/tools/runner/java/dalvik/runner/Command.java +++ b/tools/runner/java/dalvik/runner/Command.java @@ -20,6 +20,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -44,6 +45,7 @@ final class Command { private final List<String> args; private final File workingDirectory; private final boolean permitNonZeroExitStatus; + private final PrintStream tee; private Process process; Command(String... args) { @@ -54,12 +56,14 @@ final class Command { this.args = new ArrayList<String>(args); this.workingDirectory = null; this.permitNonZeroExitStatus = false; + this.tee = null; } private Command(Builder builder) { this.args = new ArrayList<String>(builder.args); this.workingDirectory = builder.workingDirectory; this.permitNonZeroExitStatus = builder.permitNonZeroExitStatus; + this.tee = builder.tee; } public List<String> getArgs() { @@ -106,6 +110,9 @@ final class Command { List<String> outputLines = new ArrayList<String>(); String outputLine; while ((outputLine = in.readLine()) != null) { + if (tee != null) { + tee.println(outputLine); + } outputLines.add(outputLine); } @@ -167,6 +174,7 @@ final class Command { private final List<String> args = new ArrayList<String>(); private File workingDirectory; private boolean permitNonZeroExitStatus = false; + private PrintStream tee = null; public Builder args(Object... objects) { for (Object object : objects) { @@ -200,6 +208,11 @@ final class Command { return this; } + public Builder tee(PrintStream printStream) { + tee = printStream; + return this; + } + public Command build() { return new Command(this); } diff --git a/tools/runner/java/dalvik/runner/DalvikRunner.java b/tools/runner/java/dalvik/runner/DalvikRunner.java index 015fb9a..c78866e 100644 --- a/tools/runner/java/dalvik/runner/DalvikRunner.java +++ b/tools/runner/java/dalvik/runner/DalvikRunner.java @@ -16,8 +16,12 @@ package dalvik.runner; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; @@ -72,6 +76,10 @@ public final class DalvikRunner { @Option(names = { "--verbose" }) private boolean verbose; + @Option(names = { "--tee" }) + private String teeName; + private PrintStream tee; + @Option(names = { "--debug" }) private Integer debugPort; @@ -116,6 +124,9 @@ public final class DalvikRunner { System.out.println(" --clean: synonym for --clean-before and --clean-after (default)."); System.out.println(" Disable with --no-clean if you want no files removed."); System.out.println(); + System.out.println(" --tee <file>: emit test output to file during execution."); + System.out.println(" Specify '-' for stdout."); + System.out.println(); System.out.println(" --timeout-seconds <seconds>: maximum execution time of each"); System.out.println(" test before the runner aborts it."); System.out.println(" Default is: " + timeoutSeconds); @@ -235,6 +246,19 @@ public final class DalvikRunner { testFiles.add(new File(testFilename)); } + if (teeName != null) { + if (teeName.equals("-")) { + tee = System.out; + } else { + try { + tee = new PrintStream(new BufferedOutputStream(new FileOutputStream(teeName))); + } catch (FileNotFoundException e) { + System.out.println("Could not open file teeName: " + e); + return false; + } + } + } + if (verbose) { Logger.getLogger("dalvik.runner").setLevel(Level.FINE); } @@ -269,6 +293,7 @@ public final class DalvikRunner { options.debugPort, options.timeoutSeconds, options.sdkJar, + options.tee, localTemp, options.vmArgs, options.cleanBefore, @@ -279,6 +304,7 @@ public final class DalvikRunner { options.debugPort, options.timeoutSeconds, options.sdkJar, + options.tee, localTemp, options.javaHome, options.vmArgs, @@ -289,6 +315,7 @@ public final class DalvikRunner { options.debugPort, options.timeoutSeconds, options.sdkJar, + options.tee, localTemp, options.cleanBefore, options.cleanAfter, diff --git a/tools/runner/java/dalvik/runner/DeviceDalvikVm.java b/tools/runner/java/dalvik/runner/DeviceDalvikVm.java index 7bdf482..061e374 100644 --- a/tools/runner/java/dalvik/runner/DeviceDalvikVm.java +++ b/tools/runner/java/dalvik/runner/DeviceDalvikVm.java @@ -17,6 +17,7 @@ package dalvik.runner; import java.io.File; +import java.io.PrintStream; import java.util.List; import java.util.logging.Logger; @@ -26,11 +27,11 @@ import java.util.logging.Logger; final class DeviceDalvikVm extends Vm { private static final Logger logger = Logger.getLogger(DeviceDalvikVm.class.getName()); - DeviceDalvikVm(Integer debugPort, long timeoutSeconds, File sdkJar, + DeviceDalvikVm(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee, File localTemp, List<String> additionalVmArgs, boolean cleanBefore, boolean cleanAfter, File runnerDir) { super(new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, localTemp, runnerDir), - timeoutSeconds, sdkJar, additionalVmArgs); + timeoutSeconds, sdkJar, tee, additionalVmArgs); } private EnvironmentDevice getEnvironmentDevice() { diff --git a/tools/runner/java/dalvik/runner/JavaVm.java b/tools/runner/java/dalvik/runner/JavaVm.java index 2dfc3e7..38e0386 100644 --- a/tools/runner/java/dalvik/runner/JavaVm.java +++ b/tools/runner/java/dalvik/runner/JavaVm.java @@ -17,6 +17,7 @@ package dalvik.runner; import java.io.File; +import java.io.PrintStream; import java.util.List; import java.util.Set; @@ -27,11 +28,11 @@ final class JavaVm extends Vm { private final File javaHome; - JavaVm(Integer debugPort, long timeoutSeconds, File sdkJar, File localTemp, - File javaHome, List<String> additionalVmArgs, + JavaVm(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee, + File localTemp, File javaHome, List<String> additionalVmArgs, boolean cleanBefore, boolean cleanAfter) { super(new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp), - timeoutSeconds, sdkJar, additionalVmArgs); + timeoutSeconds, sdkJar, tee, additionalVmArgs); this.javaHome = javaHome; } diff --git a/tools/runner/java/dalvik/runner/Mode.java b/tools/runner/java/dalvik/runner/Mode.java index 3ffd88f..3b69cb2 100644 --- a/tools/runner/java/dalvik/runner/Mode.java +++ b/tools/runner/java/dalvik/runner/Mode.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; +import java.io.PrintStream; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -44,6 +45,7 @@ abstract class Mode { protected final Environment environment; protected final long timeoutSeconds; protected final File sdkJar; + protected final PrintStream tee; /** * Set of Java files needed to built to tun the currently selected @@ -72,10 +74,11 @@ abstract class Mode { // TODO: jar up just the junit classes and drop the jar in our lib/ directory. new File("out/target/common/obj/JAVA_LIBRARIES/core-tests-luni_intermediates/classes.jar").getAbsoluteFile()); - Mode(Environment environment, long timeoutSeconds, File sdkJar) { + Mode(Environment environment, long timeoutSeconds, File sdkJar, PrintStream tee) { this.environment = environment; this.timeoutSeconds = timeoutSeconds; this.sdkJar = sdkJar; + this.tee = tee; } /** @@ -218,20 +221,16 @@ abstract class Mode { throw new IllegalArgumentException(); } - final List<Command> commands = buildCommands(testRun); - - List<String> output = null; - for (final Command command : commands) { - try { - output = command.executeWithTimeout(timeoutSeconds); - } catch (TimeoutException e) { - testRun.setResult(Result.EXEC_TIMEOUT, - Collections.singletonList("Exceeded timeout! (" + timeoutSeconds + "s)")); - return; - } catch (Exception e) { - testRun.setResult(Result.ERROR, e); - return; - } + List<String> output; + try { + output = runTestCommand(testRun); + } catch (TimeoutException e) { + testRun.setResult(Result.EXEC_TIMEOUT, + Collections.singletonList("Exceeded timeout! (" + timeoutSeconds + "s)")); + return; + } catch (Exception e) { + testRun.setResult(Result.ERROR, e); + return; } // we only look at the output of the last command if (output.isEmpty()) { @@ -247,9 +246,10 @@ abstract class Mode { } /** - * Returns commands for test execution. + * Run the actual test to gather output */ - protected abstract List<Command> buildCommands(TestRun testRun); + protected abstract List<String> runTestCommand(TestRun testRun) + throws TimeoutException; /** * Deletes files and releases any resources required for the execution of diff --git a/tools/runner/java/dalvik/runner/Vm.java b/tools/runner/java/dalvik/runner/Vm.java index 9f96ec5..8ff5858 100644 --- a/tools/runner/java/dalvik/runner/Vm.java +++ b/tools/runner/java/dalvik/runner/Vm.java @@ -19,6 +19,7 @@ package dalvik.runner; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -27,6 +28,7 @@ import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; +import java.util.concurrent.TimeoutException; import java.util.logging.Logger; /** @@ -39,22 +41,25 @@ public abstract class Vm extends Mode { protected final List<String> additionalVmArgs; Vm(Environment environment, long timeoutSeconds, File sdkJar, - List<String> additionalVmArgs) { - super(environment, timeoutSeconds, sdkJar); + PrintStream tee, List<String> additionalVmArgs) { + super(environment, timeoutSeconds, sdkJar, tee); this.additionalVmArgs = additionalVmArgs; } /** * Returns a VM for test execution. */ - @Override protected List<Command> buildCommands(TestRun testRun) { - return Collections.singletonList(newVmCommandBuilder(testRun.getUserDir()) + @Override protected List<String> runTestCommand(TestRun testRun) + throws TimeoutException { + Command command = newVmCommandBuilder(testRun.getUserDir()) .classpath(getRuntimeSupportClasspath(testRun)) .userDir(testRun.getUserDir()) .debugPort(environment.debugPort) .vmArgs(additionalVmArgs) .mainClass(TestRunner.class.getName()) - .build()); + .output(tee) + .build(); + return command.executeWithTimeout(timeoutSeconds); } /** @@ -78,6 +83,7 @@ public abstract class Vm extends Mode { private File userDir; private Integer debugPort; private String mainClass; + private PrintStream output; private List<String> vmCommand = Collections.singletonList("java"); private List<String> vmArgs = new ArrayList<String>(); @@ -116,6 +122,11 @@ public abstract class Vm extends Mode { return this; } + public VmCommandBuilder output(PrintStream output) { + this.output = output; + return this; + } + public VmCommandBuilder vmArgs(String... vmArgs) { return vmArgs(Arrays.asList(vmArgs)); } @@ -146,6 +157,8 @@ public abstract class Vm extends Mode { builder.args(vmArgs); builder.args(mainClass); + builder.tee(output); + return builder.build(); } } |