Add test.py flags to print full and obfuscated stack traces

Bug: 172167362
Fixes: 172797655
Fixes: 172795738
Change-Id: I2d2f6663d52fce6d12b19131aed753247f3775e1
diff --git a/build.gradle b/build.gradle
index 558919e..981dcfd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1875,10 +1875,11 @@
 }
 
 def printStackTrace(TestResult result) {
+    filterStackTraces(result)
     if (project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')) {
         def out = new StringBuffer()
         def err = new StringBuffer()
-        def command = "python tools/retrace.py"
+        def command = "python tools/retrace.py --quiet"
         def header = "RETRACED STACKTRACE";
         if (System.getenv('BUILDBOT_BUILDERNAME') != null
                 && !System.getenv('BUILDBOT_BUILDERNAME').endsWith("_release")) {
@@ -1893,19 +1894,49 @@
         result.exception.printStackTrace(processIn)
         processIn.flush()
         processIn.close()
-        if (process.waitFor() != 0) {
+        def errorDuringRetracing = process.waitFor() != 0
+        if (errorDuringRetracing) {
             out.append("ERROR DURING RETRACING\n")
             out.append(err.toString())
         }
-        out.append("\n\n--------------------------------------\n")
-        out.append("OBFUSCATED STACKTRACE\n")
-        out.append("--------------------------------------\n")
-        result.exceptions.add(0, new Exception(out.toString()))
+        if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
+            out.append("\n\n--------------------------------------\n")
+            out.append("OBFUSCATED STACKTRACE\n")
+            out.append("--------------------------------------\n")
+        } else {
+          result.exceptions.clear()
+        }
+        def exception = new Exception(out.toString())
+        exception.setStackTrace([] as StackTraceElement[])
+        result.exceptions.add(0, exception)
     } else {
         result.exception.printStackTrace()
     }
 }
 
+def filterStackTraces(TestResult result) {
+    for (Throwable throwable : result.getExceptions()) {
+        filterStackTrace(throwable)
+    }
+}
+
+def filterStackTrace(Throwable exception) {
+    if (!project.hasProperty('print_full_stacktraces')) {
+        def elements = []
+        def skipped = []
+        for (StackTraceElement element : exception.getStackTrace()) {
+            if (element.toString().contains("com.android.tools.r8")) {
+                elements.addAll(skipped)
+                elements.add(element)
+                skipped.clear()
+            } else {
+                skipped.add(element)
+            }
+        }
+        exception.setStackTrace(elements as StackTraceElement[])
+    }
+}
+
 test {
     if (project.hasProperty('generate_golden_files_to')) {
         systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
diff --git a/tools/retrace.py b/tools/retrace.py
index 3be9771..70e3099 100755
--- a/tools/retrace.py
+++ b/tools/retrace.py
@@ -40,6 +40,11 @@
       '--stacktrace',
       help='Path to stacktrace file.',
       default=None)
+  parser.add_argument(
+      '--quiet',
+      default=None,
+      action='store_true',
+      help='Disables diagnostics printing to stdout.')
   return parser.parse_args()
 
 
@@ -67,9 +72,10 @@
       hash_or_version,
       args.stacktrace,
       args.commit_hash is not None,
-      args.no_r8lib)
+      args.no_r8lib,
+      quiet=args.quiet)
 
-def run(map_path, hash_or_version, stacktrace, is_hash, no_r8lib):
+def run(map_path, hash_or_version, stacktrace, is_hash, no_r8lib, quiet=False):
   if hash_or_version:
     download_path = archive.GetUploadDestination(
         hash_or_version,
@@ -93,7 +99,7 @@
   if stacktrace:
     retrace_args.append(stacktrace)
 
-  utils.PrintCmd(retrace_args)
+  utils.PrintCmd(retrace_args, quiet=quiet)
   return subprocess.call(retrace_args)
 
 
diff --git a/tools/test.py b/tools/test.py
index d7987a7..0c70124 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -149,6 +149,13 @@
           ' and empty (for no runtimes).')
   result.add_option('--print-hanging-stacks', '--print_hanging_stacks',
       default=-1, type="int", help='Print hanging stacks after timeout in seconds')
+  result.add_option('--print-full-stacktraces', '--print_full_stacktraces',
+      default=False, action='store_true',
+      help='Print the full stacktraces without any filtering applied')
+  result.add_option(
+      '--print-obfuscated-stacktraces', '--print_obfuscated_stacktraces',
+      default=False, action='store_true',
+      help='Print the obfuscated stacktraces')
   return result.parse_args()
 
 def archive_failures():
@@ -202,6 +209,10 @@
     gradle_args.append('-Pdisable_assertions')
   if options.with_code_coverage:
     gradle_args.append('-Pwith_code_coverage')
+  if options.print_full_stacktraces:
+    gradle_args.append('-Pprint_full_stacktraces')
+  if options.print_obfuscated_stacktraces:
+    gradle_args.append('-Pprint_obfuscated_stacktraces')
   if os.name == 'nt':
     # temporary hack
     gradle_args.append('-Pno_internal')