Vogar.java revision d0944e3ecda89a97ac35537e280b2776b53c25ec
17850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/* 27850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Copyright (C) 2009 The Android Open Source Project 37850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 47850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Licensed under the Apache License, Version 2.0 (the "License"); 57850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * you may not use this file except in compliance with the License. 67850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * You may obtain a copy of the License at 77850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 87850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * http://www.apache.org/licenses/LICENSE-2.0 97850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 107850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Unless required by applicable law or agreed to in writing, software 117850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * distributed under the License is distributed on an "AS IS" BASIS, 127850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * See the License for the specific language governing permissions and 147850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * limitations under the License. 157850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */ 167850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 177850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.compackage vogar; 187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 197850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.File; 207850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.IOException; 217850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.ArrayList; 227850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.Arrays; 237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.LinkedHashSet; 247850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.List; 257850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.Set; 267850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.UUID; 27e956c912fdab19b9cc806b47288048fca9121546jessewilson@google.comimport vogar.commands.AndroidSdk; 287850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 297850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/** 307850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Command line interface for running benchmarks and tests on dalvik. 317850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */ 327850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.compublic final class Vogar { 337850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 34d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<File> actionFiles = new ArrayList<File>(); 35d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<String> actionClassesAndPackages = new ArrayList<String>(); 36d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<String> targetArgs = new ArrayList<String>(); 37d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 38d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--expectations" }) 39d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Set<File> expectationFiles = new LinkedHashSet<File>(); 40d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com { 41d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com File[] files = new File("expectations").listFiles(); 42d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (files != null) { 43d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com expectationFiles.addAll(Arrays.asList(files)); 447850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 45d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 467850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 47d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--mode" }) 48d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private ModeId mode = ModeId.DEVICE; 497850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 50d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--timeout" }) 51d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private long timeoutSeconds = 10 * 60; // default is ten minutes; 527850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 53d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--monitor-timeout" }) 54d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private long monitorTimeout = 30; 557850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 56d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean-before" }) 57d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean cleanBefore = true; 587850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 59d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean-after" }) 60d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean cleanAfter = true; 617850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 62d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean" }) 63d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean clean = true; 647850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 65d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--xml-reports-directory" }) 66d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private File xmlReportsDirectory; 677850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 68d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--indent" }) 69d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private String indent = " "; 707850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 71d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--verbose" }) 72d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean verbose; 737850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 74d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--stream" }) 75d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean stream = true; 767850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 77d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--color" }) 78d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean color = true; 797850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 80d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--debug" }) 81d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Integer debugPort; 82d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 83d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--device-runner-dir" }) 84d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private File deviceRunnerDir = new File("/sdcard/dalvikrunner"); 85d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 86d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--vm-arg" }) 87d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<String> vmArgs = new ArrayList<String>(); 88d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 89d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--java-home" }) 90d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private File javaHome; 91d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 92d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--javac-arg" }) 93d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<String> javacArgs = new ArrayList<String>(); 94d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 95d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--use-boot-classpath" }) 96d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean useBootClasspath = false; 97d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 98d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--build-classpath" }) 99d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> buildClasspath = new ArrayList<File>(); 100d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 101d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--classpath", "-cp" }) 102d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> classpath = new ArrayList<File>(); 103d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 104d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--sourcepath" }) 105d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> sourcepath = new ArrayList<File>(); 106d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 107d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Vogar() {} 108d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 109d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private void printUsage() { 110d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Usage: Vogar [options]... <actions>... [-- target args]..."); 111d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 112d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" <actions>: .java files, directories, or class names."); 113d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" These should be JUnit tests, jtreg tests, Caliper benchmarks"); 114d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" or executable Java classes."); 115d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 116d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" [args]: arguments passed to the target process. This is only useful when"); 117d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" the target process is a Caliper benchmark or main method."); 118d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 119d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("GENERAL OPTIONS"); 120d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 121d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --mode <activity|device|sim|host>: specify which environment to run in."); 122d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" activity: runs in an Android application on a device or emulator"); 123d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" device: runs in a Dalvik VM on a device or emulator"); 124d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" sim: runs in a Dalvik VM on the local desktop."); 125d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" host: runs in a Java VM on the local desktop"); 126d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + mode); 127d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 128d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean: synonym for --clean-before and --clean-after (default)."); 129d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Disable with --no-clean if you want no files removed."); 130d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 131d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --stream: stream output as it is emitted."); 132d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 133d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --timeout <seconds>: maximum execution time of each action before the"); 134d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" runner aborts it. Specifying zero seconds or using --debug will"); 135d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" disable the execution timeout."); 136d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + timeoutSeconds); 137d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 138d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --xml-reports-directory <path>: directory to emit JUnit-style"); 139d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" XML test results."); 140d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 141d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --classpath <jar file>: add the .jar to both build and execute classpaths."); 142d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 143d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --use-boot-classpath: use the classpath as search path for bootstrap classes."); 144d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 145d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --build-classpath <element>: add the directory or .jar to the build"); 146d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" classpath. Such classes are available as build dependencies, but"); 147d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" not at runtime."); 148d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 149d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --sourcepath <directory>: add the directory to the build sourcepath."); 150d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 151d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --verbose: turn on persistent verbose output."); 152d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 153d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("TARGET OPTIONS"); 154d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 155d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --debug <port>: enable Java debugging on the specified port."); 156d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" This port must be free both on the device and on the local"); 157d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" system. Disables the timeout specified by --timeout-seconds."); 158d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 159d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --device-runner-dir <directory>: use the specified directory for"); 160d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" on-device temporary files and code."); 161d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + deviceRunnerDir); 162d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 163d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --vm-arg <argument>: include the specified argument when spawning a"); 164d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" virtual machine. Examples: -Xint:fast, -ea, -Xmx16M"); 165d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 166d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --java-home <java_home>: execute the actions on the local workstation"); 167d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" using the specified java home directory. This does not impact"); 168d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" which javac gets used. When unset, java is used from the PATH."); 169d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 170d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("EXOTIC OPTIONS"); 171d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 172d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean-before: remove working directories before building and"); 173d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" running (default). Disable with --no-clean-before if you are"); 174d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" using interactively with your own temporary input files."); 175d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 176d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean-after: remove temporary files after running (default)."); 177d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Disable with --no-clean-after and use with --verbose if"); 178d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" you'd like to manually re-run commands afterwards."); 179d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 180d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --color: format output in technicolor."); 181d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 182d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --expectations <file>: include the specified file when looking for"); 183d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" action expectations. The file should include qualified action names"); 184d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" and the corresponding expected output."); 185d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + expectationFiles); 186d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 187d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --ident: amount to indent action result output. Can be set to ''"); 188d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" (aka empty string) to simplify output parsing."); 189d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: '" + indent + "'"); 190d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 191d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --javac-arg <argument>: include the specified argument when invoking"); 192d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" javac. Examples: --javac-arg -Xmaxerrs --javac-arg 1"); 193d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 194d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --monitor-timeout <seconds>: number of seconds to wait for the target"); 195d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" process to launch. This can be used to prevent connection failures"); 196d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" when dexopt is slow."); 197d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 198d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 199d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 200d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean parseArgs(String[] args) { 201d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com List<String> actionsAndTargetArgs; 202d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com try { 203d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com actionsAndTargetArgs = new OptionParser(this).parse(args); 204d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } catch (RuntimeException e) { 205d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(e.getMessage()); 206d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 207d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 208d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 209d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 210d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // Semantic error validation 211d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 212d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 213d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (javaHome != null && !new File(javaHome, "/bin/java").exists()) { 214d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Invalid java home: " + javaHome); 215d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 216d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 2177850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 218d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // check vm option consistency 219d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (mode.acceptsVmArgs() && !vmArgs.isEmpty()) { 220d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("VM args " + vmArgs + " should not be specified for mode " + mode); 221d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 222d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 223d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 224d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) { 225d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Invalid XML reports directory: " + xmlReportsDirectory); 226d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 227d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 228d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 229d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (!clean) { 230d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com cleanBefore = false; 231d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com cleanAfter = false; 232d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 2337850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 234d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 235d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // Post-processing arguments 236d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 237d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 238d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // disable timeout when debugging 239d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (debugPort != null) { 240d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com timeoutSeconds = 0; 241d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 242d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 243d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // separate the actions and the target args 244d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com int index = 0; 245d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com for (; index < actionsAndTargetArgs.size(); index++) { 246d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com String arg = actionsAndTargetArgs.get(index); 247d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (arg.equals("--")) { 248d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com index++; 249d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com break; 2507850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 2517850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 252d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com File file = new File(arg); 253d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (file.exists()) { 254d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (arg.endsWith(".java") || file.isDirectory()) { 255d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com actionFiles.add(file); 256d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else { 257d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Expected a .jar file, .java file, directory, " 258d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com + "package name or classname, but was: " + arg); 259d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 260d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 261d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else { 262d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com actionClassesAndPackages.add(arg); 2637850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 264d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 265d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 266d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com targetArgs.addAll(actionsAndTargetArgs.subList(index, actionsAndTargetArgs.size())); 2677850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 268d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (actionFiles.isEmpty() && actionClassesAndPackages.isEmpty()) { 269d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("No actions provided."); 270d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 2717850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 2727850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 273d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (mode.acceptsVmArgs() && !targetArgs.isEmpty()) { 274d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Target args " + targetArgs + " should not be specified for mode " + mode); 275d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 276d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 2777850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 278d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return true; 279d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 2807850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 2817850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com private void run() { 282d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setColor(color); 283d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setIndent(indent); 284d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setStream(stream); 285d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setVerbose(verbose); 286d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 287d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com int monitorPort = mode.isHost() ? 8788 : 8787; 288d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Mode.Options modeOptions = new Mode.Options(Classpath.of(buildClasspath), sourcepath, 289d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com javacArgs, javaHome, monitorPort, useBootClasspath, Classpath.of(classpath)); 290d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 291d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com AndroidSdk androidSdk = null; 292d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (mode.requiresAndroidSdk()) { 293d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com androidSdk = AndroidSdk.getFromPath(); 294d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com modeOptions.buildClasspath.addAll(androidSdk.getAndroidClasses()); 295d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 296d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 297d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com File localTemp = new File("/tmp/vogar/" + UUID.randomUUID()); 298d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Environment environment = mode.isHost() 299d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com ? new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp) 300d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com : new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, monitorPort, localTemp, 301d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com deviceRunnerDir, androidSdk); 302d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 303d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Vm.Options vmOptions = (mode.acceptsVmArgs()) 304d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com ? new Vm.Options(vmArgs, targetArgs) 305d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com : null; 306957bd524afd6837b003e9e9b82745ebc42d20ba0bdc@google.com 3077850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Mode mode; 308d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (this.mode == ModeId.HOST) { 309d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com mode = new JavaVm(environment, modeOptions, vmOptions); 310d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else if (this.mode == ModeId.SIM) { 311d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com mode = new HostDalvikVm(environment, modeOptions, vmOptions, androidSdk); 312d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else if (this.mode == ModeId.DEVICE) { 313d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com mode = new DeviceDalvikVm(environment, modeOptions, vmOptions); 314d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else if (this.mode == ModeId.ACTIVITY) { 315d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com mode = new ActivityMode(environment, modeOptions); 3167850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } else { 317d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com throw new AssertionError(); 3187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 3197850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 320d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com HostMonitor monitor = new HostMonitor(monitorTimeout); 3217850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 3227850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com List<RunnerSpec> runnerSpecs = Arrays.asList( 3237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com new JtregSpec(localTemp), 3247850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com new JUnitSpec(), 3257850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com new CaliperSpec(), 3267850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com new MainSpec()); 3277850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 3287850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com ExpectationStore expectationStore; 3297850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com try { 330d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com expectationStore = ExpectationStore.parse(expectationFiles); 3317850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } catch (IOException e) { 3327850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com System.out.println("Problem loading expectations: " + e); 3337850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com return; 3347850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 3357850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 336d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com XmlReportPrinter xmlReportPrinter = xmlReportsDirectory != null 337d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com ? new XmlReportPrinter(xmlReportsDirectory, expectationStore) 3387850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com : null; 3397850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 3407850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Driver driver = new Driver( 3417850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com localTemp, 3427850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com mode, 3437850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com expectationStore, 3447850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com runnerSpecs, 3457850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com xmlReportPrinter, 3467850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com monitor, 3477850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com monitorPort, 348d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com timeoutSeconds); 3497850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 350d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com driver.buildAndRun(actionFiles, actionClassesAndPackages); 3517850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 3527850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 3537850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com public static void main(String[] args) { 3547850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Vogar vogar = new Vogar(); 355d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (!vogar.parseArgs(args)) { 356d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com vogar.printUsage(); 3577850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com return; 3587850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 3597850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com vogar.run(); 3607850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 361d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 362d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com enum ModeId { 363d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com DEVICE, HOST, ACTIVITY, SIM; 364d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 365d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean acceptsVmArgs() { 366d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return this != ACTIVITY; 367d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 368d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 369d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean isHost() { 370d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return this == ModeId.HOST || this == ModeId.SIM; 371d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 372d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 373d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean requiresAndroidSdk() { 374d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return this == DEVICE || this == ACTIVITY || this == SIM; 375d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 376d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 3777850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com} 378