Roll sdk tools.

To run CTS, adb and aapt need to be rolled.

BUG=b:28797919
TEST=Ran cros_mark_android_as_stable_unittest
TEST=Ran cros_mark_android_as_stable --arc_bucket_url gs://chromeos-throw-away-bucket/SOME_TEST_BUCKET.

Change-Id: Ibb6f5242f359a467c1d5457868c5e78bf7d87cec
Reviewed-on: https://chromium-review.googlesource.com/347915
Commit-Ready: Hidehiko Abe <hidehiko@chromium.org>
Tested-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Ilja Friedel <ihf@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
diff --git a/scripts/cros_mark_android_as_stable.py b/scripts/cros_mark_android_as_stable.py
index 72f199b..d7c0e46 100644
--- a/scripts/cros_mark_android_as_stable.py
+++ b/scripts/cros_mark_android_as_stable.py
@@ -19,6 +19,7 @@
 import filecmp
 import glob
 import os
+import re
 
 from chromite.cbuildbot import constants
 from chromite.lib import commandline
@@ -58,7 +59,7 @@
   """
   gs_context = gs.GSContext()
   subpaths_dict = {}
-  for build, target in constants.ANDROID_BUILD_TARGETS.iteritems():
+  for build, (target, _) in constants.ANDROID_BUILD_TARGETS.iteritems():
     build_dir = '%s-%s' % (build_branch, target)
     build_id_path = os.path.join(bucket_url, build_dir, build_id)
 
@@ -81,12 +82,10 @@
 
     # Look for a zipfile ending in the build_id number.
     try:
-      for zipfile in gs_context.List(subpath_dir):
-        if zipfile.url.endswith('.zip'):
-          break
+      gs_context.List(subpath_dir)
     except gs.GSNoSuchKey:
       logging.warn(
-          'Did not find a zipfile for build id [%s] in directory [%s].',
+          'Did not find a file for build id [%s] in directory [%s].',
           build_id, subpath_dir)
       return None
 
@@ -111,7 +110,7 @@
   gs_context = gs.GSContext()
   common_build_ids = None
   # Find builds for each target.
-  for target in constants.ANDROID_BUILD_TARGETS.itervalues():
+  for target, _ in constants.ANDROID_BUILD_TARGETS.itervalues():
     build_dir = '-'.join((build_branch, target))
     base_path = os.path.join(bucket_url, build_dir)
     build_ids = []
@@ -194,22 +193,22 @@
   """
   gs_context = gs.GSContext()
   for build, subpath in subpaths.iteritems():
-    target = constants.ANDROID_BUILD_TARGETS[build]
+    target, pattern = constants.ANDROID_BUILD_TARGETS[build]
     build_dir = '%s-%s' % (build_branch, target)
     android_dir = os.path.join(android_bucket_url, build_dir, build_id, subpath)
     arc_dir = os.path.join(arc_bucket_url, build_dir, build_id)
 
-    # Copy all zip files from android_dir to arc_dir, setting ACLs.
-    for zipfile in gs_context.List(android_dir):
-      if zipfile.url.endswith('.zip'):
-        zipname = os.path.basename(zipfile.url)
-        arc_path = os.path.join(arc_dir, zipname)
+    # Copy all target files from android_dir to arc_dir, setting ACLs.
+    for targetfile in gs_context.List(android_dir):
+      if re.search(pattern, targetfile.url):
+        basename = os.path.basename(targetfile.url)
+        arc_path = os.path.join(arc_dir, basename)
         acl = acls[build]
         needs_copy = True
 
         # Check a pre-existing file with the original source.
         if gs_context.Exists(arc_path):
