Vogar.java revision 75a72cc4c645e7e038f381c936d3f521ac6c30ad
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 19d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.comimport com.google.common.collect.Lists; 207850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.File; 214cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.comimport java.io.FileNotFoundException; 227850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.IOException; 237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.ArrayList; 24d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.comimport java.util.Date; 257850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.LinkedHashSet; 267850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.List; 277850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.Set; 287850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.UUID; 29969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.ActivityMode; 30969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.AndroidSdk; 31969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.DeviceDalvikVm; 32969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.DeviceFileCache; 33969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.EnvironmentDevice; 34969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.HostDalvikVm; 35d59b17f5dc87d856a01714853d5296d387ff8dedjessewilson@google.comimport vogar.util.Strings; 367850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 377850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/** 387850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Command line interface for running benchmarks and tests on dalvik. 397850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */ 407850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.compublic final class Vogar { 417850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 428c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com private static final int LARGE_TIMEOUT_MULTIPLIER = 10; 43126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com private static final int NUM_PROCESSORS = Runtime.getRuntime().availableProcessors(); 448c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com 45d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<File> actionFiles = new ArrayList<File>(); 46d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<String> actionClassesAndPackages = new ArrayList<String>(); 47d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private final List<String> targetArgs = new ArrayList<String>(); 48fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com private final OptionParser optionParser = new OptionParser(this); 4925d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com private File configFile = Vogar.dotFile(".vogarconfig"); 5025d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com 51969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.com public static File dotFile (String name) { 5225d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com return new File(System.getProperty("user.home", "."), name); 5325d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com } 5425d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com 55d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 56d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--expectations" }) 57d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Set<File> expectationFiles = new LinkedHashSet<File>(); 58d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com { 599f9a3ba8e244912c50140ba15ec583a8098dca41enh@google.com expectationFiles.addAll(AndroidSdk.defaultExpectations()); 60d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 617850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 62d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--mode" }) 63d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private ModeId mode = ModeId.DEVICE; 647850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 65d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--timeout" }) 66d296ba8af13d367b4a701ddeba405ee51caa05c1enh@google.com private int timeoutSeconds = 1 * 60; // default is one minute; 677850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 68d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--monitor-timeout" }) 695884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com private int monitorTimeout = 30; 707850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 71126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com @Option(names = { "--first-monitor-port" }) 72126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com private int firstMonitorPort = -1; 73126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com 74d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean-before" }) 75d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean cleanBefore = true; 767850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 77d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean-after" }) 78d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean cleanAfter = true; 797850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 80d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--clean" }) 81d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean clean = true; 827850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 83d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--xml-reports-directory" }) 84d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private File xmlReportsDirectory; 857850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 86d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--indent" }) 87d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private String indent = " "; 887850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 89d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--verbose" }) 90d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean verbose; 917850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 92d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--stream" }) 93d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean stream = true; 947850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 95d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--color" }) 96d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean color = true; 977850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 9850bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com @Option(names = { "--pass-color" }) 9950bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com private int passColor = 32; // green 10050bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com 10150bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com @Option(names = { "--warn-color" }) 10250bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com private int warnColor = 33; // yellow 10350bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com 10450bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com @Option(names = { "--fail-color" }) 10550bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com private int failColor = 31; // red 10650bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com 107d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--debug" }) 108d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Integer debugPort; 109d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 1103d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com @Option(names = { "--device-dir" }) 1113d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com private File deviceDir = new File("/sdcard/vogar"); 112d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 113d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--vm-arg" }) 114d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<String> vmArgs = new ArrayList<String>(); 115d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 116d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--java-home" }) 117d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private File javaHome; 118d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 119d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--javac-arg" }) 120d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<String> javacArgs = new ArrayList<String>(); 121d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 12282131e6aba37e8b6f8ebbadbbe57fb5a78b4f743jessewilson@google.com @Option(names = { "--use-bootclasspath" }) 123d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean useBootClasspath = false; 124d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 125d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--build-classpath" }) 126d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> buildClasspath = new ArrayList<File>(); 127d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 128d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--classpath", "-cp" }) 129d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> classpath = new ArrayList<File>(); 130d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 131d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com @Option(names = { "--sourcepath" }) 132d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private List<File> sourcepath = new ArrayList<File>(); 133dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com { 134dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com sourcepath.addAll(AndroidSdk.defaultSourcePath()); 135dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com } 136d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 13741a680807eb80e63fbfe42c218c9e1da6615d867jsharpe@google.com @Option(names = { "--device-cache" }) 1382c67cf17be7262353493480d98fb88ad0f8fc320jsharpe@google.com private boolean deviceCache = true; 13941a680807eb80e63fbfe42c218c9e1da6615d867jsharpe@google.com 140d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com @Option(names = { "--jar-search-dir" }) 141d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com private List<File> jarSearchDirs = Lists.newArrayList(); 142d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 143d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com @Option(names = { "--vogar-dir" }) 1444ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com private File vogarDir = Vogar.dotFile(".vogar"); 1454cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 1468918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com @Option(names = { "--tag-dir" }) 1478918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com private File tagDir = null; 1488918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com 14900d4ce596c71916d975f6c8d967af53ab0a8f453jsharpe@google.com @Option(names = { "--tag" }, savedInTag = false) 1504cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com private String tagName = null; 1514cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 15200d4ce596c71916d975f6c8d967af53ab0a8f453jsharpe@google.com @Option(names = { "--run-tag" }, savedInTag = false) 1534cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com private String runTag = null; 1544cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 155d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com @Option(names = { "--compare-to-tag" }, savedInTag = false) 156d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com private String compareToTag = null; 157d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 15800d4ce596c71916d975f6c8d967af53ab0a8f453jsharpe@google.com @Option(names = { "--tag-overwrite" }, savedInTag = false) 1594cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com private boolean tagOverwrite = false; 1604cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 161d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com @Option(names = { "--record-results" }) 162d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com private boolean recordResults = false; 163d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 164d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com @Option(names = { "--results-dir" }) 165d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com private File resultsDir = null; 166d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 1673dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com @Option(names = { "--suggest-classpaths" }) 1683dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com private boolean suggestClasspaths = false; 1693dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com 1705bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com @Option(names = { "--valgrind" }) 1715bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com private boolean valgrind = false; 1725bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com 173d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private Vogar() {} 174d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 175d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private void printUsage() { 176fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com // have to reset fields so that "Default is: FOO" lines are accurate 177fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com optionParser.reset(); 178fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com 179d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Usage: Vogar [options]... <actions>... [-- target args]..."); 180d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 181d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" <actions>: .java files, directories, or class names."); 182d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" These should be JUnit tests, jtreg tests, Caliper benchmarks"); 183d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" or executable Java classes."); 184d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 18572c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com System.out.println(" When passing in a JUnit test class, it may have \"#method_name\""); 18672c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com System.out.println(" appended to it, to specify a single test method."); 18772c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com System.out.println(); 188d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" [args]: arguments passed to the target process. This is only useful when"); 189d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" the target process is a Caliper benchmark or main method."); 190d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 191d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("GENERAL OPTIONS"); 192d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 19379e4231584a3b24b44f42224475d41fcbe957af4jessewilson@google.com System.out.println(" --mode <activity|device|sim|jvm>: specify which environment to run in."); 194d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" activity: runs in an Android application on a device or emulator"); 195d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" device: runs in a Dalvik VM on a device or emulator"); 196d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" sim: runs in a Dalvik VM on the local desktop."); 19779e4231584a3b24b44f42224475d41fcbe957af4jessewilson@google.com System.out.println(" jvm: runs in a Java VM on the local desktop"); 198d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + mode); 199d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 200d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean: synonym for --clean-before and --clean-after (default)."); 201d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Disable with --no-clean if you want no files removed."); 202d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 203d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --stream: stream output as it is emitted."); 204d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 2055bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com System.out.println(" --valgrind: run the VM under valgrind (not supported for all VMs)."); 2065bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com System.out.println(); 207d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --timeout <seconds>: maximum execution time of each action before the"); 208d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" runner aborts it. Specifying zero seconds or using --debug will"); 2098c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com System.out.println(" disable the execution timeout. Tests tagged with 'large' will time"); 2108c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com System.out.println(" out in " + LARGE_TIMEOUT_MULTIPLIER + "x this timeout."); 211d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + timeoutSeconds); 212d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 213d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --xml-reports-directory <path>: directory to emit JUnit-style"); 214d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" XML test results."); 215d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 216d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --classpath <jar file>: add the .jar to both build and execute classpaths."); 217d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 218ba0670d6c4481a866ae558d4e31f8004c709dd77jessewilson@google.com System.out.println(" --use-bootclasspath: use the classpath as search path for bootstrap classes."); 219d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 220d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --build-classpath <element>: add the directory or .jar to the build"); 221d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" classpath. Such classes are available as build dependencies, but"); 222d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" not at runtime."); 223d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 224d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --sourcepath <directory>: add the directory to the build sourcepath."); 225d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 226d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --vogar-dir <directory>: directory in which to find Vogar"); 2276a52e048641707c987c6a00691ba8c9f891ccf00jsharpe@google.com System.out.println(" configuration information, caches, saved results, and tags,"); 2286a52e048641707c987c6a00691ba8c9f891ccf00jsharpe@google.com System.out.println(" unless they've been put explicitly elsewhere."); 229d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" Default is: " + vogarDir); 2304cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(); 2316a52e048641707c987c6a00691ba8c9f891ccf00jsharpe@google.com System.out.println(" --tag-dir <directory>: directory in which to find tag information."); 2324ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com System.out.println(" Default is: " + vogarDir + "/tags"); 2336a52e048641707c987c6a00691ba8c9f891ccf00jsharpe@google.com System.out.println(); 2344cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" --tag <tag name>: creates a tag recording the arguments to this"); 2354cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" invocation of Vogar so that it can be rerun later."); 2364cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(); 2374cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" --run-tag <tag name>: runs Vogar with arguments as specified by the"); 2384cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" tag. Any arguments supplied for this run will override those"); 2394cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" supplied by the tag."); 2404cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(); 241d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --compare-to-tag <tag name>: compares the results of this run with"); 242d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" the results saved when the tag was created. Defaults to the value"); 243d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" of --run-tag if that argument is given."); 244d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 245d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --record-results: record test results for future comparison."); 246d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 247d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --results-dir <directory>: read and write (if --record-results used)"); 248d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" results from and to this directory."); 249d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 2504cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" --tag-overwrite: allow --tag to overwrite an existing tag."); 2514cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(); 252d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --verbose: turn on persistent verbose output."); 253d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 254d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("TARGET OPTIONS"); 255d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 256d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --debug <port>: enable Java debugging on the specified port."); 257d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" This port must be free both on the device and on the local"); 258d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" system. Disables the timeout specified by --timeout-seconds."); 259d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 2603d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com System.out.println(" --device-dir <directory>: use the specified directory for"); 261d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" on-device temporary files and code."); 2623d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com System.out.println(" Default is: " + deviceDir); 263d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 264d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --vm-arg <argument>: include the specified argument when spawning a"); 265d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" virtual machine. Examples: -Xint:fast, -ea, -Xmx16M"); 266d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 267d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --java-home <java_home>: execute the actions on the local workstation"); 268d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" using the specified java home directory. This does not impact"); 269d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" which javac gets used. When unset, java is used from the PATH."); 270d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 271d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("EXOTIC OPTIONS"); 272d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 2732c67cf17be7262353493480d98fb88ad0f8fc320jsharpe@google.com System.out.println(" --device-cache: keep copies of dexed files on the SD card so they"); 27441a680807eb80e63fbfe42c218c9e1da6615d867jsharpe@google.com System.out.println(" don't need to be pushed each time a test is run, improving"); 2752c67cf17be7262353493480d98fb88ad0f8fc320jsharpe@google.com System.out.println(" start times (default). Only affects device mode. Disable with"); 2764cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println(" --no-device-cache to save space on the SD card."); 27741a680807eb80e63fbfe42c218c9e1da6615d867jsharpe@google.com System.out.println(); 2783dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com System.out.println(" --suggest-classpaths: build an index of jar files under the"); 279d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" directories given by --jar-search-dir arguments. If Vogar then "); 280d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" fails due to missing classes or packages, it will use the index to"); 281d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" diagnose the problem and suggest a fix."); 2823dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com System.out.println(); 2833dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com System.out.println(" Currently only looks for jars called exactly \"classes.jar\"."); 2843dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com System.out.println(); 285d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --jar-search-dir <directory>: a directory that should be searched for"); 286d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" jar files to add to the class file index for use with"); 287d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" --suggest-classpaths."); 288d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 289d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean-before: remove working directories before building and"); 290d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" running (default). Disable with --no-clean-before if you are"); 291d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" using interactively with your own temporary input files."); 292d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 293d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --clean-after: remove temporary files after running (default)."); 294d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Disable with --no-clean-after and use with --verbose if"); 295d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" you'd like to manually re-run commands afterwards."); 296d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 297d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --color: format output in technicolor."); 298d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 29950bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" --pass-color: ANSI color code to use for passes."); 30050bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" Default: 32 (green)"); 30150bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(); 30250bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" --warn-color: ANSI color code to use for warnings."); 30350bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" Default: 33 (yellow)"); 30450bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(); 30550bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" --fail-color: ANSI color code to use for failures."); 30650bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(" Default: 31 (red)"); 30750bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com System.out.println(); 308d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --expectations <file>: include the specified file when looking for"); 309d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" action expectations. The file should include qualified action names"); 310d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" and the corresponding expected output."); 311d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: " + expectationFiles); 312d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 3133dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com System.out.println(" --indent: amount to indent action result output. Can be set to ''"); 314d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" (aka empty string) to simplify output parsing."); 315d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" Default is: '" + indent + "'"); 316d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 317d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --javac-arg <argument>: include the specified argument when invoking"); 318d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" javac. Examples: --javac-arg -Xmaxerrs --javac-arg 1"); 319d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 320d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" --monitor-timeout <seconds>: number of seconds to wait for the target"); 321d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" process to launch. This can be used to prevent connection failures"); 322d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(" when dexopt is slow."); 323d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(); 324126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(" --first-monitor-port <port>: the port on the host (and possibly target)"); 325126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(" used to traffic control messages between vogar and forked processes."); 326126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(" Use this to avoid port conflicts when running multiple vogar instances"); 327126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(" concurrently. Vogar will use up to N ports starting with this one,"); 328126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(" where N is the number of processors on the host (" + NUM_PROCESSORS + "). "); 329126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com System.out.println(); 330d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println("CONFIG FILE"); 331d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 332d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" User-defined default arguments can be specified in ~/.vogarconfig. See"); 333d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(" .vogarconfig.example for an example."); 334d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com System.out.println(); 335d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 336d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 337d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com private boolean parseArgs(String[] args) { 338d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com List<String> actionsAndTargetArgs; 339d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 340d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com // extract arguments from config file 3418918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com String[] configArgs = optionParser.readFile(configFile); 342d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 343d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com // config file args are added first so that in a conflict, the currently supplied 344d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com // arguments win. 345d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com actionsAndTargetArgs = optionParser.parse(configArgs); 3468918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com if (!actionsAndTargetArgs.isEmpty()) { 3478918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com throw new RuntimeException( 3488918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com "actions or targets given in .vogarconfig: " + actionsAndTargetArgs); 3498918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com } 350d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 351d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com try { 352d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com actionsAndTargetArgs.addAll(optionParser.parse(args)); 353d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } catch (RuntimeException e) { 354d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println(e.getMessage()); 355d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 356d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 357d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 3584cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com if (runTag != null && tagName != null) { 3594cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println("Cannot use both --run-tag and --tag options"); 3604cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com return false; 3614cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com } 3624cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 3634cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com if (runTag != null) { 3644cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com String oldTag = tagName; 3654cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com String[] runTagArgs; 3668918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com if (tagDir == null) { 3674ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com tagDir = new File(vogarDir, "/tags"); 3688918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com } 3694cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com try { 3704cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com runTagArgs = new Tag(tagDir, runTag, false).getArgs(); 3714cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com System.out.println("Executing Vogar with additional arguments from tag \"" 3724cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com + runTag + "\":"); 373c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com System.out.println(Strings.join(" ", (Object[]) runTagArgs)); 3744cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com } catch (FileNotFoundException e) { 375fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com System.out.println("Tag \"" + runTag + "\" doesn't exist"); 376fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com System.out.println("Existing tags are: " 377c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com + Strings.join(", ", (Object[]) Tag.getAllTags(tagDir))); 3784cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com return false; 3794cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com } 380d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com // rollback changes already made by the optionParser to insert tag arguments 3814cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com optionParser.reset(); 382d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com actionsAndTargetArgs = optionParser.parse(configArgs); 3834cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com // runTags options are applied first so that the current command's arguments win if 3844cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com // there is a conflict 385d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com actionsAndTargetArgs.addAll(optionParser.parse(runTagArgs)); 3864cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com // tag is the only argument we don't allow to be supplied by the run tag 3874cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com tagName = oldTag; 3884cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com actionsAndTargetArgs.addAll(optionParser.parse(args)); 3894cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com } 3904cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 391d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 392d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // Semantic error validation 393d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 394d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 395d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (javaHome != null && !new File(javaHome, "/bin/java").exists()) { 396d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Invalid java home: " + javaHome); 397d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 398d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 3997850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 400d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // check vm option consistency 401595d8fd07fcad6d6661466b4b22905e5e82eb857jessewilson@google.com if (!mode.acceptsVmArgs() && !vmArgs.isEmpty()) { 402d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("VM args " + vmArgs + " should not be specified for mode " + mode); 403d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 404d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 405d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 406d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) { 407d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Invalid XML reports directory: " + xmlReportsDirectory); 408d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 409d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 410d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 411d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (!clean) { 412d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com cleanBefore = false; 413d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com cleanAfter = false; 414d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 4157850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 416d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 417d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // Post-processing arguments 418d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // 419d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 420d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // disable timeout when debugging 421d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (debugPort != null) { 422d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com timeoutSeconds = 0; 423d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 424d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 425126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com if (firstMonitorPort == -1) { 426126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com firstMonitorPort = mode.isHost() ? 8788 : 8787; 427126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com } 428126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com 429d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com // separate the actions and the target args 430d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com int index = 0; 431d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com for (; index < actionsAndTargetArgs.size(); index++) { 432d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com String arg = actionsAndTargetArgs.get(index); 433d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (arg.equals("--")) { 434d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com index++; 435d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com break; 4367850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 4377850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 438d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com File file = new File(arg); 439d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (file.exists()) { 440d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (arg.endsWith(".java") || file.isDirectory()) { 441995a215ce56a98ed522888b0fdc286cd612c0218jessewilson@google.com actionFiles.add(file.getAbsoluteFile()); 442d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else { 443d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Expected a .jar file, .java file, directory, " 444d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com + "package name or classname, but was: " + arg); 445d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 446d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 447d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } else { 448d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com actionClassesAndPackages.add(arg); 4497850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 450d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 451d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 452d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com targetArgs.addAll(actionsAndTargetArgs.subList(index, actionsAndTargetArgs.size())); 4537850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 454d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (actionFiles.isEmpty() && actionClassesAndPackages.isEmpty()) { 455d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("No actions provided."); 456d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 4577850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 4587850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 459595d8fd07fcad6d6661466b4b22905e5e82eb857jessewilson@google.com if (!mode.acceptsVmArgs() && !targetArgs.isEmpty()) { 460d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com System.out.println("Target args " + targetArgs + " should not be specified for mode " + mode); 461d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return false; 462d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 4637850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 4645bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com if (valgrind && !mode.supportsValgrind()) { 4655bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com System.out.println("Valgrind is not supported for mode " + mode); 4665bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com return false; 4675bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com } 4685bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com 4694cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com if (tagName != null) { 4708918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com if (tagDir == null) { 4714ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com tagDir = new File(vogarDir, "/tags"); 4728918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com } 4738918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com new Tag(tagDir, tagName, tagOverwrite).saveArgs(args); 4744cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com } 4754cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com 476d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return true; 477d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 4787850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 47975a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com private boolean run() { 4805884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com Console.init(stream); 48150bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com Console.getInstance().setUseColor(color, passColor, warnColor, failColor); 482d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setIndent(indent); 483d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Console.getInstance().setVerbose(verbose); 484d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 485d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com ClassFileIndex classFileIndex = new ClassFileIndex(jarSearchDirs); 4863dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com if (suggestClasspaths) { 4873dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com classFileIndex.createIndex(); 4883dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com } 4893dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com 490d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com if (resultsDir == null) { 4914ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com resultsDir = new File(vogarDir, "results"); 492d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com } 4938918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com if (tagDir == null) { 4944ac80fd21b440a8e9debe995e73c71e0fed8735cjsharpe@google.com tagDir = new File(vogarDir, "results/tags"); 4958918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com } 4963d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com 4975884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com int numRunners = (stream || this.mode == ModeId.ACTIVITY) 4985884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com ? 1 499126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com : NUM_PROCESSORS; 500d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Mode.Options modeOptions = new Mode.Options(Classpath.of(buildClasspath), sourcepath, 501c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com javacArgs, javaHome, firstMonitorPort, monitorTimeout, timeoutSeconds, 502c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com useBootClasspath, Classpath.of(classpath)); 503d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 504d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com AndroidSdk androidSdk = null; 505d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (mode.requiresAndroidSdk()) { 506d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com androidSdk = AndroidSdk.getFromPath(); 5073d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com if (deviceCache) { 5083d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com androidSdk.setDeviceCache(new DeviceFileCache(deviceDir, androidSdk)); 5093d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com } 510d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com modeOptions.buildClasspath.addAll(androidSdk.getAndroidClasses()); 511d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 512d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 513d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com File localTemp = new File("/tmp/vogar/" + UUID.randomUUID()); 514d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Environment environment = mode.isHost() 515c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com ? new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp) 516c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com : new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, firstMonitorPort, 517c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com numRunners, localTemp, new File(deviceDir, "run"), androidSdk); 518d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 519d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com Vm.Options vmOptions = (mode.acceptsVmArgs()) 520d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com ? new Vm.Options(vmArgs, targetArgs) 521d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com : null; 522957bd524afd6837b003e9e9b82745ebc42d20ba0bdc@google.com 5237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Mode mode; 524c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com switch (this.mode) { 525c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com case JVM: 526c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com mode = new JavaVm(environment, modeOptions, vmOptions); 527c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com break; 528c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com case SIM: 529c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com mode = new HostDalvikVm(environment, modeOptions, vmOptions, androidSdk, valgrind); 530c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com break; 531c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com case DEVICE: 532c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com mode = new DeviceDalvikVm(environment, modeOptions, vmOptions); 533c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com break; 534c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com case ACTIVITY: 535c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com mode = new ActivityMode(environment, modeOptions); 536c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com break; 537c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com default: 538c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com throw new AssertionError(); 5397850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 5407850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 5417850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com ExpectationStore expectationStore; 5427850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com try { 543d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com expectationStore = ExpectationStore.parse(expectationFiles); 5447850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } catch (IOException e) { 5457850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com System.out.println("Problem loading expectations: " + e); 54675a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com return false; 5477850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 5487850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 549d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com Date currentDate = new Date(); 550d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 551d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com XmlReportPrinter xmlReportPrinter = xmlReportsDirectory != null 552d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com ? new XmlReportPrinter(xmlReportsDirectory, expectationStore, currentDate) 5537850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com : null; 5547850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 555d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com // Automatically compare to a tag if we explicitly run it 556d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com if (runTag != null && compareToTag == null) { 557d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com compareToTag = runTag; 558d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com } 559d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com 5608c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com int smallTimeoutSeconds = timeoutSeconds; 5617850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Driver driver = new Driver( 5627850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com localTemp, 5637850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com mode, 5647850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com expectationStore, 565d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com currentDate, 5667850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com xmlReportPrinter, 567126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com firstMonitorPort, 5688c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com smallTimeoutSeconds, 5693dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com smallTimeoutSeconds * LARGE_TIMEOUT_MULTIPLIER, 5705884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com classFileIndex, 571d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com resultsDir, 5728918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com tagDir, 573d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com tagName, 574d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com compareToTag, 575d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com recordResults, 5765884b0e6bc3eec46f4a374254626a14d128179fajessewilson@google.com numRunners); 5777850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 57875a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com return driver.buildAndRun(actionFiles, actionClassesAndPackages); 5797850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 5807850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 5817850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com public static void main(String[] args) { 5827850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Vogar vogar = new Vogar(); 583d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com if (!vogar.parseArgs(args)) { 584d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com vogar.printUsage(); 5857850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com return; 5867850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 58775a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com boolean allSuccess = vogar.run(); 58875a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com System.exit(allSuccess ? 0 : 1); 5897850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 590d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 591d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com enum ModeId { 592c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com DEVICE, JVM, ACTIVITY, SIM, CRORE; 593d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 5945bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com public boolean supportsValgrind() { 5955bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com return this == SIM; 5965bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com } 5975bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com 598d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean acceptsVmArgs() { 599c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com return this != ACTIVITY && this != CRORE; 600d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 601d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 602d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean isHost() { 603c68971a68a4f7fe5a58ca0f59161bb44fcf2833djessewilson@google.com return this == JVM || this == SIM || this == CRORE; 604d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 605d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 606d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com public boolean requiresAndroidSdk() { 607d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com return this == DEVICE || this == ACTIVITY || this == SIM; 608d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 609d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 6107850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com} 611