aboutsummaryrefslogtreecommitdiffstats
path: root/ddms/libs/ddmlib
diff options
context:
space:
mode:
Diffstat (limited to 'ddms/libs/ddmlib')
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/Client.java2
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/Device.java75
-rwxr-xr-xddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java10
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java63
-rwxr-xr-xddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java328
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java65
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java76
-rw-r--r--ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java49
-rw-r--r--ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java60
9 files changed, 285 insertions, 443 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
index 866d578..a4576aa 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
@@ -94,7 +94,7 @@ public class Client {
* is only used for data generated within Client.
*/
private static final int INITIAL_BUF_SIZE = 2*1024;
- private static final int MAX_BUF_SIZE = 200*1024*1024;
+ private static final int MAX_BUF_SIZE = 2*1024*1024;
private ByteBuffer mReadBuffer;
private static final int WRITE_BUF_SIZE = 256;
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
index 0e7f0bb..34ef432 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
@@ -30,7 +30,7 @@ import java.util.Map;
/**
* A Device. It can be a physical device or an emulator.
- *
+ *
* TODO: make this class package-protected, and shift all callers to use IDevice
*/
public final class Device implements IDevice {
@@ -62,10 +62,10 @@ public final class Device implements IDevice {
return null;
}
}
-
+
/** Emulator Serial Number regexp. */
final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$
-
+
/** Serial number of the device */
String serialNumber = null;
@@ -74,7 +74,7 @@ public final class Device implements IDevice {
/** State of the device. */
DeviceState state = null;
-
+
/** Device properties. */
private final Map<String, String> mProperties = new HashMap<String, String>();
@@ -85,29 +85,29 @@ public final class Device implements IDevice {
* Socket for the connection monitoring client connection/disconnection.
*/
private SocketChannel mSocketChannel;
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getSerialNumber()
*/
public String getSerialNumber() {
return serialNumber;
}
-
+
public String getAvdName() {
return mAvdName;
}
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getState()
*/
public DeviceState getState() {
return state;
}
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getProperties()
*/
@@ -115,7 +115,7 @@ public final class Device implements IDevice {
return Collections.unmodifiableMap(mProperties);
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getPropertyCount()
*/
@@ -123,21 +123,21 @@ public final class Device implements IDevice {
return mProperties.size();
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getProperty(java.lang.String)
*/
public String getProperty(String name) {
return mProperties.get(name);
}
-
+
@Override
public String toString() {
return serialNumber;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#isOnline()
*/
@@ -145,7 +145,7 @@ public final class Device implements IDevice {
return state == DeviceState.ONLINE;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#isEmulator()
*/
@@ -153,7 +153,7 @@ public final class Device implements IDevice {
return serialNumber.matches(RE_EMULATOR_SN);
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#isOffline()
*/
@@ -161,7 +161,7 @@ public final class Device implements IDevice {
return state == DeviceState.OFFLINE;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#isBootLoader()
*/
@@ -169,7 +169,7 @@ public final class Device implements IDevice {
return state == DeviceState.BOOTLOADER;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#hasClients()
*/
@@ -177,7 +177,7 @@ public final class Device implements IDevice {
return mClients.size() > 0;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getClients()
*/
@@ -186,8 +186,8 @@ public final class Device implements IDevice {
return mClients.toArray(new Client[mClients.size()]);
}
}
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getClient(java.lang.String)
*/
@@ -204,7 +204,7 @@ public final class Device implements IDevice {
return null;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getSyncService()
*/
@@ -217,7 +217,7 @@ public final class Device implements IDevice {
return null;
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getFileListingService()
*/
@@ -225,7 +225,7 @@ public final class Device implements IDevice {
return new FileListingService(this);
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getScreenshot()
*/
@@ -233,7 +233,7 @@ public final class Device implements IDevice {
return AdbHelper.getFrameBuffer(AndroidDebugBridge.sSocketAddr, this);
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#executeShellCommand(java.lang.String, com.android.ddmlib.IShellOutputReceiver)
*/
@@ -242,25 +242,16 @@ public final class Device implements IDevice {
AdbHelper.executeRemoteCommand(AndroidDebugBridge.sSocketAddr, command, this,
receiver);
}
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#runEventLogService(com.android.ddmlib.log.LogReceiver)
*/
public void runEventLogService(LogReceiver receiver) throws IOException {
AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver);
}
-
- /*
- * (non-Javadoc)
- * @see com.android.ddmlib.IDevice#runLogService(com.android.ddmlib.log.LogReceiver)
- */
- public void runLogService(String logname,
- LogReceiver receiver) throws IOException {
- AdbHelper.runLogService(AndroidDebugBridge.sSocketAddr, this, logname, receiver);
- }
-
- /*
+
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#createForward(int, int)
*/
@@ -274,7 +265,7 @@ public final class Device implements IDevice {
}
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#removeForward(int, int)
*/
@@ -288,7 +279,7 @@ public final class Device implements IDevice {
}
}
- /*
+ /*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getClientName(int)
*/
@@ -334,7 +325,7 @@ public final class Device implements IDevice {
return false;
}
-
+
void clearClientList() {
synchronized (mClients) {
mClients.clear();
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
index 5dbce92..664b0c9 100755
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
@@ -44,7 +44,7 @@ public interface IDevice {
* Returns the serial number of the device.
*/
public String getSerialNumber();
-
+
/**
* Returns the name of the AVD the emulator is running.
* <p/>This is only valid if {@link #isEmulator()} returns true.
@@ -152,14 +152,6 @@ public interface IDevice {
public void runEventLogService(LogReceiver receiver) throws IOException;
/**
- * Runs the log service for the given log and outputs the log to the {@link LogReceiver}.
- * @param logname the logname of the log to read from.
- * @param receiver the receiver to receive the event log entries.
- * @throws IOException
- */
- public void runLogService(String logname, LogReceiver receiver) throws IOException;
-
- /**
* Creates a port forwarding between a local and a remote port.
* @param localPort the local port to forward
* @param remotePort the remote port.
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
index b61a698..4c0d9de 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
@@ -17,69 +17,56 @@
package com.android.ddmlib.testrunner;
/**
- * Receives event notifications during instrumentation test runs.
- * Patterned after {@link junit.runner.TestRunListener}.
+ * Listener for instrumentation test runs
+ *
+ * Modeled after junit.runner.TestRunListener
*/
public interface ITestRunListener {
-
- /**
- * Types of test failures.
- */
- enum TestFailure {
- /** Test failed due to unanticipated uncaught exception. */
- ERROR,
- /** Test failed due to a false assertion. */
- FAILURE
- }
+ public static final int STATUS_ERROR = 1;
+ public static final int STATUS_FAILURE = 2;
/**
- * Reports the start of a test run.
- *
- * @param testCount total number of tests in test run
- */
+ * Reports the start of a test run
+ * @param testCount - total number of tests in test run
+ * */
public void testRunStarted(int testCount);
/**
- * Reports end of test run.
- *
- * @param elapsedTime device reported elapsed time, in milliseconds
+ * Reports end of test run
+ * @param elapsedTime - device reported elapsed time, in milliseconds
*/
public void testRunEnded(long elapsedTime);
/**
- * Reports test run stopped before completion.
- *
- * @param elapsedTime device reported elapsed time, in milliseconds
+ * Reports test run stopped before completion
+ * @param elapsedTime - device reported elapsed time, in milliseconds
*/
public void testRunStopped(long elapsedTime);
/**
- * Reports the start of an individual test case.
- *
- * @param test identifies the test
+ * Reports the start of an individual test case
*/
- public void testStarted(TestIdentifier test);
+ public void testStarted(String className, String testName);
/**
- * Reports the execution end of an individual test case.
- * If {@link #testFailed} was not invoked, this test passed.
- *
- * @param test identifies the test
+ * Reports the execution end of an individual test case
+ * If no testFailed has been reported, this is a passed test
*/
- public void testEnded(TestIdentifier test);
+ public void testEnded(String className, String testName);
/**
- * Reports the failure of a individual test case.
- * Will be called between testStarted and testEnded.
+ * Reports the failure of a individual test case
+ * Will be called between testStarted and testEnded
*
- * @param status failure type
- * @param test identifies the test
- * @param trace stack trace of failure
+ * @param status - one of STATUS_ERROR, STATUS_FAILURE
+ * @param className - name of test class
+ * @param testName - name of test method
+ * @param trace - stack trace of failure
*/
- public void testFailed(TestFailure status, TestIdentifier test, String trace);
+ public void testFailed(int status, String className, String testName, String trace);
/**
- * Reports test run failed to execute due to a fatal error.
+ * Reports test run failed to execute due to a fatal error
*/
public void testRunFailed(String errorMessage);
}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
index bc1834f..d47bd56 100755
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
@@ -20,21 +20,24 @@ import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
+import java.util.Hashtable;
+import java.util.Map;
+
/**
- * Parses the 'raw output mode' results of an instrumentation test run from shell and informs a
- * ITestRunListener of the results.
+ * Parses the 'raw output mode' results of an instrument test run from shell, and informs a
+ * ITestRunListener of the results
*
- * <p>Expects the following output:
+ * Expects the following output:
*
- * <p>If fatal error occurred when attempted to run the tests:
- * <pre> INSTRUMENTATION_FAILED: </pre>
+ * If fatal error occurred when attempted to run the tests:
+ * <i> INSTRUMENTATION_FAILED: </i>
*
- * <p>Otherwise, expect a series of test results, each one containing a set of status key/value
+ * Otherwise, expect a series of test results, each one containing a set of status key/value
* pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test
* run, expects that the elapsed test time in seconds will be displayed
*
- * <p>For example:
- * <pre>
+ * i.e.
+ * <i>
* INSTRUMENTATION_STATUS_CODE: 1
* INSTRUMENTATION_STATUS: class=com.foo.FooTest
* INSTRUMENTATION_STATUS: test=testFoo
@@ -45,85 +48,64 @@ import com.android.ddmlib.MultiLineReceiver;
* ...
*
* Time: X
- * </pre>
- * <p>Note that the "value" portion of the key-value pair may wrap over several text lines
+ * </i>
+ *
+ * Note that the "value" portion of the key-value pair may wrap over several text lines
*/
public class InstrumentationResultParser extends MultiLineReceiver {
- /** Relevant test status keys. */
- private static class StatusKeys {
- private static final String TEST = "test";
- private static final String CLASS = "class";
- private static final String STACK = "stack";
- private static final String NUMTESTS = "numtests";
- }
+ // relevant test status keys
+ private static final String CODE_KEY = "code";
+ private static final String TEST_KEY = "test";
+ private static final String CLASS_KEY = "class";
+ private static final String STACK_KEY = "stack";
+ private static final String NUMTESTS_KEY = "numtests";
- /** Test result status codes. */
- private static class StatusCodes {
- private static final int FAILURE = -2;
- private static final int START = 1;
- private static final int ERROR = -1;
- private static final int OK = 0;
- }
+ // test result status codes
+ private static final int FAILURE_STATUS_CODE = -2;
+ private static final int START_STATUS_CODE = 1;
+ private static final int ERROR_STATUS_CODE = -1;
+ private static final int OK_STATUS_CODE = 0;
- /** Prefixes used to identify output. */
- private static class Prefixes {
- private static final String STATUS = "INSTRUMENTATION_STATUS: ";
- private static final String STATUS_CODE = "INSTRUMENTATION_STATUS_CODE: ";
- private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
- private static final String TIME_REPORT = "Time: ";
- }
+ // recognized output patterns
+ private static final String STATUS_PREFIX = "INSTRUMENTATION_STATUS: ";
+ private static final String STATUS_PREFIX_CODE = "INSTRUMENTATION_STATUS_CODE: ";
+ private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
+ private static final String TIME_REPORT = "Time: ";
private final ITestRunListener mTestListener;
-
- /**
- * Test result data
- */
- private static class TestResult {
- private Integer mCode = null;
- private String mTestName = null;
- private String mTestClass = null;
- private String mStackTrace = null;
- private Integer mNumTests = null;
-
- /** Returns true if all expected values have been parsed */
- boolean isComplete() {
- return mCode != null && mTestName != null && mTestClass != null;
- }
- }
-
- /** Stores the status values for the test result currently being parsed */
- private TestResult mCurrentTestResult = null;
-
- /** Stores the current "key" portion of the status key-value being parsed. */
- private String mCurrentKey = null;
-
- /** Stores the current "value" portion of the status key-value being parsed. */
- private StringBuilder mCurrentValue = null;
-
- /** True if start of test has already been reported to listener. */
- private boolean mTestStartReported = false;
-
- /** The elapsed time of the test run, in milliseconds. */
- private long mTestTime = 0;
-
- /** True if current test run has been canceled by user. */
- private boolean mIsCancelled = false;
+ /** key-value map for current test */
+ private Map<String, String> mStatusValues;
+ /** stores the current "key" portion of the status key-value being parsed */
+ private String mCurrentKey;
+ /** stores the current "value" portion of the status key-value being parsed */
+ private StringBuilder mCurrentValue;
+ /** true if start of test has already been reported to listener */
+ private boolean mTestStartReported;
+ /** the elapsed time of the test run, in ms */
+ private long mTestTime;
+ /** true if current test run has been canceled by user */
+ private boolean mIsCancelled;
private static final String LOG_TAG = "InstrumentationResultParser";
/**
- * Creates the InstrumentationResultParser.
- *
- * @param listener informed of test results as the tests are executing
+ * Creates the InstrumentationResultParser
+ * @param listener - listener to report results to. will be informed of test results as the
+ * tests are executing
*/
public InstrumentationResultParser(ITestRunListener listener) {
+ mStatusValues = new Hashtable<String, String>();
+ mCurrentKey = null;
+ setTrimLine(false);
mTestListener = listener;
+ mTestStartReported = false;
+ mTestTime = 0;
+ mIsCancelled = false;
}
/**
- * Processes the instrumentation test output from shell.
- *
+ * Processes the instrumentation test output from shell
* @see MultiLineReceiver#processNewLines
*/
@Override
@@ -134,37 +116,31 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Parse an individual output line. Expects a line that is one of:
- * <ul>
- * <li>
- * The start of a new status line (starts with Prefixes.STATUS or Prefixes.STATUS_CODE),
- * and thus there is a new key=value pair to parse, and the previous key-value pair is
- * finished.
- * </li>
- * <li>
- * A continuation of the previous status (the "value" portion of the key has wrapped
- * to the next line).
- * </li>
- * <li> A line reporting a fatal error in the test run (Prefixes.STATUS_FAILED) </li>
- * <li> A line reporting the total elapsed time of the test run. (Prefixes.TIME_REPORT) </li>
- * </ul>
+ * Parse an individual output line. Expects a line that either is:
+ * a) the start of a new status line (ie. starts with STATUS_PREFIX or STATUS_PREFIX_CODE),
+ * and thus there is a new key=value pair to parse, and the previous key-value pair is
+ * finished
+ * b) a continuation of the previous status (ie the "value" portion of the key has wrapped
+ * to the next line.
+ * c) a line reporting a fatal error in the test run (STATUS_FAILED)
+ * d) a line reporting the total elapsed time of the test run.
*
- * @param line Text output line
+ * @param line - text output line
*/
private void parse(String line) {
- if (line.startsWith(Prefixes.STATUS_CODE)) {
+ if (line.startsWith(STATUS_PREFIX_CODE)) {
// Previous status key-value has been collected. Store it.
submitCurrentKeyValue();
parseStatusCode(line);
- } else if (line.startsWith(Prefixes.STATUS)) {
+ } else if (line.startsWith(STATUS_PREFIX)) {
// Previous status key-value has been collected. Store it.
submitCurrentKeyValue();
- parseKey(line, Prefixes.STATUS.length());
- } else if (line.startsWith(Prefixes.STATUS_FAILED)) {
+ parseKey(line, STATUS_PREFIX.length());
+ } else if (line.startsWith(STATUS_FAILED)) {
Log.e(LOG_TAG, "test run failed " + line);
mTestListener.testRunFailed(line);
- } else if (line.startsWith(Prefixes.TIME_REPORT)) {
- parseTime(line, Prefixes.TIME_REPORT.length());
+ } else if (line.startsWith(TIME_REPORT)) {
+ parseTime(line, TIME_REPORT.length());
} else {
if (mCurrentValue != null) {
// this is a value that has wrapped to next line.
@@ -177,53 +153,21 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Stores the currently parsed key-value pair into mCurrentTestInfo.
+ * Stores the currently parsed key-value pair in the status map
*/
private void submitCurrentKeyValue() {
if (mCurrentKey != null && mCurrentValue != null) {
- TestResult testInfo = getCurrentTestInfo();
- String statusValue = mCurrentValue.toString();
-
- if (mCurrentKey.equals(StatusKeys.CLASS)) {
- testInfo.mTestClass = statusValue.trim();
- }
- else if (mCurrentKey.equals(StatusKeys.TEST)) {
- testInfo.mTestName = statusValue.trim();
- }
- else if (mCurrentKey.equals(StatusKeys.NUMTESTS)) {
- try {
- testInfo.mNumTests = Integer.parseInt(statusValue);
- }
- catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Unexpected integer number of tests, received " + statusValue);
- }
- }
- else if (mCurrentKey.equals(StatusKeys.STACK)) {
- testInfo.mStackTrace = statusValue;
- }
-
+ mStatusValues.put(mCurrentKey, mCurrentValue.toString());
mCurrentKey = null;
mCurrentValue = null;
}
}
- private TestResult getCurrentTestInfo() {
- if (mCurrentTestResult == null) {
- mCurrentTestResult = new TestResult();
- }
- return mCurrentTestResult;
- }
-
- private void clearCurrentTestInfo() {
- mCurrentTestResult = null;
- }
-
/**
- * Parses the key from the current line.
- * Expects format of "key=value".
- *
- * @param line full line of text to parse
- * @param keyStartPos the starting position of the key in the given line
+ * Parses the key from the current line
+ * Expects format of "key=value",
+ * @param line - full line of text to parse
+ * @param keyStartPos - the starting position of the key in the given line
*/
private void parseKey(String line, int keyStartPos) {
int endKeyPos = line.indexOf('=', keyStartPos);
@@ -234,8 +178,7 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Parses the start of a key=value pair.
- *
+ * Parses the start of a key=value pair.
* @param line - full line of text to parse
* @param valueStartPos - the starting position of the value in the given line
*/
@@ -245,25 +188,20 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Parses out a status code result.
+ * Parses out a status code result. For consistency, stores the result as a CODE entry in
+ * key-value status map
*/
private void parseStatusCode(String line) {
- String value = line.substring(Prefixes.STATUS_CODE.length()).trim();
- TestResult testInfo = getCurrentTestInfo();
- try {
- testInfo.mCode = Integer.parseInt(value);
- }
- catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Expected integer status code, received: " + value);
- }
+ String value = line.substring(STATUS_PREFIX_CODE.length()).trim();
+ mStatusValues.put(CODE_KEY, value);
// this means we're done with current test result bundle
- reportResult(testInfo);
- clearCurrentTestInfo();
+ reportResult(mStatusValues);
+ mStatusValues.clear();
}
/**
- * Returns true if test run canceled.
+ * Returns true if test run canceled
*
* @see IShellOutputReceiver#isCancelled()
*/
@@ -272,7 +210,7 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Requests cancellation of test run.
+ * Requests cancellation of test result parsing
*/
public void cancel() {
mIsCancelled = true;
@@ -281,62 +219,82 @@ public class InstrumentationResultParser extends MultiLineReceiver {
/**
* Reports a test result to the test run listener. Must be called when a individual test
* result has been fully parsed.
- *
- * @param statusMap key-value status pairs of test result
+ * @param statusMap - key-value status pairs of test result
*/
- private void reportResult(TestResult testInfo) {
- if (!testInfo.isComplete()) {
- Log.e(LOG_TAG, "invalid instrumentation status bundle " + testInfo.toString());
+ private void reportResult(Map<String, String> statusMap) {
+ String className = statusMap.get(CLASS_KEY);
+ String testName = statusMap.get(TEST_KEY);
+ String statusCodeString = statusMap.get(CODE_KEY);
+
+ if (className == null || testName == null || statusCodeString == null) {
+ Log.e(LOG_TAG, "invalid instrumentation status bundle " + statusMap.toString());
return;
}
- reportTestRunStarted(testInfo);
- TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
+ className = className.trim();
+ testName = testName.trim();
- switch (testInfo.mCode) {
- case StatusCodes.START:
- mTestListener.testStarted(testId);
- break;
- case StatusCodes.FAILURE:
- mTestListener.testFailed(ITestRunListener.TestFailure.FAILURE, testId,
- getTrace(testInfo));
- mTestListener.testEnded(testId);
- break;
- case StatusCodes.ERROR:
- mTestListener.testFailed(ITestRunListener.TestFailure.ERROR, testId,
- getTrace(testInfo));
- mTestListener.testEnded(testId);
- break;
- case StatusCodes.OK:
- mTestListener.testEnded(testId);
- break;
- default:
- Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
- mTestListener.testEnded(testId);
- break;
+ reportTestStarted(statusMap);
+
+ try {
+ int statusCode = Integer.parseInt(statusCodeString);
+
+ switch (statusCode) {
+ case START_STATUS_CODE:
+ mTestListener.testStarted(className, testName);
+ break;
+ case FAILURE_STATUS_CODE:
+ mTestListener.testFailed(ITestRunListener.STATUS_FAILURE, className, testName,
+ getTrace(statusMap));
+ mTestListener.testEnded(className, testName);
+ break;
+ case ERROR_STATUS_CODE:
+ mTestListener.testFailed(ITestRunListener.STATUS_ERROR, className, testName,
+ getTrace(statusMap));
+ mTestListener.testEnded(className, testName);
+ break;
+ case OK_STATUS_CODE:
+ mTestListener.testEnded(className, testName);
+ break;
+ default:
+ Log.e(LOG_TAG, "Expected status code, received: " + statusCodeString);
+ mTestListener.testEnded(className, testName);
+ break;
+ }
+ }
+ catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "Expected integer status code, received: " + statusCodeString);
}
-
}
/**
* Reports the start of a test run, and the total test count, if it has not been previously
- * reported.
- *
- * @param testInfo current test status values
+ * reported
+ * @param statusMap - key-value status pairs
*/
- private void reportTestRunStarted(TestResult testInfo) {
+ private void reportTestStarted(Map<String, String> statusMap) {
// if start test run not reported yet
- if (!mTestStartReported && testInfo.mNumTests != null) {
- mTestListener.testRunStarted(testInfo.mNumTests);
- mTestStartReported = true;
+ if (!mTestStartReported) {
+ String numTestsString = statusMap.get(NUMTESTS_KEY);
+ if (numTestsString != null) {
+ try {
+ int numTests = Integer.parseInt(numTestsString);
+ mTestListener.testRunStarted(numTests);
+ mTestStartReported = true;
+ }
+ catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "Unexpected numTests format " + numTestsString);
+ }
+ }
}
}
/**
- * Returns the stack trace of the current failed test, from the provided testInfo.
+ * Returns the stack trace of the current failed test, from the provided key-value status map
*/
- private String getTrace(TestResult testInfo) {
- if (testInfo.mStackTrace != null) {
- return testInfo.mStackTrace;
+ private String getTrace(Map<String, String> statusMap) {
+ String stackTrace = statusMap.get(STACK_KEY);
+ if (stackTrace != null) {
+ return stackTrace;
}
else {
Log.e(LOG_TAG, "Could not find stack trace for failed test ");
@@ -345,7 +303,7 @@ public class InstrumentationResultParser extends MultiLineReceiver {
}
/**
- * Parses out and store the elapsed time.
+ * Parses out and store the elapsed time
*/
private void parseTime(String line, int startPos) {
String timeString = line.substring(startPos);
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
index 4edbbbb..5de632e 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
@@ -23,7 +23,7 @@ import com.android.ddmlib.Log;
import java.io.IOException;
/**
- * Runs a Android test command remotely and reports results.
+ * Runs a Android test command remotely and reports results
*/
public class RemoteAndroidTestRunner {
@@ -43,12 +43,11 @@ public class RemoteAndroidTestRunner {
"android.test.InstrumentationTestRunner";
/**
- * Creates a remote Android test runner.
- *
- * @param packageName the Android application package that contains the tests to run
- * @param runnerName the instrumentation test runner to execute. If null, will use default
+ * Creates a remote android test runner.
+ * @param packageName - the Android application package that contains the tests to run
+ * @param runnerName - the instrumentation test runner to execute. If null, will use default
* runner
- * @param remoteDevice the Android device to execute tests on
+ * @param remoteDevice - the Android device to execute tests on
*/
public RemoteAndroidTestRunner(String packageName,
String runnerName,
@@ -63,10 +62,9 @@ public class RemoteAndroidTestRunner {
}
/**
- * Alternate constructor. Uses default instrumentation runner.
- *
- * @param packageName the Android application package that contains the tests to run
- * @param remoteDevice the Android device to execute tests on
+ * Alternate constructor. Uses default instrumentation runner
+ * @param packageName - the Android application package that contains the tests to run
+ * @param remoteDevice - the Android device to execute tests on
*/
public RemoteAndroidTestRunner(String packageName,
IDevice remoteDevice) {
@@ -74,14 +72,14 @@ public class RemoteAndroidTestRunner {
}
/**
- * Returns the application package name.
+ * Returns the application package name
*/
public String getPackageName() {
return mPackageName;
}
/**
- * Returns the runnerName.
+ * Returns the runnerName
*/
public String getRunnerName() {
if (mRunnerName == null) {
@@ -91,7 +89,7 @@ public class RemoteAndroidTestRunner {
}
/**
- * Returns the complete instrumentation component path.
+ * Returns the complete instrumentation component path
*/
private String getRunnerPath() {
return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
@@ -99,9 +97,8 @@ public class RemoteAndroidTestRunner {
/**
* Sets to run only tests in this class
- * Must be called before 'run'.
- *
- * @param className fully qualified class name (eg x.y.z)
+ * Must be called before 'run'
+ * @param className - fully qualified class name (eg x.y.z)
*/
public void setClassName(String className) {
mClassArg = className;
@@ -109,12 +106,10 @@ public class RemoteAndroidTestRunner {
/**
* Sets to run only tests in the provided classes
- * Must be called before 'run'.
- * <p>
+ * Must be called before 'run'
* If providing more than one class, requires a InstrumentationTestRunner that supports
- * the multiple class argument syntax.
- *
- * @param classNames array of fully qualified class names (eg x.y.z)
+ * the multiple class argument syntax
+ * @param classNames - array of fully qualified class name (eg x.y.z)
*/
public void setClassNames(String[] classNames) {
StringBuilder classArgBuilder = new StringBuilder();
@@ -130,10 +125,9 @@ public class RemoteAndroidTestRunner {
/**
* Sets to run only specified test method
- * Must be called before 'run'.
- *
- * @param className fully qualified class name (eg x.y.z)
- * @param testName method name
+ * Must be called before 'run'
+ * @param className - fully qualified class name (eg x.y.z)
+ * @param testName - method name
*/
public void setMethodName(String className, String testName) {
mClassArg = className + METHOD_SEPARATOR + testName;
@@ -141,9 +135,8 @@ public class RemoteAndroidTestRunner {
/**
* Sets extra arguments to include in instrumentation command.
- * Must be called before 'run'.
- *
- * @param instrumentationArgs must not be null
+ * Must be called before 'run'
+ * @param instrumentationArgs - must not be null
*/
public void setExtraArgs(String instrumentationArgs) {
if (instrumentationArgs == null) {
@@ -153,23 +146,23 @@ public class RemoteAndroidTestRunner {
}
/**
- * Returns the extra instrumentation arguments.
+ * Returns the extra instrumentation arguments
*/
public String getExtraArgs() {
return mExtraArgs;
}
/**
- * Sets this test run to log only mode - skips test execution.
+ * Sets this test run to log only mode - skips test execution
*/
public void setLogOnly(boolean logOnly) {
mLogOnlyMode = logOnly;
}
/**
- * Execute this test run.
+ * Execute this test run
*
- * @param listener listens for test results
+ * @param listener - listener to report results to
*/
public void run(ITestRunListener listener) {
final String runCaseCommandStr = "am instrument -w -r "
@@ -186,7 +179,7 @@ public class RemoteAndroidTestRunner {
}
/**
- * Requests cancellation of this test run.
+ * Requests cancellation of this test run
*/
public void cancel() {
if (mParser != null) {
@@ -195,7 +188,7 @@ public class RemoteAndroidTestRunner {
}
/**
- * Returns the test class argument.
+ * Returns the test class argument
*/
private String getClassArg() {
return mClassArg;
@@ -203,7 +196,7 @@ public class RemoteAndroidTestRunner {
/**
* Returns the full instrumentation command which specifies the test classes to execute.
- * Returns an empty string if no classes were specified.
+ * Returns an empty string if no classes were specified
*/
private String getClassCmd() {
String classArg = getClassArg();
@@ -215,7 +208,7 @@ public class RemoteAndroidTestRunner {
/**
* Returns the full command to enable log only mode - if specified. Otherwise returns an
- * empty string.
+ * empty string
*/
private String getLogCmd() {
if (mLogOnlyMode) {
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
deleted file mode 100644
index 4d3b108..0000000
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ddmlib.testrunner;
-
-/**
- * Identifies a parsed instrumentation test
- */
-public class TestIdentifier {
-
- private final String mClassName;
- private final String mTestName;
-
- /**
- * Creates a test identifier
- *
- * @param className fully qualified class name of the test. Cannot be null.
- * @param testName name of the test. Cannot be null.
- */
- public TestIdentifier(String className, String testName) {
- if (className == null || testName == null) {
- throw new IllegalArgumentException("className and testName must " +
- "be non-null");
- }
- mClassName = className;
- mTestName = testName;
- }
-
- /**
- * Returns the fully qualified class name of the test
- */
- public String getClassName() {
- return mClassName;
- }
-
- /**
- * Returns the name of the test
- */
- public String getTestName() {
- return mTestName;
- }
-
- /**
- * Tests equality by comparing class and method name
- */
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof TestIdentifier)) {
- return false;
- }
- TestIdentifier otherTest = (TestIdentifier)other;
- return getClassName().equals(otherTest.getClassName()) &&
- getTestName().equals(otherTest.getTestName());
- }
-
- /**
- * Generates hashCode based on class and method name.
- */
- @Override
- public int hashCode() {
- return getClassName().hashCode() * 31 + getTestName().hashCode();
- }
-}
diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
index 77d10c1..67f6198 100644
--- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
+++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
/**
- * Tests InstrumentationResultParser.
+ * Tests InstrumentationResultParser
*/
public class InstrumentationResultParserTest extends TestCase {
@@ -51,7 +51,7 @@ public class InstrumentationResultParserTest extends TestCase {
/**
* Tests that the test run started and test start events is sent on first
- * bundle received.
+ * bundle received
*/
public void testTestStarted() {
StringBuilder output = buildCommonResult();
@@ -63,7 +63,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * Tests that a single successful test execution.
+ * Tests that a single successful test execution
*/
public void testTestSuccess() {
StringBuilder output = buildCommonResult();
@@ -74,11 +74,11 @@ public class InstrumentationResultParserTest extends TestCase {
injectTestString(output.toString());
assertCommonAttributes();
assertEquals(1, mTestResult.mNumTestsRun);
- assertEquals(null, mTestResult.mTestStatus);
+ assertEquals(0, mTestResult.mTestStatus);
}
/**
- * Test basic parsing of failed test case.
+ * Test basic parsing of failed test case
*/
public void testTestFailed() {
StringBuilder output = buildCommonResult();
@@ -91,12 +91,12 @@ public class InstrumentationResultParserTest extends TestCase {
assertCommonAttributes();
assertEquals(1, mTestResult.mNumTestsRun);
- assertEquals(ITestRunListener.TestFailure.FAILURE, mTestResult.mTestStatus);
+ assertEquals(ITestRunListener.STATUS_FAILURE, mTestResult.mTestStatus);
assertEquals(STACK_TRACE, mTestResult.mTrace);
}
/**
- * Test basic parsing and conversion of time from output.
+ * Test basic parsing and conversion of time from output
*/
public void testTimeParsing() {
final String timeString = "Time: 4.9";
@@ -105,7 +105,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * builds a common test result using TEST_NAME and TEST_CLASS.
+ * builds a common test result using TEST_NAME and TEST_CLASS
*/
private StringBuilder buildCommonResult() {
StringBuilder output = new StringBuilder();
@@ -118,7 +118,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * Adds common status results to the provided output.
+ * Adds common status results to the provided output
*/
private void addCommonStatus(StringBuilder output) {
addStatusKey(output, "stream", "\r\n" + CLASS_NAME);
@@ -130,7 +130,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * Adds a stack trace status bundle to output.
+ * Adds a stack trace status bundle to output
*/
private void addStackTrace(StringBuilder output) {
addStatusKey(output, "stack", STACK_TRACE);
@@ -138,7 +138,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * Helper method to add a status key-value bundle.
+ * Helper method to add a status key-value bundle
*/
private void addStatusKey(StringBuilder outputBuilder, String key,
String value) {
@@ -168,7 +168,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * inject a test string into the result parser.
+ * inject a test string into the result parser
*
* @param result
*/
@@ -185,7 +185,7 @@ public class InstrumentationResultParserTest extends TestCase {
}
/**
- * A specialized test listener that stores a single test events.
+ * A specialized test listener that stores a single test events
*/
private class VerifyingTestResult implements ITestRunListener {
@@ -194,28 +194,29 @@ public class InstrumentationResultParserTest extends TestCase {
int mNumTestsRun;
String mTestName;
long mTestTime;
- TestFailure mTestStatus;
+ int mTestStatus;
String mTrace;
boolean mStopped;
VerifyingTestResult() {
mNumTestsRun = 0;
- mTestStatus = null;
+ mTestStatus = 0;
mStopped = false;
}
- public void testEnded(TestIdentifier test) {
+ public void testEnded(String className, String testName) {
mNumTestsRun++;
- assertEquals("Unexpected class name", mSuiteName, test.getClassName());
- assertEquals("Unexpected test ended", mTestName, test.getTestName());
+ assertEquals("Unexpected class name", mSuiteName, className);
+ assertEquals("Unexpected test ended", mTestName, testName);
}
- public void testFailed(TestFailure status, TestIdentifier test, String trace) {
+ public void testFailed(int status, String className, String testName,
+ String trace) {
mTestStatus = status;
mTrace = trace;
- assertEquals("Unexpected class name", mSuiteName, test.getClassName());
- assertEquals("Unexpected test ended", mTestName, test.getTestName());
+ assertEquals("Unexpected class name", mSuiteName, className);
+ assertEquals("Unexpected test ended", mTestName, testName);
}
public void testRunEnded(long elapsedTime) {
@@ -232,9 +233,9 @@ public class InstrumentationResultParserTest extends TestCase {
mStopped = true;
}
- public void testStarted(TestIdentifier test) {
- mSuiteName = test.getClassName();
- mTestName = test.getTestName();
+ public void testStarted(String className, String testName) {
+ mSuiteName = className;
+ mTestName = testName;
}
public void testRunFailed(String errorMessage) {
diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
index 9acaaf9..54ffae8 100644
--- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
+++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
@@ -31,16 +31,16 @@ import java.io.IOException;
import java.util.Map;
/**
- * Tests RemoteAndroidTestRunner.
+ * Test RemoteAndroidTestRunner.
*/
public class RemoteAndroidTestRunnerTest extends TestCase {
private RemoteAndroidTestRunner mRunner;
private MockDevice mMockDevice;
-
+
private static final String TEST_PACKAGE = "com.test";
private static final String TEST_RUNNER = "com.test.InstrumentationTestRunner";
-
+
/**
* @see junit.framework.TestCase#setUp()
*/
@@ -49,40 +49,40 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
mMockDevice = new MockDevice();
mRunner = new RemoteAndroidTestRunner(TEST_PACKAGE, TEST_RUNNER, mMockDevice);
}
-
+
/**
- * Test the basic case building of the instrumentation runner command with no arguments.
+ * Test the basic case building of the instrumentation runner command with no arguments
*/
public void testRun() {
mRunner.run(new EmptyListener());
- assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER),
+ assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER),
mMockDevice.getLastShellCommand());
}
/**
- * Test the building of the instrumentation runner command with log set.
+ * Test the building of the instrumentation runner command with log set
*/
public void testRunWithLog() {
mRunner.setLogOnly(true);
mRunner.run(new EmptyListener());
- assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE,
+ assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE,
TEST_RUNNER), mMockDevice.getLastShellCommand());
}
/**
- * Test the building of the instrumentation runner command with method set.
+ * Test the building of the instrumentation runner command with method set
*/
public void testRunWithMethod() {
final String className = "FooTest";
final String testName = "fooTest";
mRunner.setMethodName(className, testName);
mRunner.run(new EmptyListener());
- assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className,
+ assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className,
testName, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
}
-
+
/**
- * Test the building of the instrumentation runner command with extra args set.
+ * Test the building of the instrumentation runner command with extra args set
*/
public void testRunWithExtraArgs() {
final String extraArgs = "blah";
@@ -94,37 +94,37 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
/**
- * Assert two strings are equal ignoring whitespace.
+ * Assert two strings are equal ignoring whitespace
*/
private void assertStringsEquals(String str1, String str2) {
String strippedStr1 = str1.replaceAll(" ", "");
String strippedStr2 = str2.replaceAll(" ", "");
assertEquals(strippedStr1, strippedStr2);
}
-
+
/**
- * A dummy device that does nothing except store the provided executed shell command for
- * later retrieval.
+ * A dummy device that does nothing except store the provided executed shell command for
+ * later retrieval
*/
private static class MockDevice implements IDevice {
private String mLastShellCommand;
-
+
/**
- * Stores the provided command for later retrieval from getLastShellCommand.
+ * Stores the provided command for later retrieval from getLastShellCommand
*/
public void executeShellCommand(String command,
IShellOutputReceiver receiver) throws IOException {
mLastShellCommand = command;
}
-
+
/**
- * Get the last command provided to executeShellCommand.
+ * Get the last command provided to executeShellCommand
*/
public String getLastShellCommand() {
return mLastShellCommand;
}
-
+
public boolean createForward(int localPort, int remotePort) {
throw new UnsupportedOperationException();
}
@@ -201,26 +201,22 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
throw new UnsupportedOperationException();
}
- public void runLogService(String logname, LogReceiver receiver) throws IOException {
- throw new UnsupportedOperationException();
- }
-
public String getAvdName() {
return "";
}
}
-
- /**
- * An empty implementation of ITestRunListener.
+
+ /** An empty implementation of TestRunListener
*/
private static class EmptyListener implements ITestRunListener {
- public void testEnded(TestIdentifier test) {
+ public void testEnded(String className, String testName) {
// ignore
}
- public void testFailed(TestFailure status, TestIdentifier test, String trace) {
+ public void testFailed(int status, String className, String testName,
+ String trace) {
// ignore
}
@@ -240,9 +236,9 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
// ignore
}
- public void testStarted(TestIdentifier test) {
+ public void testStarted(String className, String testName) {
// ignore
}
-
+
}
}