- Improve ScriptRunner command line parsing to actually pass more of the arguments. (And a unit test to go with it).
- Set __name__ inside the scriptfile runner so python scripts expecting it get it.
- Propagate sys.exit error codes so monkeyrunner will actually return those error codes.
- Better handle PyExceptions thrown by the script to actually terminate monkeyrunner.
- Bubble up installPackage and removePackage error codes so callers can tell if they worked or not.
Change-Id: Ia4717b1ad2c9b4cccd607aba00211f2f85dfb412
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyDevice.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyDevice.java
index 5f04d64..f8cecc6 100644
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyDevice.java
+++ b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyDevice.java
@@ -170,24 +170,26 @@
@MonkeyRunnerExported(doc = "Install the specified apk onto the device.",
args = { "path" },
- argDocs = { "The path on the host filesystem to the APK to install." })
- public void installPackage(PyObject[] args, String[] kws) {
+ argDocs = { "The path on the host filesystem to the APK to install." },
+ returns = "True if install succeeded")
+ public boolean installPackage(PyObject[] args, String[] kws) {
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
String path = ap.getString(0);
- installPackage(path);
+ return installPackage(path);
}
@MonkeyRunnerExported(doc = "Remove the specified package from the device.",
args = { "package"},
- argDocs = { "The name of the package to uninstall"})
- public void removePackage(PyObject[] args, String[] kws) {
+ argDocs = { "The name of the package to uninstall"},
+ returns = "'True if remove succeeded")
+ public boolean removePackage(PyObject[] args, String[] kws) {
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
String packageName = ap.getString(0);
- removePackage(packageName);
+ return removePackage(packageName);
}
@MonkeyRunnerExported(doc = "Start the Activity specified by the intent.",
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerOptions.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerOptions.java
index 68577a5..0586045 100644
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerOptions.java
+++ b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerOptions.java
@@ -150,7 +150,9 @@
}
pluginListBuilder.add(plugin);
- } else if (argument.startsWith("-")) {
+ } else if (argument.startsWith("-") &&
+ // Once we have the scriptfile, the rest of the arguments go to jython.
+ scriptFile == null) {
// we have an unrecognized argument.
printUsage("Unrecognized argument: " + argument + ".");
return null;
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerStarter.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerStarter.java
index 54bb7da..8c32408 100644
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerStarter.java
+++ b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunnerStarter.java
@@ -78,13 +78,14 @@
}
}
- private void run() {
+ private int run() {
MonkeyRunner.setBackend(backend);
Map<String, Predicate<PythonInterpreter>> plugins = handlePlugins();
- ScriptRunner.run(options.getScriptFile().getAbsolutePath(),
- options.getArguments(), plugins);
+ int error = ScriptRunner.run(options.getScriptFile().getAbsolutePath(),
+ options.getArguments(), plugins);
backend.shutdown();
MonkeyRunner.setBackend(null);
+ return error;
}
private Predicate<PythonInterpreter> handlePlugin(File f) {
@@ -189,9 +190,9 @@
}
MonkeyRunnerStarter runner = new MonkeyRunnerStarter(options);
- runner.run();
+ int error = runner.run();
// This will kill any background threads as well.
- System.exit(0);
+ System.exit(error);
}
}
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java b/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
index 7920e50..616ba85 100644
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
+++ b/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
@@ -20,6 +20,8 @@
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableMap.Builder;
+import org.python.core.Py;
+import org.python.core.PyException;
import org.python.core.PyObject;
import org.python.util.InteractiveConsole;
import org.python.util.PythonInterpreter;
@@ -64,8 +66,9 @@
* @param scriptfilename the name of the file to run.
* @param args the arguments passed in (excluding the filename).
* @param plugins a list of plugins to load.
+ * @return the error code from running the script.
*/
- public static void run(String scriptfilename, Collection<String> args,
+ public static int run(String scriptfilename, Collection<String> args,
Map<String, Predicate<PythonInterpreter>> plugins) {
// Add the current directory of the script to the python.path search path.
File f = new File(scriptfilename);
@@ -99,7 +102,21 @@
}
}
- python.execfile(scriptfilename);
+ // Bind __name__ to __main__ so mains will run
+ python.set("__name__", "__main__");
+
+ try {
+ python.execfile(scriptfilename);
+ } catch (PyException e) {
+ if (Py.SystemExit.equals(e.type)) {
+ // Then recover the error code so we can pass it on
+ return (Integer) e.value.__tojava__(Integer.class);
+ }
+ // Then some other kind of exception was thrown. Log it and return error;
+ LOG.log(Level.SEVERE, "Script terminated due to an exception", e);
+ return 1;
+ }
+ return 0;
}
public static void runString(String script) {
diff --git a/tools/monkeyrunner/test/com/android/monkeyrunner/AllTests.java b/tools/monkeyrunner/test/com/android/monkeyrunner/AllTests.java
index c5f0d67..645360e 100644
--- a/tools/monkeyrunner/test/com/android/monkeyrunner/AllTests.java
+++ b/tools/monkeyrunner/test/com/android/monkeyrunner/AllTests.java
@@ -35,7 +35,8 @@
public static void main(String args[]) {
TestRunner tr = new TestRunner();
- TestResult result = tr.doRun(AllTests.suite(ImageUtilsTest.class, JythonUtilsTest.class));
+ TestResult result = tr.doRun(AllTests.suite(ImageUtilsTest.class, JythonUtilsTest.class,
+ MonkeyRunnerOptionsTest.class));
if (result.wasSuccessful()) {
System.exit(0);
} else {
diff --git a/tools/monkeyrunner/test/com/android/monkeyrunner/MonkeyRunnerOptionsTest.java b/tools/monkeyrunner/test/com/android/monkeyrunner/MonkeyRunnerOptionsTest.java
new file mode 100644
index 0000000..0852c0b
--- /dev/null
+++ b/tools/monkeyrunner/test/com/android/monkeyrunner/MonkeyRunnerOptionsTest.java
@@ -0,0 +1,56 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+
+package com.android.monkeyrunner;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.util.Iterator;
+
+/**
+ * Unit Tests to test command line argument parsing.
+ */
+public class MonkeyRunnerOptionsTest extends TestCase {
+ // We need to use a file that actually exists
+ private static final String FILENAME = "/etc/passwd";
+
+ public void testSimpleArgs() {
+ MonkeyRunnerOptions options =
+ MonkeyRunnerOptions.processOptions(new String[] { FILENAME });
+ assertEquals(options.getScriptFile(), new File(FILENAME));
+ }
+
+ public void testParsingArgsBeforeScriptName() {
+ MonkeyRunnerOptions options =
+ MonkeyRunnerOptions.processOptions(new String[] { "-be", "stub", FILENAME});
+ assertEquals("stub", options.getBackendName());
+ assertEquals(options.getScriptFile(), new File(FILENAME));
+ }
+
+ public void testParsingScriptArgument() {
+ MonkeyRunnerOptions options =
+ MonkeyRunnerOptions.processOptions(new String[] { FILENAME, "arg1", "arg2" });
+ assertEquals(options.getScriptFile(), new File(FILENAME));
+ Iterator<String> i = options.getArguments().iterator();
+ assertEquals("arg1", i.next());
+ assertEquals("arg2", i.next());
+ }
+
+ public void testParsingScriptArgumentWithDashes() {
+ MonkeyRunnerOptions options =
+ MonkeyRunnerOptions.processOptions(new String[] { FILENAME, "--arg1" });
+ assertEquals(options.getScriptFile(), new File(FILENAME));
+ assertEquals("--arg1", options.getArguments().iterator().next());
+ }
+
+ public void testMixedArgs() {
+ MonkeyRunnerOptions options =
+ MonkeyRunnerOptions.processOptions(new String[] { "-be", "stub", FILENAME,
+ "arg1", "--debug=True"});
+ assertEquals("stub", options.getBackendName());
+ assertEquals(options.getScriptFile(), new File(FILENAME));
+ Iterator<String> i = options.getArguments().iterator();
+ assertEquals("arg1", i.next());
+ assertEquals("--debug=True", i.next());
+ }
+}