2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package dalvik.runner;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.LinkedHashSet;
24 import java.util.List;
26 import java.util.UUID;
27 import java.util.logging.ConsoleHandler;
28 import java.util.logging.Formatter;
29 import java.util.logging.Level;
30 import java.util.logging.LogRecord;
31 import java.util.logging.Logger;
34 * Command line interface for running benchmarks and tests on dalvik.
36 public final class DalvikRunner {
38 private static class Options {
40 private final List<File> testFiles = new ArrayList<File>();
42 @Option(names = { "--expectations" })
43 private Set<File> expectationFiles = new LinkedHashSet<File>();
45 expectationFiles.add(new File("dalvik/libcore/tools/runner/expectations.txt"));
48 private static String MODE_DEVICE = "device";
49 private static String MODE_HOST = "host";
50 private static String MODE_ACTIVITY = "activity";
51 @Option(names = { "--mode" })
52 private String mode = MODE_DEVICE;
54 @Option(names = { "--timeout" })
55 private long timeoutSeconds = 10 * 60; // default is ten minutes;
57 @Option(names = { "--clean" })
58 private boolean clean = true;
60 @Option(names = { "--xml-reports-directory" })
61 private File xmlReportsDirectory;
63 @Option(names = { "--verbose" })
64 private boolean verbose;
66 @Option(names = { "--debug" })
67 private Integer debugPort;
69 @Option(names = { "--device-runner-dir" })
70 private File deviceRunnerDir = new File("/sdcard/dalvikrunner");
72 @Option(names = { "--vm-arg" })
73 private List<String> vmArgs = new ArrayList<String>();
75 @Option(names = { "--java-home" })
76 private File javaHome;
78 @Option(names = { "--sdk" })
79 private File sdkJar = new File("/home/dalvik-prebuild/android-sdk-linux/platforms/android-2.0/android.jar");
81 private void printUsage() {
82 System.out.println("Usage: DalvikRunner [options]... <tests>...");
84 System.out.println(" <tests>: a .java file containing a jtreg test, JUnit test,");
85 System.out.println(" Caliper benchmark, or a directory of such tests.");
87 System.out.println("GENERAL OPTIONS");
89 System.out.println(" --expectations <file>: include the specified file when looking for");
90 System.out.println(" test expectations. The file should include qualified test names");
91 System.out.println(" and the corresponding expected output.");
92 System.out.println(" Default is: " + expectationFiles);
94 System.out.println(" --mode <device|host|activity>: specify which environment to run the");
95 System.out.println(" tests in. Options are on the device VM, on the host VM, and on");
96 System.out.println(" device within an android.app.Activity.");
97 System.out.println(" Default is: " + mode);
99 System.out.println(" --clean: remove temporary files (default). Disable with --no-clean");
100 System.out.println(" and use with --verbose if you'd like to manually re-run");
101 System.out.println(" commands afterwards.");
102 System.out.println();
103 System.out.println(" --timeout-seconds <seconds>: maximum execution time of each");
104 System.out.println(" test before the runner aborts it.");
105 System.out.println(" Default is: " + timeoutSeconds);
106 System.out.println();
107 System.out.println(" --xml-reports-directory <path>: directory to emit JUnit-style");
108 System.out.println(" XML test results.");
109 System.out.println();
110 System.out.println(" --verbose: turn on verbose output");
111 System.out.println();
112 System.out.println("DEVICE OPTIONS");
113 System.out.println();
114 System.out.println(" --debug <port>: enable Java debugging on the specified port.");
115 System.out.println(" This port must be free both on the device and on the local");
116 System.out.println(" system.");
117 System.out.println();
118 System.out.println(" --device-runner-dir <directory>: use the specified directory for");
119 System.out.println(" on-device temporary files and code.");
120 System.out.println(" Default is: " + deviceRunnerDir);
121 System.out.println();
122 System.out.println("GENERAL VM OPTIONS");
123 System.out.println();
124 System.out.println(" --vm-arg <argument>: include the specified argument when spawning a");
125 System.out.println(" virtual machine. Examples: -Xint:fast, -ea, -Xmx16M");
126 System.out.println();
127 System.out.println("HOST VM OPTIONS");
128 System.out.println();
129 System.out.println(" --java-home <java_home>: execute the tests on the local workstation");
130 System.out.println(" using the specified java home directory. This does not impact");
131 System.out.println(" which javac gets used. When unset, java is used from the PATH.");
132 System.out.println();
133 System.out.println("COMPILE OPTIONS");
134 System.out.println();
135 System.out.println(" --sdk <android jar>: the API jar file to compile against.");
136 System.out.println(" Usually this is <SDK>/platforms/android-<X.X>/android.jar");
137 System.out.println(" where <SDK> is the path to an Android SDK path and <X.X> is");
138 System.out.println(" a release version like 1.5.");
139 System.out.println(" Default is: " + sdkJar);
140 System.out.println();
143 private boolean parseArgs(String[] args) {
144 final List<String> testFilenames;
146 testFilenames = new OptionParser(this).parse(args);
147 } catch (RuntimeException e) {
148 System.out.println(e.getMessage());
153 // Semantic error validation
158 if (mode.equals(MODE_DEVICE)) {
161 } else if (mode.equals(MODE_HOST)) {
164 } else if (mode.equals(MODE_ACTIVITY)) {
168 System.out.println("Unknown mode: " + mode);
173 if (device) { // check device option consistency
174 if (javaHome != null) {
175 System.out.println("java home " + javaHome + " should not be specified for mode " + mode);
179 } else { // check host (!device) option consistency
180 if (javaHome != null && !new File(javaHome, "/bin/java").exists()) {
181 System.out.println("Invalid java home: " + javaHome);
184 if (debugPort != null) {
185 System.out.println("debug port " + debugPort + " should not be specified for mode " + mode);
190 // check vm option consistency
192 if (!vmArgs.isEmpty()) {
193 System.out.println("vm args " + vmArgs + " should not be specified for mode " + mode);
198 if (!sdkJar.exists()) {
199 System.out.println("Could not find SDK jar: " + sdkJar);
203 if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) {
204 System.out.println("Invalid XML reports directory: " + xmlReportsDirectory);
208 if (testFilenames.isEmpty()) {
209 System.out.println("No tests provided.");
214 // Post-processing arguments
217 for (String testFilename : testFilenames) {
218 testFiles.add(new File(testFilename));
222 Logger.getLogger("dalvik.runner").setLevel(Level.FINE);
230 private final Options options = new Options();
231 private final File localTemp = new File("/tmp/" + UUID.randomUUID());
233 private DalvikRunner() {}
235 private void prepareLogging() {
236 ConsoleHandler handler = new ConsoleHandler();
237 handler.setLevel(Level.ALL);
238 handler.setFormatter(new Formatter() {
239 @Override public String format(LogRecord r) {
240 return r.getMessage() + "\n";
243 Logger logger = Logger.getLogger("dalvik.runner");
244 logger.addHandler(handler);
245 logger.setUseParentHandlers(false);
250 if (options.mode.equals(Options.MODE_DEVICE)) {
251 vm = new DeviceDalvikVm(
253 options.timeoutSeconds,
258 options.deviceRunnerDir);
259 } else if (options.mode.equals(Options.MODE_HOST)) {
262 options.timeoutSeconds,
268 } else if (options.mode.equals(Options.MODE_ACTIVITY)) {
270 System.out.println("Mode " + options.mode + " not currently supported.");
273 System.out.println("Unknown mode mode " + options.mode + ".");
277 List<CodeFinder> codeFinders = Arrays.asList(
278 new JtregFinder(localTemp),
282 Driver driver = new Driver(
285 options.expectationFiles,
286 options.xmlReportsDirectory,
289 driver.loadExpectations();
290 } catch (IOException e) {
291 System.out.println("Problem loading expectations: " + e);
295 driver.buildAndRunAllTests(options.testFiles);
299 public static void main(String[] args) {
300 DalvikRunner dalvikRunner = new DalvikRunner();
301 if (!dalvikRunner.options.parseArgs(args)) {
302 dalvikRunner.options.printUsage();
305 dalvikRunner.prepareLogging();