Home | History | Annotate | Download | only in chromedriver
      1 #!/usr/bin/env python
      2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Runs all the buildbot steps for ChromeDriver except for update/compile."""
      7 
      8 import optparse
      9 import os
     10 import platform
     11 import shutil
     12 import subprocess
     13 import sys
     14 import tempfile
     15 import time
     16 import urllib2
     17 import zipfile
     18 
     19 import archive
     20 import chrome_paths
     21 import util
     22 
     23 _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
     24 GS_BUCKET = 'gs://chromedriver-prebuilts'
     25 GS_ZIP_PREFIX = 'chromedriver2_prebuilts'
     26 SLAVE_SCRIPT_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir,
     27                                 os.pardir, os.pardir, os.pardir, os.pardir,
     28                                 'scripts', 'slave')
     29 UPLOAD_SCRIPT = os.path.join(SLAVE_SCRIPT_DIR, 'skia', 'upload_to_bucket.py')
     30 DOWNLOAD_SCRIPT = os.path.join(SLAVE_SCRIPT_DIR, 'gsutil_download.py')
     31 
     32 
     33 def Archive(revision):
     34   util.MarkBuildStepStart('archive')
     35   prebuilts = ['chromedriver2_server',
     36                'chromedriver2_unittests', 'chromedriver2_tests']
     37   build_dir = chrome_paths.GetBuildDir(prebuilts[0:1])
     38   zip_name = '%s_r%s.zip' % (GS_ZIP_PREFIX, revision)
     39   temp_dir = util.MakeTempDir()
     40   zip_path = os.path.join(temp_dir, zip_name)
     41   print 'Zipping prebuilts %s' % zip_path
     42   f = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
     43   for prebuilt in prebuilts:
     44     f.write(os.path.join(build_dir, prebuilt), prebuilt)
     45   f.close()
     46 
     47   cmd = [
     48       sys.executable,
     49       UPLOAD_SCRIPT,
     50       '--source_filepath=%s' % zip_path,
     51       '--dest_gsbase=%s' % GS_BUCKET
     52   ]
     53   if util.RunCommand(cmd):
     54     util.MarkBuildStepError()
     55 
     56 
     57 def Download():
     58   util.MarkBuildStepStart('Download chromedriver prebuilts')
     59 
     60   temp_dir = util.MakeTempDir()
     61   zip_path = os.path.join(temp_dir, 'chromedriver2_prebuilts.zip')
     62   cmd = [
     63       sys.executable,
     64       DOWNLOAD_SCRIPT,
     65       '--url=%s' % GS_BUCKET,
     66       '--partial-name=%s' % GS_ZIP_PREFIX,
     67       '--dst=%s' % zip_path
     68   ]
     69   if util.RunCommand(cmd):
     70     util.MarkBuildStepError()
     71 
     72   build_dir = chrome_paths.GetBuildDir(['host_forwarder'])
     73   print 'Unzipping prebuilts %s to %s' % (zip_path, build_dir)
     74   f = zipfile.ZipFile(zip_path, 'r')
     75   f.extractall(build_dir)
     76   f.close()
     77   # Workaround for Python bug: http://bugs.python.org/issue15795
     78   os.chmod(os.path.join(build_dir, 'chromedriver2_server'), 0700)
     79 
     80 
     81 def MaybeRelease(revision):
     82   # Version is embedded as: const char kChromeDriverVersion[] = "0.1";
     83   # Minimum supported Chrome version is embedded as:
     84   # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0};
     85   with open(os.path.join(_THIS_DIR, 'chrome', 'version.cc'), 'r') as f:
     86     lines = f.readlines()
     87     version_line = filter(lambda x: 'kChromeDriverVersion' in x, lines)
     88     chrome_min_version_line = filter(
     89         lambda x: 'kMinimumSupportedChromeVersion' in x, lines)
     90   version = version_line[0].split('"')[1]
     91   chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0]
     92   with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f:
     93     chrome_max_version = f.readlines()[0].split('=')[1]
     94 
     95   bitness = '32'
     96   if util.IsLinux() and platform.architecture()[0] == '64bit':
     97     bitness = '64'
     98   zip_name = 'chromedriver_%s%s_%s.zip' % (
     99       util.GetPlatformName(), bitness, version)
    100 
    101   site = 'https://code.google.com/p/chromedriver/downloads/list'
    102   s = urllib2.urlopen(site)
    103   downloads = s.read()
    104   s.close()
    105 
    106   if zip_name in downloads:
    107     return 0
    108 
    109   util.MarkBuildStepStart('releasing %s' % zip_name)
    110   if util.IsWindows():
    111     server_orig_name = 'chromedriver2_server.exe'
    112     server_name = 'chromedriver.exe'
    113   else:
    114     server_orig_name = 'chromedriver2_server'
    115     server_name = 'chromedriver'
    116   server = os.path.join(chrome_paths.GetBuildDir([server_orig_name]),
    117                         server_orig_name)
    118 
    119   print 'Zipping ChromeDriver server', server
    120   temp_dir = util.MakeTempDir()
    121   zip_path = os.path.join(temp_dir, zip_name)
    122   f = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
    123   f.write(server, server_name)
    124   f.close()
    125 
    126   cmd = [
    127       sys.executable,
    128       os.path.join(_THIS_DIR, 'third_party', 'googlecode',
    129                    'googlecode_upload.py'),
    130       '--summary',
    131       'ChromeDriver server for %s%s (v%s.%s.dyu) supports Chrome v%s-%s' % (
    132           util.GetPlatformName(), bitness, version, revision,
    133           chrome_min_version, chrome_max_version),
    134       '--project', 'chromedriver',
    135       '--user', 'chromedriver.bot (at] gmail.com',
    136       zip_path
    137   ]
    138   with open(os.devnull, 'wb') as no_output:
    139     if subprocess.Popen(cmd, stdout=no_output, stderr=no_output).wait():
    140       util.MarkBuildStepError()
    141 
    142 
    143 def KillChromes():
    144   chrome_map = {
    145       'win': 'chrome.exe',
    146       'mac': 'Chromium',
    147       'linux': 'chrome',
    148   }
    149   if util.IsWindows():
    150     cmd = ['taskkill', '/F', '/IM']
    151   else:
    152     cmd = ['killall', '-9']
    153   cmd.append(chrome_map[util.GetPlatformName()])
    154   util.RunCommand(cmd)
    155 
    156 
    157 def CleanTmpDir():
    158   tmp_dir = tempfile.gettempdir()
    159   print 'cleaning temp directory:', tmp_dir
    160   for file_name in os.listdir(tmp_dir):
    161     if os.path.isdir(os.path.join(tmp_dir, file_name)):
    162       print 'deleting sub-directory', file_name
    163       shutil.rmtree(os.path.join(tmp_dir, file_name), True)
    164 
    165 
    166 def WaitForLatestSnapshot(revision):
    167   util.MarkBuildStepStart('wait_for_snapshot')
    168   while True:
    169     snapshot_revision = archive.GetLatestRevision(archive.Site.SNAPSHOT)
    170     if snapshot_revision >= revision:
    171       break
    172     util.PrintAndFlush('Waiting for snapshot >= %s, found %s' %
    173                        (revision, snapshot_revision))
    174     time.sleep(60)
    175   util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision)
    176 
    177 
    178 def main():
    179   parser = optparse.OptionParser()
    180   parser.add_option(
    181       '', '--android-package',
    182       help='Application package name, if running tests on Android.')
    183   parser.add_option(
    184       '-r', '--revision', type='string', default=None,
    185       help='Chromium revision')
    186   options, _ = parser.parse_args()
    187 
    188   if not options.android_package:
    189     KillChromes()
    190   CleanTmpDir()
    191 
    192   if options.android_package:
    193     Download()
    194   else:
    195     if not options.revision:
    196       parser.error('Must supply a --revision')
    197 
    198     if util.IsLinux() and platform.architecture()[0] == '64bit':
    199       Archive(options.revision)
    200 
    201     WaitForLatestSnapshot(options.revision)
    202 
    203   cmd = [
    204       sys.executable,
    205       os.path.join(_THIS_DIR, 'test', 'run_all_tests.py'),
    206   ]
    207   if options.android_package:
    208     cmd.append('--android-package=' + options.android_package)
    209 
    210   passed = (util.RunCommand(cmd) == 0)
    211 
    212   if not options.android_package and passed:
    213     MaybeRelease(options.revision)
    214 
    215 
    216 if __name__ == '__main__':
    217   main()
    218