Adding support for command line args to vogar-initiated processes.

Also adding monitor timeouts for use by the continuous build.
From the huge number of files in this relatively simple CL, it's
becoming clear that we need to simplify vogar's internals!
diff --git a/libcore/tools/runner/java/vogar/DeviceDalvikVm.java b/libcore/tools/runner/java/vogar/DeviceDalvikVm.java
index fa96e82..4b44f02 100644
--- a/libcore/tools/runner/java/vogar/DeviceDalvikVm.java
+++ b/libcore/tools/runner/java/vogar/DeviceDalvikVm.java
@@ -29,9 +29,10 @@
 
     DeviceDalvikVm(Integer debugPort, File sdkJar, List<String> javacArgs,
             int monitorPort, File localTemp, List<String> additionalVmArgs,
-            boolean cleanBefore, boolean cleanAfter, File runnerDir) {
+            List<String> targetArgs, boolean cleanBefore, boolean cleanAfter,
+            File runnerDir) {
         super(new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, monitorPort, localTemp,
-                runnerDir), sdkJar, javacArgs, additionalVmArgs, monitorPort);
+                runnerDir), sdkJar, javacArgs, additionalVmArgs, targetArgs, monitorPort);
     }
 
     private EnvironmentDevice getEnvironmentDevice() {
diff --git a/libcore/tools/runner/java/vogar/HostMonitor.java b/libcore/tools/runner/java/vogar/HostMonitor.java
index 9732b66..c5e84bf 100644
--- a/libcore/tools/runner/java/vogar/HostMonitor.java
+++ b/libcore/tools/runner/java/vogar/HostMonitor.java
@@ -39,8 +39,11 @@
 
     private static final Logger logger = Logger.getLogger(HostMonitor.class.getName());
 
-    private final int MAX_CONNECT_ATTEMPTS = 10;
-    private final int CONNECTION_ATTEMPT_DELAY_MILLIS = 1000;
+    private final long monitorTimeoutSeconds;
+
+    HostMonitor(long monitorTimeoutSeconds) {
+        this.monitorTimeoutSeconds = monitorTimeoutSeconds;
+    }
 
     /**
      * Connect to the target process on the given port, read all of its
@@ -65,16 +68,16 @@
                 return false;
             }
 
-            if (attempt++ == MAX_CONNECT_ATTEMPTS) {
-                logger.warning("Exceeded " + MAX_CONNECT_ATTEMPTS
+            if (attempt++ == monitorTimeoutSeconds) {
+                logger.warning("Exceeded " + monitorTimeoutSeconds
                         + " attempts to connect to localhost:" + port);
                 return false;
             }
 
             logger.fine("connection " + attempt + " to localhost:" + port
-                    + " failed; retrying in " + CONNECTION_ATTEMPT_DELAY_MILLIS + "ms");
+                    + " failed; retrying in 1s");
             try {
-                Thread.sleep(CONNECTION_ATTEMPT_DELAY_MILLIS);
+                Thread.sleep(1000);
             } catch (InterruptedException e) {
             }
         } while (true);
diff --git a/libcore/tools/runner/java/vogar/JavaVm.java b/libcore/tools/runner/java/vogar/JavaVm.java
index dcb0969..f728744 100644
--- a/libcore/tools/runner/java/vogar/JavaVm.java
+++ b/libcore/tools/runner/java/vogar/JavaVm.java
@@ -28,9 +28,9 @@
 
     JavaVm(Integer debugPort, File sdkJar, List<String> javacArgs, int monitorPort,
             File localTemp, File javaHome, List<String> additionalVmArgs,
-            boolean cleanBefore, boolean cleanAfter) {
+            List<String> targetArgs, boolean cleanBefore, boolean cleanAfter) {
         super(new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp),
-                sdkJar, javacArgs, additionalVmArgs, monitorPort);
+                sdkJar, javacArgs, additionalVmArgs, targetArgs, monitorPort);
         this.javaHome = javaHome;
     }
 
diff --git a/libcore/tools/runner/java/vogar/Vm.java b/libcore/tools/runner/java/vogar/Vm.java
index c69d7a2..4edb0bc 100644
--- a/libcore/tools/runner/java/vogar/Vm.java
+++ b/libcore/tools/runner/java/vogar/Vm.java
@@ -32,11 +32,13 @@
 public abstract class Vm extends Mode {
 
     protected final List<String> additionalVmArgs;
+    protected final List<String> targetArgs;
 
     Vm(Environment environment, File sdkJar, List<String> javacArgs,
-            List<String> additionalVmArgs, int monitorPort) {
+            List<String> additionalVmArgs, List<String> targetArgs, int monitorPort) {
         super(environment, sdkJar, javacArgs, monitorPort);
         this.additionalVmArgs = additionalVmArgs;
+        this.targetArgs = targetArgs;
     }
 
     /**
@@ -49,6 +51,7 @@
                 .debugPort(environment.debugPort)
                 .vmArgs(additionalVmArgs)
                 .mainClass(TestRunner.class.getName())
+                .args(targetArgs)
                 .build();
     }
 
@@ -76,6 +79,7 @@
         private PrintStream output;
         private List<String> vmCommand = Collections.singletonList("java");
         private List<String> vmArgs = new ArrayList<String>();
+        private List<String> args = new ArrayList<String>();
 
         public VmCommandBuilder vmCommand(String... vmCommand) {
             this.vmCommand = Arrays.asList(vmCommand.clone());
@@ -126,6 +130,15 @@
             return this;
         }
 
+        public VmCommandBuilder args(String... args) {
+            return args(Arrays.asList(args));
+        }
+
+        public VmCommandBuilder args(Collection<String> args) {
+            this.args.addAll(args);
+            return this;
+        }
+
         public Command build() {
             Command.Builder builder = new Command.Builder();
             builder.args(vmCommand);
@@ -146,6 +159,7 @@
 
             builder.args(vmArgs);
             builder.args(mainClass);
+            builder.args(args);
 
             builder.tee(output);
 
diff --git a/libcore/tools/runner/java/vogar/Vogar.java b/libcore/tools/runner/java/vogar/Vogar.java
index bca0a3d..2e9e3a9 100644
--- a/libcore/tools/runner/java/vogar/Vogar.java
+++ b/libcore/tools/runner/java/vogar/Vogar.java
@@ -36,6 +36,7 @@
     private static class Options {
 
         private final List<File> actionFiles = new ArrayList<File>();
+        private final List<String> targetArgs = new ArrayList<String>();
 
         @Option(names = { "--expectations" })
         private Set<File> expectationFiles = new LinkedHashSet<File>();
@@ -52,6 +53,9 @@
         @Option(names = { "--timeout" })
         private long timeoutSeconds = 10 * 60; // default is ten minutes;
 
+        @Option(names = { "--monitor-timeout" })
+        private long monitorTimeout = 10;
+
         @Option(names = { "--clean-before" })
         private boolean cleanBefore = true;
 
@@ -95,53 +99,43 @@
         private File sdkJar = new File("/home/dalvik-prebuild/android-sdk-linux/platforms/android-2.0/android.jar");
 
         private void printUsage() {
-            System.out.println("Usage: Vogar [options]... <actions>...");
+            System.out.println("Usage: Vogar [options]... <actions>... [target args]...");
             System.out.println();
-            System.out.println("  <actions>: .java files containing a jtreg tests, JUnit tests,");
-            System.out.println("      Caliper benchmarks, or a directory of such tests.");
+            System.out.println("  <actions>: .java files or directories containing jtreg tests, JUnit");
+            System.out.println("      tests, Caliper benchmarks, or executable Java classes.");
+            System.out.println();
+            System.out.println("  [args]: arguments passed to the target process. This is only useful when");
+            System.out.println("      the target process is a Caliper benchmark or main method.");
             System.out.println();
             System.out.println("GENERAL OPTIONS");
             System.out.println();
-            System.out.println("  --expectations <file>: include the specified file when looking for");
-            System.out.println("      action expectations. The file should include qualified action names");
-            System.out.println("      and the corresponding expected output.");
-            System.out.println("      Default is: " + expectationFiles);
-            System.out.println();
             System.out.println("  --mode <device|host|activity>: specify which environment to run the");
             System.out.println("      actions in. Options are on the device VM, on the host VM, and on");
             System.out.println("      device within an android.app.Activity.");
             System.out.println("      Default is: " + mode);
             System.out.println();
-            System.out.println("  --clean-before: remove working directories before building and");
-            System.out.println("      running (default). Disable with --no-clean-before if you are");
-            System.out.println("      using interactively with your own temporary input files.");
-            System.out.println();
-            System.out.println("  --clean-after: remove temporary files after running (default).");
-            System.out.println("      Disable with --no-clean-after and use with --verbose if");
-            System.out.println("      you'd like to manually re-run commands afterwards.");
-            System.out.println();
             System.out.println("  --clean: synonym for --clean-before and --clean-after (default).");
             System.out.println("      Disable with --no-clean if you want no files removed.");
             System.out.println();
-            System.out.println("  --color: format output in technicolor.");
-            System.out.println();
             System.out.println("  --stream: stream output as it is emitted.");
             System.out.println();
-            System.out.println("  --timeout-seconds <seconds>: maximum execution time of each");
-            System.out.println("      action before the runner aborts it. Specifying zero seconds");
-            System.out.println("      or using --debug will disable the execution timeout");
+            System.out.println("  --timeout <seconds>: maximum execution time of each action before the");
+            System.out.println("      runner aborts it. Specifying zero seconds or using --debug will");
+            System.out.println("      disable the execution timeout.");
             System.out.println("      Default is: " + timeoutSeconds);
             System.out.println();
             System.out.println("  --xml-reports-directory <path>: directory to emit JUnit-style");
             System.out.println("      XML test results.");
             System.out.println();
-            System.out.println("  --ident: amount to indent action result output. Can be set to ''");
-            System.out.println("      (aka empty string) to simplify output parsing.");
-            System.out.println("      Default is: '" + indent + "'");
+            System.out.println("  --sdk <android jar>: the API jar file to compile against.");
+            System.out.println("      Usually this is <SDK>/platforms/android-<X.X>/android.jar");
+            System.out.println("      where <SDK> is the path to an Android SDK path and <X.X> is");
+            System.out.println("      a release version like 1.5.");
+            System.out.println("      Default is: " + sdkJar);
             System.out.println();
             System.out.println("  --verbose: turn on verbose output");
             System.out.println();
-            System.out.println("DEVICE OPTIONS");
+            System.out.println("TARGET OPTIONS");
             System.out.println();
             System.out.println("  --debug <port>: enable Java debugging on the specified port.");
             System.out.println("      This port must be free both on the device and on the local");
@@ -151,34 +145,47 @@
             System.out.println("      on-device temporary files and code.");
             System.out.println("      Default is: " + deviceRunnerDir);
             System.out.println();
-            System.out.println("GENERAL VM OPTIONS");
-            System.out.println();
             System.out.println("  --vm-arg <argument>: include the specified argument when spawning a");
             System.out.println("      virtual machine. Examples: -Xint:fast, -ea, -Xmx16M");
             System.out.println();
-            System.out.println("HOST VM OPTIONS");
-            System.out.println();
             System.out.println("  --java-home <java_home>: execute the actions on the local workstation");
             System.out.println("      using the specified java home directory. This does not impact");
             System.out.println("      which javac gets used. When unset, java is used from the PATH.");
             System.out.println();
-            System.out.println("COMPILE OPTIONS");
+            System.out.println("EXOTIC OPTIONS");
             System.out.println();
-            System.out.println("  --sdk <android jar>: the API jar file to compile against.");
-            System.out.println("      Usually this is <SDK>/platforms/android-<X.X>/android.jar");
-            System.out.println("      where <SDK> is the path to an Android SDK path and <X.X> is");
-            System.out.println("      a release version like 1.5.");
-            System.out.println("      Default is: " + sdkJar);
+            System.out.println("  --clean-before: remove working directories before building and");
+            System.out.println("      running (default). Disable with --no-clean-before if you are");
+            System.out.println("      using interactively with your own temporary input files.");
+            System.out.println();
+            System.out.println("  --clean-after: remove temporary files after running (default).");
+            System.out.println("      Disable with --no-clean-after and use with --verbose if");
+            System.out.println("      you'd like to manually re-run commands afterwards.");
+            System.out.println();
+            System.out.println("  --color: format output in technicolor.");
+            System.out.println();
+            System.out.println("  --expectations <file>: include the specified file when looking for");
+            System.out.println("      action expectations. The file should include qualified action names");
+            System.out.println("      and the corresponding expected output.");
+            System.out.println("      Default is: " + expectationFiles);
+            System.out.println();
+            System.out.println("  --ident: amount to indent action result output. Can be set to ''");
+            System.out.println("      (aka empty string) to simplify output parsing.");
+            System.out.println("      Default is: '" + indent + "'");
             System.out.println();
             System.out.println("  --javac-arg <argument>: include the specified argument when invoking");
             System.out.println("      javac. Examples: --javac-arg -Xmaxerrs --javac-arg 1");
             System.out.println();
+            System.out.println("  --monitor-timeout <seconds>: number of seconds to wait for the target");
+            System.out.println("      process to launch. This can be used to prevent connection failures");
+            System.out.println("      when dexopt is slow.");
+            System.out.println();
         }
 
         private boolean parseArgs(String[] args) {
-            final List<String> actionFilenames;
+            List<String> actionsAndTargetArgs;
             try {
-                actionFilenames = new OptionParser(this).parse(args);
+                actionsAndTargetArgs = new OptionParser(this).parse(args);
             } catch (RuntimeException e) {
                 System.out.println(e.getMessage());
                 return false;
@@ -236,11 +243,6 @@
                 return false;
             }
 
-            if (actionFilenames.isEmpty()) {
-                System.out.println("No actions provided.");
-                return false;
-            }
-
             if (!clean) {
                 cleanBefore = false;
                 cleanAfter = false;
@@ -255,13 +257,35 @@
                 timeoutSeconds = 0;
             }
 
-            for (String actionFilename : actionFilenames) {
-                actionFiles.add(new File(actionFilename));
+            // separate the actions and the target args
+            boolean action = true;
+            for (String arg : actionsAndTargetArgs) {
+                if (arg.equals("--")) {
+                    action = false;
+                    continue;
+                }
+
+                File actionFile = new File(arg);
+                if (action && actionFile.exists()) {
+                    actionFiles.add(actionFile);
+                } else {
+                    targetArgs.add(arg);
+                    action = false;
+                }
+            }
+
+            if (actionFiles.isEmpty()) {
+                System.out.println("No actions provided.");
+                return false;
+            }
+
+            if (!targetArgs.isEmpty() && mode.equals(Options.MODE_ACTIVITY)) {
+                System.out.println("Target args not supported with --mode activity");
+                return false;
             }
 
             return true;
         }
-
     }
 
     private final Options options = new Options();
@@ -284,6 +308,7 @@
                     monitorPort,
                     localTemp,
                     options.vmArgs,
+                    options.targetArgs,
                     options.cleanBefore,
                     options.cleanAfter,
                     options.deviceRunnerDir);
@@ -297,6 +322,7 @@
                     localTemp,
                     options.javaHome,
                     options.vmArgs,
+                    options.targetArgs,
                     options.cleanBefore,
                     options.cleanAfter
             );
@@ -316,7 +342,7 @@
             return;
         }
 
-        HostMonitor monitor = new HostMonitor();
+        HostMonitor monitor = new HostMonitor(options.monitorTimeout);
 
         List<CodeFinder> codeFinders = Arrays.asList(
                 new JtregFinder(localTemp),
diff --git a/libcore/tools/runner/java/vogar/target/CaliperRunner.java b/libcore/tools/runner/java/vogar/target/CaliperRunner.java
index 5b424c8..3336716 100644
--- a/libcore/tools/runner/java/vogar/target/CaliperRunner.java
+++ b/libcore/tools/runner/java/vogar/target/CaliperRunner.java
@@ -32,10 +32,10 @@
         this.monitor = monitor;
     }
 
-    public void run(String actionName, Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
         monitor.outcomeStarted(actionName, actionName);
         try {
-            Runner.main(testClass.asSubclass(Benchmark.class), new String[0]);
+            Runner.main(testClass.asSubclass(Benchmark.class), args);
         } catch (Exception ex) {
             ex.printStackTrace();
         }
diff --git a/libcore/tools/runner/java/vogar/target/JUnitRunner.java b/libcore/tools/runner/java/vogar/target/JUnitRunner.java
index 00c61f8..f15cad3 100644
--- a/libcore/tools/runner/java/vogar/target/JUnitRunner.java
+++ b/libcore/tools/runner/java/vogar/target/JUnitRunner.java
@@ -57,7 +57,7 @@
         this.junitTest = testRunner.getTest(testClass.getName());
     }
 
-    public void run(String actionName, Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
         testRunner.doRun(junitTest);
     }
 
diff --git a/libcore/tools/runner/java/vogar/target/JtregRunner.java b/libcore/tools/runner/java/vogar/target/JtregRunner.java
index 6deeef9..47090c5 100644
--- a/libcore/tools/runner/java/vogar/target/JtregRunner.java
+++ b/libcore/tools/runner/java/vogar/target/JtregRunner.java
@@ -37,10 +37,10 @@
         }
     }
 
-    public void run(String actionName, Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
         monitor.outcomeStarted(actionName, actionName);
         try {
-            main.invoke(null, new Object[] { new String[0] });
+            main.invoke(null, new Object[] { args });
             monitor.outcomeFinished(Result.SUCCESS);
         } catch (Throwable failure) {
             failure.printStackTrace();
diff --git a/libcore/tools/runner/java/vogar/target/MainRunner.java b/libcore/tools/runner/java/vogar/target/MainRunner.java
index cc7dccd..d4e5dec 100644
--- a/libcore/tools/runner/java/vogar/target/MainRunner.java
+++ b/libcore/tools/runner/java/vogar/target/MainRunner.java
@@ -37,10 +37,10 @@
         }
     }
 
-    public void run(String actionName, Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
         monitor.outcomeStarted(actionName, actionName);
         try {
-            main.invoke(null, new Object[] { new String[0] });
+            main.invoke(null, new Object[] { args });
         } catch (Throwable ex) {
             ex.printStackTrace();
         }
diff --git a/libcore/tools/runner/java/vogar/target/Runner.java b/libcore/tools/runner/java/vogar/target/Runner.java
index af98a00..a06ba1a 100644
--- a/libcore/tools/runner/java/vogar/target/Runner.java
+++ b/libcore/tools/runner/java/vogar/target/Runner.java
@@ -25,5 +25,5 @@
     public void init(TargetMonitor monitor, String actionName,
             Class<?> testClass);
 
-    public void run(String actionName, Class<?> testClass);
+    public void run(String actionName, Class<?> testClass, String[] args);
 }
diff --git a/libcore/tools/runner/java/vogar/target/TestRunner.java b/libcore/tools/runner/java/vogar/target/TestRunner.java
index 1e1f479..739cbc5 100644
--- a/libcore/tools/runner/java/vogar/target/TestRunner.java
+++ b/libcore/tools/runner/java/vogar/target/TestRunner.java
@@ -75,7 +75,7 @@
         }
     }
 
-    public void run() {
+    public void run(String[] args) {
         final TargetMonitor monitor = new TargetMonitor();
         monitor.await(monitorPort);
 
@@ -97,7 +97,7 @@
             throw new RuntimeException(e);
         }
         runner.init(monitor, qualifiedName, testClass);
-        runner.run(qualifiedName, testClass);
+        runner.run(qualifiedName, testClass, args);
 
         monitor.close();
     }
@@ -105,9 +105,6 @@
 
 
     public static void main(String[] args) {
-        if (args.length != 0) {
-            throw new RuntimeException("TestRunner doesn't take arguments");
-        }
-        new TestRunner().run();
+        new TestRunner().run(args);
     }
 }
diff --git a/libcore/tools/runner/lib/TestActivity.java b/libcore/tools/runner/lib/TestActivity.java
index 6e6d09f..39a6575 100644
--- a/libcore/tools/runner/lib/TestActivity.java
+++ b/libcore/tools/runner/lib/TestActivity.java
@@ -48,7 +48,7 @@
                 1, Threads.daemonThreadFactory());
         executor.submit(new Runnable() {
             public void run() {
-                new TestRunner().run();
+                new TestRunner().run(args);
             }
         });
         executor.shutdown();