-          if (gs_context.Stat(zipfile.url).hash_crc32c !=
+          if (gs_context.Stat(targetfile.url).hash_crc32c !=
               gs_context.Stat(arc_path).hash_crc32c):
             logging.warn('Removing incorrect file %s', arc_path)
             gs_context.Remove(arc_path)
@@ -225,8 +224,9 @@
         # - rerunning the copy in case one of the googlestorage_acl_X.txt
         #   files changes (e.g. we add a new variant which reuses a build).
         if needs_copy:
-          logging.info('Copying %s -> %s (acl %s)', zipfile.url, arc_path, acl)
-          gs_context.Copy(zipfile.url, arc_path, version=0)
+          logging.info('Copying %s -> %s (acl %s)',
+                       targetfile.url, arc_path, acl)
+          gs_context.Copy(targetfile.url, arc_path, version=0)
         gs_context.ChangeACL(arc_path, acl_args_file=acl)
 
 
@@ -309,7 +309,7 @@
     new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
 
   variables = {'BASE_URL': arc_bucket_url}
-  for build, target in constants.ANDROID_BUILD_TARGETS.iteritems():
+  for build, (target, _) in constants.ANDROID_BUILD_TARGETS.iteritems():
     variables[build + '_TARGET'] = '%s-%s' % (build_branch, target)
 
   portage_util.EBuild.MarkAsStable(
diff --git a/scripts/cros_mark_android_as_stable_unittest.py b/scripts/cros_mark_android_as_stable_unittest.py
index ffaa20f..c0b1f34 100644
--- a/scripts/cros_mark_android_as_stable_unittest.py
+++ b/scripts/cros_mark_android_as_stable_unittest.py
@@ -6,6 +6,7 @@
 
 from __future__ import print_function
 
+import itertools
 import mock
 import os
 
@@ -80,6 +81,7 @@
         'ARM': self.arm_acl,
         'X86': self.x86_acl,
         'CTS': self.cts_acl,
+        'SDK_TOOLS': self.cts_acl,
     }
 
     osutils.WriteFile(self.arm_acl, self.arm_acl_data, makedirs=True)
@@ -101,57 +103,76 @@
             self.old_version, self.old2_version, self.new_version,
             self.partial_new_version
         ],
+        'SDK_TOOLS': [
+            self.old_version, self.old2_version, self.new_version,
+            self.partial_new_version
+        ],
     }
     for build_type, builds in builds.iteritems():
-      url = self.makeSrcTargetUrl(constants.ANDROID_BUILD_TARGETS[build_type])
+      url = self.makeSrcTargetUrl(
+          constants.ANDROID_BUILD_TARGETS[build_type][0])
       builds = '\n'.join(os.path.join(url, version) for version in builds)
       self.gs_mock.AddCmdResult(['ls', '--', url], output=builds)
 
     for version in [self.old_version, self.old2_version, self.new_version]:
-      for target in constants.ANDROID_BUILD_TARGETS.itervalues():
-        self.setupMockBuild(target, version)
+      for key in constants.ANDROID_BUILD_TARGETS.iterkeys():
+        self.setupMockBuild(key, version)
     self.new_subpaths = {
         'ARM': 'linux-cheets_arm-userdebug100',
         'X86': 'linux-cheets_x86-userdebug100',
         'CTS': 'linux-cts100',
+        'SDK_TOOLS': 'linux-static_sdk_tools100',
     }
 
-    self.setupMockBuild(constants.ANDROID_BUILD_TARGETS['ARM'],
-                        self.partial_new_version)
-    self.setupMockBuild(constants.ANDROID_BUILD_TARGETS['X86'],
-                        self.partial_new_version, False)
-    self.setupMockBuild(constants.ANDROID_BUILD_TARGETS['CTS'],
-                        self.partial_new_version)
+    self.setupMockBuild('ARM', self.partial_new_version)
+    self.setupMockBuild('X86', self.partial_new_version, valid=False)
+    self.setupMockBuild('CTS', self.partial_new_version)
+    self.setupMockBuild('SDK_TOOLS', self.partial_new_version)
 
-    for target in constants.ANDROID_BUILD_TARGETS.itervalues():
-      self.setupMockBuild(target, self.not_new_version, False)
+    for key in constants.ANDROID_BUILD_TARGETS.iterkeys():
+      self.setupMockBuild(key, self.not_new_version, False)
 
-  def setupMockBuild(self, target, version, valid=True):
+  def setupMockBuild(self, key, version, valid=True):
     """Helper to mock a build."""
     def _RaiseGSNoSuchKey(*_args, **_kwargs):
       raise gs.GSNoSuchKey('file does not exist')
