Archive failures to cloud storage if gradle fails and the archive flag
is set

This will upload the build/reports/tests directory to cloud storage
making it readable directly from the printed link

R=sgjesse@google.com

Bug:
Change-Id: I300ad4949de5a25395989dd2f3c54635b197a9bb
diff --git a/tools/gradle.py b/tools/gradle.py
index f30b3f4..3a309ab 100755
--- a/tools/gradle.py
+++ b/tools/gradle.py
@@ -33,13 +33,16 @@
   else:
     print 'gradle.py: Gradle binary present'
 
-def RunGradle(args):
+def RunGradle(args, throw_on_failure=True):
   EnsureGradle()
   cmd = [GRADLE]
   cmd.extend(args)
   utils.PrintCmd(cmd)
   with utils.ChangedWorkingDirectory(utils.REPO_ROOT):
-    subprocess.check_call(cmd)
+    return_value = subprocess.call(cmd)
+    if throw_on_failure:
+      raise
+    return return_value
 
 def Main():
   RunGradle(sys.argv[1:])
diff --git a/tools/test.py b/tools/test.py
index 49a6f3c..7102207 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -11,14 +11,20 @@
 import gradle
 import optparse
 import sys
+import utils
+import uuid
 
 ALL_ART_VMS = ["default", "7.0.0", "6.0.1", "5.1.1"]
+BUCKET = 'r8-test-results'
 
 def ParseOptions():
   result = optparse.OptionParser()
   result.add_option('--no_internal',
       help='Do not run Google internal tests.',
       default=False, action='store_true')
+  result.add_option('--archive_failures',
+      help='Upload test results to cloud storage on failure.',
+      default=False, action='store_true')
   result.add_option('--only_internal',
       help='Only run Google internal tests.',
       default=False, action='store_true')
@@ -54,6 +60,14 @@
 
   return result.parse_args()
 
+def archive_failures():
+  upload_dir = os.path.join(utils.REPO_ROOT, 'build', 'reports', 'tests')
+  u_dir = uuid.uuid4()
+  destination = 'gs://%s/%s' % (BUCKET, u_dir)
+  utils.upload_html_to_cloud_storage(upload_dir, destination)
+  url = 'http://storage.googleapis.com/%s/%s/index.html' % (BUCKET, u_dir)
+  print 'Test results available at: %s' % url
+
 def Main():
   (options, args) = ParseOptions()
   gradle_args = ['cleanTest', 'test']
@@ -94,7 +108,12 @@
     gradle_args.append('jctfTestsClasses')
   vms_to_test = [options.dex_vm] if options.dex_vm != "all" else ALL_ART_VMS
   for art_vm in vms_to_test:
-    gradle.RunGradle(gradle_args + ['-Pdex_vm=%s' % art_vm])
+    return_code = gradle.RunGradle(gradle_args + ['-Pdex_vm=%s' % art_vm],
+                                   throw_on_failure=False)
+    if return_code != 0:
+      if options.archive_failures:
+        archive_failures()
+      return return_code
 
 if __name__ == '__main__':
   sys.exit(Main())
diff --git a/tools/utils.py b/tools/utils.py
index 8c4f710..fd7212b 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -50,6 +50,13 @@
     if not os.path.isdir(path):
         raise
 
+def upload_html_to_cloud_storage(directory, destination):
+  # Upload and make the content encoding right for viewing directly
+  cmd = ['gsutil.py', 'cp', '-z', 'html', '-a',
+         'public-read', '-R', directory, destination]
+  PrintCmd(cmd)
+  subprocess.check_call(cmd)
+
 class TempDir(object):
  def __init__(self, prefix=''):
    self._temp_dir = None