Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fc8f1f8 authored by Joe Onorato's avatar Joe Onorato Committed by android-build-merger
Browse files

Merge "Make am instrument capture logcat during test run, and return it to the host." into qt-dev

am: e587f53c

Change-Id: I04ff3bcfe64394cbbf431a71451b52290ba6016b
parents de4d1240 e587f53c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ message ResultsBundle {
message TestStatus {
    optional sint32 result_code = 3;
    optional ResultsBundle results = 4;
    optional string logcat = 5;
}

enum SessionStatusCode {
+66 −6
Original line number Diff line number Diff line
@@ -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();
        }
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -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());
        }
    }