+
+    target = constants.ANDROID_BUILD_TARGETS[key][0]
     src_url = self.makeSrcUrl(target, version)
     if valid:
       # Show source subpath directory.
       src_subdir = os.path.join(src_url, self.makeSubpath(target, version))
       self.gs_mock.AddCmdResult(['ls', '--', src_url], output=src_subdir)
 
-      # Show zipfile.
-      zipname = 'file-%s.zip' % version
-      src_zip = os.path.join(src_subdir, zipname)
-      self.gs_mock.AddCmdResult(['ls', '--', src_subdir], output=src_zip)
-      self.gs_mock.AddCmdResult(['stat', '--', src_zip],
-                                output=(self.STAT_OUTPUT) % src_url)
+      # Show files.
+      mock_file_template_list = {
+          'ARM': ['file-%(version)s.zip'],
+          'X86': ['file-%(version)s.zip'],
+          'CTS': ['android-cts.zip'],
+          'SDK_TOOLS': ['aapt', 'adb']
+      }
+      filelist = [template % {'version': version}
+                  for template in mock_file_template_list[key]]
+      src_filelist = [os.path.join(src_subdir, filename)
+                      for filename in filelist]
+      self.gs_mock.AddCmdResult(['ls', '--', src_subdir],
+                                output='\n'.join(src_filelist))
+      for src_file in src_filelist:
+        self.gs_mock.AddCmdResult(['stat', '--', src_file],
+                                  output=(self.STAT_OUTPUT) % src_url)
 
       # Show nothing in destination.
       dst_url = self.makeDstUrl(target, version)
-      dst_zip = os.path.join(dst_url, zipname)
-      self.gs_mock.AddCmdResult(['stat', '--', dst_zip],
-                                side_effect=_RaiseGSNoSuchKey)
+      dst_filelist = [os.path.join(dst_url, filename)
+                      for filename in filelist]
+      for dst_file in dst_filelist:
+        self.gs_mock.AddCmdResult(['stat', '--', dst_file],
+                                  side_effect=_RaiseGSNoSuchKey)
       logging.warn('mocking no %s', dst_url)
 
       # Allow copying of source to dest.
-      self.gs_mock.AddCmdResult(['cp', '-v', '--', src_zip, dst_zip])
+      for src_file, dst_file in itertools.izip(src_filelist, dst_filelist):
+        self.gs_mock.AddCmdResult(['cp', '-v', '--', src_file, dst_file])
     else:
       self.gs_mock.AddCmdResult(['ls', '--', src_url],
                                 side_effect=_RaiseGSNoSuchKey)
@@ -184,10 +205,11 @@
                                                           self.build_branch,
                                                           self.old_version)
     self.assertTrue(subpaths)
-    self.assertEquals(len(subpaths), 3)
+    self.assertEquals(len(subpaths), 4)
     self.assertEquals(subpaths['ARM'], 'linux-cheets_arm-userdebug25')
     self.assertEquals(subpaths['X86'], 'linux-cheets_x86-userdebug25')
     self.assertEquals(subpaths['CTS'], 'linux-cts25')
+    self.assertEquals(subpaths['SDK_TOOLS'], 'linux-static_sdk_tools25')
 
     subpaths = cros_mark_android_as_stable.IsBuildIdValid(self.bucket_url,
                                                           self.build_branch,
@@ -220,10 +242,11 @@
         self.bucket_url, self.build_branch)
     self.assertEqual(version, self.new_version)
     self.assertTrue(subpaths)
-    self.assertEquals(len(subpaths), 3)
+    self.assertEquals(len(subpaths), 4)
     self.assertEquals(subpaths['ARM'], 'linux-cheets_arm-userdebug100')
     self.assertEquals(subpaths['X86'], 'linux-cheets_x86-userdebug100')
     self.assertEquals(subpaths['CTS'], 'linux-cts100')
+    self.assertEquals(subpaths['SDK_TOOLS'], 'linux-static_sdk_tools100')
 
   def testCopyToArcBucket(self):
     """Test copying of images to ARC bucket."""