OSDN Git Service

Change DalvikRunner to use newly added OptionParser.
[android-x86/dalvik.git] / libcore / tools / runner / java / dalvik / runner / DalvikRunner.java
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package dalvik.runner;
18
19 import java.io.File;
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;
25 import java.util.Set;
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;
32
33 /**
34  * Command line interface for running benchmarks and tests on dalvik.
35  */
36 public final class DalvikRunner {
37
38     private static class Options {
39
40         private final List<File> testFiles = new ArrayList<File>();
41
42         @Option(names = { "--expectations" })
43         private Set<File> expectationFiles = new LinkedHashSet<File>();
44         {
45             expectationFiles.add(new File("dalvik/libcore/tools/runner/expectations.txt"));
46         }
47
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;
53
54         @Option(names = { "--timeout" })
55         private long timeoutSeconds = 10 * 60; // default is ten minutes;
56
57         @Option(names = { "--clean" })
58         private boolean clean = true;
59
60         @Option(names = { "--xml-reports-directory" })
61         private File xmlReportsDirectory;
62
63         @Option(names = { "--verbose" })
64         private boolean verbose;
65
66         @Option(names = { "--debug" })
67         private Integer debugPort;
68
69         @Option(names = { "--device-runner-dir" })
70         private File deviceRunnerDir = new File("/sdcard/dalvikrunner");
71
72         @Option(names = { "--vm-arg" })
73         private List<String> vmArgs = new ArrayList<String>();
74
75         @Option(names = { "--java-home" })
76         private File javaHome;
77
78         @Option(names = { "--sdk" })
79         private File sdkJar = new File("/home/dalvik-prebuild/android-sdk-linux/platforms/android-2.0/android.jar");
80
81         private void printUsage() {
82             System.out.println("Usage: DalvikRunner [options]... <tests>...");
83             System.out.println();
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.");
86             System.out.println();
87             System.out.println("GENERAL OPTIONS");
88             System.out.println();
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);
93             System.out.println();
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);
98             System.out.println();
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();
141         }
142
143         private boolean parseArgs(String[] args) {
144             final List<String> testFilenames;
145             try {
146                 testFilenames = new OptionParser(this).parse(args);
147             } catch (RuntimeException e) {
148                 System.out.println(e.getMessage());
149                 return false;
150             }
151
152             //
153             // Semantic error validation
154             //
155
156             boolean device;
157             boolean vm;
158             if (mode.equals(MODE_DEVICE)) {
159                 device = true;
160                 vm = true;
161             } else if (mode.equals(MODE_HOST)) {
162                 device = false;
163                 vm = true;
164             } else if (mode.equals(MODE_ACTIVITY)) {
165                 device = true;
166                 vm = false;
167             } else {
168                 System.out.println("Unknown mode: " + mode);
169                 return false;
170             }
171
172
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);
176                     return false;
177                 }
178
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);
182                     return false;
183                 }
184                 if (debugPort != null) {
185                     System.out.println("debug port " + debugPort + " should not be specified for mode " + mode);
186                     return false;
187                 }
188             }
189
190             // check vm option consistency
191             if (!vm) {
192                 if (!vmArgs.isEmpty()) {
193                     System.out.println("vm args " + vmArgs + " should not be specified for mode " + mode);
194                     return false;
195                 }
196             }
197
198             if (!sdkJar.exists()) {
199                 System.out.println("Could not find SDK jar: " + sdkJar);
200                 return false;
201             }
202
203             if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) {
204                 System.out.println("Invalid XML reports directory: " + xmlReportsDirectory);
205                 return false;
206             }
207
208             if (testFilenames.isEmpty()) {
209                 System.out.println("No tests provided.");
210                 return false;
211             }
212
213             //
214             // Post-processing arguments
215             //
216
217             for (String testFilename : testFilenames) {
218                 testFiles.add(new File(testFilename));
219             }
220
221             if (verbose) {
222                 Logger.getLogger("dalvik.runner").setLevel(Level.FINE);
223             }
224
225             return true;
226         }
227
228     }
229
230     private final Options options = new Options();
231     private final File localTemp = new File("/tmp/" + UUID.randomUUID());
232
233     private DalvikRunner() {}
234
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";
241             }
242         });
243         Logger logger = Logger.getLogger("dalvik.runner");
244         logger.addHandler(handler);
245         logger.setUseParentHandlers(false);
246     }
247
248     private void run() {
249         Vm vm;
250         if (options.mode.equals(Options.MODE_DEVICE)) {
251             vm = new DeviceDalvikVm(
252                     options.debugPort,
253                     options.timeoutSeconds,
254                     options.sdkJar,
255                     localTemp,
256                     options.vmArgs,
257                     options.clean,
258                     options.deviceRunnerDir);
259         } else if (options.mode.equals(Options.MODE_HOST)) {
260             vm = new JavaVm(
261                     options.debugPort,
262                     options.timeoutSeconds,
263                     options.sdkJar,
264                     localTemp,
265                     options.javaHome,
266                     options.vmArgs,
267                     options.clean);
268         } else if (options.mode.equals(Options.MODE_ACTIVITY)) {
269             vm = null;
270             System.out.println("Mode " + options.mode + " not currently supported.");
271             return;
272         } else {
273             System.out.println("Unknown mode mode " + options.mode + ".");
274             return;
275         }
276
277         List<CodeFinder> codeFinders = Arrays.asList(
278                 new JtregFinder(localTemp),
279                 new JUnitFinder(),
280                 new CaliperFinder(),
281                 new MainFinder());
282         Driver driver = new Driver(
283                 localTemp,
284                 vm,
285                 options.expectationFiles,
286                 options.xmlReportsDirectory,
287                 codeFinders);
288         try {
289             driver.loadExpectations();
290         } catch (IOException e) {
291             System.out.println("Problem loading expectations: " + e);
292             return;
293         }
294
295         driver.buildAndRunAllTests(options.testFiles);
296         vm.shutdown();
297     }
298
299     public static void main(String[] args) {
300         DalvikRunner dalvikRunner = new DalvikRunner();
301         if (!dalvikRunner.options.parseArgs(args)) {
302             dalvikRunner.options.printUsage();
303             return;
304         }
305         dalvikRunner.prepareLogging();
306         dalvikRunner.run();
307     }
308 }