summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/am/proto/instrumentation_data.proto1
-rw-r--r--cmds/am/src/com/android/commands/am/Instrument.java72
-rw-r--r--tools/bit/main.cpp10
3 files changed, 75 insertions, 8 deletions
diff --git a/cmds/am/proto/instrumentation_data.proto b/cmds/am/proto/instrumentation_data.proto
index 8e29f9645568..23e951992305 100644
--- a/cmds/am/proto/instrumentation_data.proto
+++ b/cmds/am/proto/instrumentation_data.proto
@@ -38,6 +38,7 @@ message ResultsBundle {
message TestStatus {
optional sint32 result_code = 3;
optional ResultsBundle results = 4;
+ optional string logcat = 5;
}
enum SessionStatusCode {
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 70baa8702ba9..4d7b5a79b4f7 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -38,6 +38,7 @@ import android.view.IWindowManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -62,8 +63,15 @@ import java.util.Locale;
* other: Failure
*/
public class Instrument {
+ private static final String TAG = "am";
+
public static final String DEFAULT_LOG_DIR = "instrument-logs";
+ private static final int STATUS_TEST_PASSED = 0;
+ private static final int STATUS_TEST_STARTED = 1;
+ private static final int STATUS_TEST_FAILED_ASSERTION = -1;
+ private static final int STATUS_TEST_FAILED_OTHER = -2;
+
private final IActivityManager mAm;
private final IPackageManager mPm;
private final IWindowManager mWm;
@@ -207,6 +215,8 @@ public class Instrument {
private File mLog;
+ private long mTestStartMs;
+
ProtoStatusReporter() {
if (protoFile) {
if (logPath == null) {
@@ -241,10 +251,22 @@ public class Instrument {
Bundle results) {
final ProtoOutputStream proto = new ProtoOutputStream();
- final long token = proto.start(InstrumentationData.Session.TEST_STATUS);
+ final long testStatusToken = proto.start(InstrumentationData.Session.TEST_STATUS);
+
proto.write(InstrumentationData.TestStatus.RESULT_CODE, resultCode);
writeBundle(proto, InstrumentationData.TestStatus.RESULTS, results);
- proto.end(token);
+
+ if (resultCode == STATUS_TEST_STARTED) {
+ // Logcat -T takes wall clock time (!?)
+ mTestStartMs = System.currentTimeMillis();
+ } else {
+ if (mTestStartMs > 0) {
+ proto.write(InstrumentationData.TestStatus.LOGCAT, readLogcat(mTestStartMs));
+ }
+ mTestStartMs = 0;
+ }
+
+ proto.end(testStatusToken);
outputProto(proto);
}
@@ -254,12 +276,12 @@ public class Instrument {
Bundle results) {
final ProtoOutputStream proto = new ProtoOutputStream();
- final long token = proto.start(InstrumentationData.Session.SESSION_STATUS);
+ final long sessionStatusToken = proto.start(InstrumentationData.Session.SESSION_STATUS);
proto.write(InstrumentationData.SessionStatus.STATUS_CODE,
InstrumentationData.SESSION_FINISHED);
proto.write(InstrumentationData.SessionStatus.RESULT_CODE, resultCode);
writeBundle(proto, InstrumentationData.SessionStatus.RESULTS, results);
- proto.end(token);
+ proto.end(sessionStatusToken);
outputProto(proto);
}
@@ -268,11 +290,11 @@ public class Instrument {
public void onError(String errorText, boolean commandError) {
final ProtoOutputStream proto = new ProtoOutputStream();
- final long token = proto.start(InstrumentationData.Session.SESSION_STATUS);
+ final long sessionStatusToken = proto.start(InstrumentationData.Session.SESSION_STATUS);
proto.write(InstrumentationData.SessionStatus.STATUS_CODE,
InstrumentationData.SESSION_ABORTED);
proto.write(InstrumentationData.SessionStatus.ERROR_TEXT, errorText);
- proto.end(token);
+ proto.end(sessionStatusToken);
outputProto(proto);
}
@@ -514,5 +536,43 @@ public class Instrument {
}
}
}
+
+ private static String readLogcat(long startTimeMs) {
+ try {
+ // Figure out the timestamp arg for logcat.
+ final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ final String timestamp = format.format(new Date(startTimeMs));
+
+ // Start the process
+ final Process process = new ProcessBuilder()
+ .command("logcat", "-d", "-v threadtime,uid", "-T", timestamp)
+ .start();
+
+ // Nothing to write. Don't let the command accidentally block.
+ process.getOutputStream().close();
+
+ // Read the output
+ final StringBuilder str = new StringBuilder();
+ final InputStreamReader reader = new InputStreamReader(process.getInputStream());
+ char[] buffer = new char[4096];
+ int amt;
+ while ((amt = reader.read(buffer, 0, buffer.length)) >= 0) {
+ if (amt > 0) {
+ str.append(buffer, 0, amt);
+ }
+ }
+
+ try {
+ process.waitFor();
+ } catch (InterruptedException ex) {
+ // We already have the text, drop the exception.
+ }
+
+ return str.toString();
+
+ } catch (IOException ex) {
+ return "Error reading logcat command:\n" + ex.toString();
+ }
+ }
}
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index 1a91f52bc6cf..d80c2e742fae 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -290,8 +290,14 @@ TestResults::OnTestStatus(TestStatus& status)
m_currentAction->target->name.c_str(), className.c_str(),
testName.c_str(), g_escapeEndColor);
- string stack = get_bundle_string(results, &found, "stack", NULL);
- if (found) {
+ bool stackFound;
+ string stack = get_bundle_string(results, &stackFound, "stack", NULL);
+ if (status.has_logcat()) {
+ const string logcat = status.logcat();
+ if (logcat.length() > 0) {
+ printf("%s\n", logcat.c_str());
+ }
+ } else if (stackFound) {
printf("%s\n", stack.c_str());
}
}