Add option logcat-on-failure-size to CTS and GTS

bug:30720850

(cherry-picked from 0e9d107fcfbd3421b7988a4252a9965896019aba)

Change-Id: I91b2996b329b63f4532f633b72356e32058fc04d
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
index 420f51f..8759318 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
@@ -88,6 +88,7 @@
     public static final String SKIP_DEVICE_INFO_OPTION = "skip-device-info";
     public static final String SKIP_PRECONDITIONS_OPTION = "skip-preconditions";
     public static final String DEVICE_TOKEN_OPTION = "device-token";
+    public static final String LOGCAT_ON_FAILURE_SIZE_OPTION = "logcat-on-failure-size";
     private static final String URL = "dynamic-config-url";
 
     /* API Key for compatibility test project, used for dynamic configuration */
@@ -179,6 +180,11 @@
             description = "Take a logcat snapshot on every test failure.")
     private boolean mLogcatOnFailure = false;
 
+    @Option(name = LOGCAT_ON_FAILURE_SIZE_OPTION,
+            description = "The max number of logcat data in bytes to capture when "
+            + "--logcat-on-failure is on. Should be an amount that can comfortably fit in memory.")
+    private int mMaxLogcatBytes = 500 * 1024; // 500K
+
     @Option(name = "screenshot-on-failure",
             description = "Take a screenshot on every test failure.")
     private boolean mScreenshotOnFailure = false;
@@ -309,7 +315,7 @@
             List<IModuleDef> modules = mModuleRepo.getModules(getDevice().getSerialNumber());
 
             listener = new FailureListener(listener, getDevice(), mBugReportOnFailure,
-                    mLogcatOnFailure, mScreenshotOnFailure, mRebootOnFailure);
+                    mLogcatOnFailure, mScreenshotOnFailure, mRebootOnFailure, mMaxLogcatBytes);
             int moduleCount = modules.size();
             CLog.logAndDisplay(LogLevel.INFO, "Starting %d module%s on %s", moduleCount,
                     (moduleCount > 1) ? "s" : "", mDevice.getSerialNumber());
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
index 5d2cd38..cd0e54f 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/FailureListener.java
@@ -27,23 +27,38 @@
 
 public class FailureListener extends ResultForwarder {
 
-    private static final int MAX_LOGCAT_BYTES = 500 * 1024; // 500K
+    private static final int DEFAULT_MAX_LOGCAT_BYTES = 500 * 1024; // 500K
+    /* Arbitrary upper limit for mMaxLogcatBytes, per b/30720850 */
+    public static final int LOGCAT_BYTE_LIMIT = 20 * 1024 * 1024; // 20 MB
 
     private ITestDevice mDevice;
     private boolean mBugReportOnFailure;
     private boolean mLogcatOnFailure;
     private boolean mScreenshotOnFailure;
     private boolean mRebootOnFailure;
+    private int mMaxLogcatBytes;
 
     public FailureListener(ITestInvocationListener listener, ITestDevice device,
             boolean bugReportOnFailure, boolean logcatOnFailure, boolean screenshotOnFailure,
-            boolean rebootOnFailure) {
+            boolean rebootOnFailure, int maxLogcatBytes) {
         super(listener);
         mDevice = device;
         mBugReportOnFailure = bugReportOnFailure;
         mLogcatOnFailure = logcatOnFailure;
         mScreenshotOnFailure = screenshotOnFailure;
         mRebootOnFailure = rebootOnFailure;
+        if (maxLogcatBytes < 0 ) {
+            CLog.w("FailureListener could not set %s to '%d', using default value %d",
+                    CompatibilityTest.LOGCAT_ON_FAILURE_SIZE_OPTION, maxLogcatBytes,
+                    DEFAULT_MAX_LOGCAT_BYTES);
+            mMaxLogcatBytes = DEFAULT_MAX_LOGCAT_BYTES;
+        } else if (maxLogcatBytes > LOGCAT_BYTE_LIMIT) {
+            CLog.w("Value %d for %s exceeds limit %d, using limit value", maxLogcatBytes,
+                    CompatibilityTest.LOGCAT_ON_FAILURE_SIZE_OPTION, LOGCAT_BYTE_LIMIT);
+            mMaxLogcatBytes = LOGCAT_BYTE_LIMIT;
+        } else {
+            mMaxLogcatBytes = maxLogcatBytes;
+        }
     }
 
     /**
@@ -62,7 +77,7 @@
         if (mLogcatOnFailure) {
             // sleep 2s to ensure test failure stack trace makes it into logcat capture
             RunUtil.getDefault().sleep(2 * 1000);
-            InputStreamSource logSource = mDevice.getLogcat(MAX_LOGCAT_BYTES);
+            InputStreamSource logSource = mDevice.getLogcat(mMaxLogcatBytes);
             super.testLog(String.format("%s-logcat", test.toString()), LogDataType.LOGCAT,
                     logSource);
             logSource.cancel();