run_buildbot_steps.py revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2013 The Chromium Authors. All rights reserved.
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""Runs all the buildbot steps for ChromeDriver except for update/compile."""
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import bisect
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)import csv
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)import datetime
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import glob
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import json
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import optparse
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import platform as platform_module
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import re
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import shutil
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)import StringIO
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import tempfile
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)import time
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import urllib2
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)_THIS_DIR = os.path.abspath(os.path.dirname(__file__))
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GS_CHROMEDRIVER_BUCKET = 'gs://chromedriver'
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GS_CHROMEDRIVER_DATA_BUCKET = 'gs://chromedriver-data'
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GS_CHROMEDRIVER_RELEASE_URL = 'http://chromedriver.storage.googleapis.com'
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GS_CONTINUOUS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/continuous'
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GS_PREBUILTS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/prebuilts'
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs'
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)SERVER_LOGS_LINK = (
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'http://chromedriver-data.storage.googleapis.com/server_logs')
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_LOG_FORMAT = '%s_log.json'
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)SCRIPT_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir, os.pardir,
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          os.pardir, os.pardir, os.pardir, 'scripts')
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)SITE_CONFIG_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir,
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               os.pardir, os.pardir, os.pardir, os.pardir,
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               'site_config')
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)sys.path.append(SCRIPT_DIR)
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)sys.path.append(SITE_CONFIG_DIR)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import archive
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import chrome_paths
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)from slave import gsutil_download
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)from slave import slave_utils
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import util
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _ArchivePrebuilts(revision):
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Uploads the prebuilts to google storage."""
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  util.MarkBuildStepStart('archive prebuilts')
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir(['chromedriver']),
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   'chromedriver'))
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if slave_utils.GSUtilCopy(
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      zip_path,
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      '%s/%s' % (GS_PREBUILTS_URL, 'r%s.zip' % revision)):
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    util.MarkBuildStepError()
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)def _ArchiveServerLogs():
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  """Uploads chromedriver server logs to google storage."""
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  util.MarkBuildStepStart('archive chromedriver server logs')
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for server_log in glob.glob(os.path.join(tempfile.gettempdir(),
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                           'chromedriver_*')):
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base_name = os.path.basename(server_log)
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    util.AddLink(base_name, '%s/%s' % (SERVER_LOGS_LINK, base_name))
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    slave_utils.GSUtilCopy(
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        server_log,
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        '%s/%s' % (GS_SERVER_LOGS_URL, base_name),
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        mimetype='text/plain')
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _DownloadPrebuilts():
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Downloads the most recent prebuilts from google storage."""
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  util.MarkBuildStepStart('Download latest chromedriver')
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  zip_path = os.path.join(util.MakeTempDir(), 'build.zip')
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if gsutil_download.DownloadLatestFile(GS_PREBUILTS_URL, 'r', zip_path):
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    util.MarkBuildStepError()
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  util.Unzip(zip_path, chrome_paths.GetBuildDir(['host_forwarder']))
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetTestResultsLog(platform):
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Gets the test results log for the given platform.
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Args:
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    platform: The platform that the test results log is for.
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Returns:
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    A dictionary where the keys are SVN revisions and the values are booleans
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    indicating whether the tests passed.
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  temp_log = tempfile.mkstemp()[1]
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  log_name = TEST_LOG_FORMAT % platform
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  result = slave_utils.GSUtilDownloadFile(
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      '%s/%s' % (GS_CHROMEDRIVER_DATA_BUCKET, log_name), temp_log)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if result:
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return {}
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  with open(temp_log, 'rb') as log_file:
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    json_dict = json.load(log_file)
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # Workaround for json encoding dictionary keys as strings.
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return dict([(int(v[0]), v[1]) for v in json_dict.items()])
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _PutTestResultsLog(platform, test_results_log):
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Pushes the given test results log to google storage."""
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  temp_dir = util.MakeTempDir()
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  log_name = TEST_LOG_FORMAT % platform
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  log_path = os.path.join(temp_dir, log_name)
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  with open(log_path, 'wb') as log_file:
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    json.dump(test_results_log, log_file)
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if slave_utils.GSUtilCopyFile(log_path, GS_CHROMEDRIVER_DATA_BUCKET):
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    raise Exception('Failed to upload test results log to google storage')
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _UpdateTestResultsLog(platform, revision, passed):
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Updates the test results log for the given platform.
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Args:
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    platform: The platform name.
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    revision: The SVN revision number.
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    passed: Boolean indicating whether the tests passed at this revision.
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  assert isinstance(revision, int), 'The revision must be an integer'
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  log = _GetTestResultsLog(platform)
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if len(log) > 500:
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    del log[min(log.keys())]
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  assert revision not in log, 'Results already exist for revision %s' % revision
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  log[revision] = bool(passed)
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  _PutTestResultsLog(platform, log)
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetVersion():
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Get the current chromedriver version."""
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  with open(os.path.join(_THIS_DIR, 'VERSION'), 'r') as f:
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return f.read().strip()
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetSupportedChromeVersions():
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Get the minimum and maximum supported Chrome versions.
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Returns:
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    A tuple of the form (min_version, max_version).
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  # Minimum supported Chrome version is embedded as:
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0};
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  with open(os.path.join(_THIS_DIR, 'chrome', 'version.cc'), 'r') as f:
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    lines = f.readlines()
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome_min_version_line = [
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        x for x in lines if 'kMinimumSupportedChromeVersion' in x]
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0]
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f:
155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome_max_version = f.readlines()[0].split('=')[1].strip()
156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return (chrome_min_version, chrome_max_version)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _RevisionState(test_results_log, revision):
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Check the state of tests at a given SVN revision.
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Considers tests as having passed at a revision if they passed at revisons both
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  before and after.
164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Args:
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    test_results_log: A test results log dictionary from _GetTestResultsLog().
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    revision: The revision to check at.
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Returns:
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    'passed', 'failed', or 'unknown'
171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  assert isinstance(revision, int), 'The revision must be an integer'
173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  keys = sorted(test_results_log.keys())
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # Return passed if the exact revision passed on Android.
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if revision in test_results_log:
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return 'passed' if test_results_log[revision] else 'failed'
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # Tests were not run on this exact revision on Android.
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  index = bisect.bisect_right(keys, revision)
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # Tests have not yet run on Android at or above this revision.
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if index == len(test_results_log):
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return 'unknown'
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # No log exists for any prior revision, assume it failed.
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if index == 0:
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return 'failed'
185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  # Return passed if the revisions on both sides passed.
186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if test_results_log[keys[index]] and test_results_log[keys[index - 1]]:
187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return 'passed'
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return 'failed'
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _ArchiveGoodBuild(platform, revision):
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Archive chromedriver binary if the build is green."""
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  assert platform != 'android'
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  util.MarkBuildStepStart('archive build')
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  server_name = 'chromedriver'
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if util.IsWindows():
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    server_name += '.exe'
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir([server_name]),
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   server_name))
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  build_name = 'chromedriver_%s_%s.%s.zip' % (
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      platform, _GetVersion(), revision)
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  build_url = '%s/%s' % (GS_CONTINUOUS_URL, build_name)
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if slave_utils.GSUtilCopy(zip_path, build_url):
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    util.MarkBuildStepError()
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  (latest_fd, latest_file) = tempfile.mkstemp()
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  os.write(latest_fd, build_name)
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  os.close(latest_fd)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  latest_url = '%s/latest_%s' % (GS_CONTINUOUS_URL, platform)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if slave_utils.GSUtilCopy(latest_file, latest_url, mimetype='text/plain'):
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    util.MarkBuildStepError()
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  os.remove(latest_file)
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _WasReleased(version, platform):
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Check if the specified version is released for the given platform."""
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result, _ = slave_utils.GSUtilListBucket(
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      '%s/%s/chromedriver_%s.zip' % (GS_CHROMEDRIVER_BUCKET, version, platform),
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      [])
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result == 0
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _MaybeRelease(platform):
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  """Releases a release candidate if conditions are right."""
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  assert platform != 'android'
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version = _GetVersion()
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  # Check if the current version has already been released.
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if _WasReleased(version, platform):
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  # Fetch Android test results.
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  android_test_results = _GetTestResultsLog('android')
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  # Fetch release candidates.
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  result, output = slave_utils.GSUtilListBucket(
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      '%s/chromedriver_%s_%s*' % (
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GS_CONTINUOUS_URL, platform, version),
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      [])
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  assert result == 0 and output, 'No release candidates found'
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  candidate_pattern = re.compile(
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      r'.*/chromedriver_%s_%s\.(\d+)\.zip$' % (platform, version))
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  candidates = []
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for line in output.strip().split('\n'):
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result = candidate_pattern.match(line)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if not result:
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      print 'Ignored line "%s"' % line
2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      continue
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    candidates.append(int(result.group(1)))
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # Release the latest candidate build that passed Android, if any.
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # In this way, if a hot fix is needed, we can delete the release from
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # the chromedriver bucket instead of bumping up the release version number.
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  candidates.sort(reverse=True)
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for revision in candidates:
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    android_result = _RevisionState(android_test_results, revision)
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if android_result == 'failed':
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      print 'Android tests did not pass at revision', revision
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    elif android_result == 'passed':
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      print 'Android tests passed at revision', revision
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      candidate = 'chromedriver_%s_%s.%s.zip' % (platform, version, revision)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      _Release('%s/%s' % (GS_CONTINUOUS_URL, candidate), version, platform)
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else:
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      print 'Android tests have not run at a revision as recent as', revision
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _Release(build, version, platform):
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  """Releases the given candidate build."""
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  release_name = 'chromedriver_%s.zip' % platform
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  util.MarkBuildStepStart('releasing %s' % release_name)
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  slave_utils.GSUtilCopy(
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      build, '%s/%s/%s' % (GS_CHROMEDRIVER_BUCKET, version, release_name))
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  _MaybeUploadReleaseNotes(version)
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  _MaybeUpdateLatestRelease(version)
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _GetWebPageContent(url):
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Return the content of the web page specified by the given url."""
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return urllib2.urlopen(url).read()
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _MaybeUploadReleaseNotes(version):
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  """Upload release notes if conditions are right."""
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  # Check if the current version has already been released.
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notes_name = 'notes.txt'
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  notes_url = '%s/%s/%s' % (GS_CHROMEDRIVER_BUCKET, version, notes_name)
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  prev_version = '.'.join([version.split('.')[0],
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           str(int(version.split('.')[1]) - 1)])
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  prev_notes_url = '%s/%s/%s' % (
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GS_CHROMEDRIVER_BUCKET, prev_version, notes_name)
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  result, _ = slave_utils.GSUtilListBucket(notes_url, [])
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if result == 0:
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fixed_issues = []
302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  query = ('https://code.google.com/p/chromedriver/issues/csv?'
303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)           'q=status%3AToBeReleased&colspec=ID%20Summary')
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  issues = StringIO.StringIO(_GetWebPageContent(query).split('\n', 1)[1])
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for issue in csv.reader(issues):
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if not issue:
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      continue
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    issue_id = issue[0]
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    desc = issue[1]
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    labels = issue[2]
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fixed_issues += ['Resolved issue %s: %s [%s]' % (issue_id, desc, labels)]
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  old_notes = ''
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  temp_notes_fname = tempfile.mkstemp()[1]
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if not slave_utils.GSUtilDownloadFile(prev_notes_url, temp_notes_fname):
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    with open(temp_notes_fname, 'rb') as f:
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      old_notes = f.read()
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_notes = '----------ChromeDriver v%s (%s)----------\n%s\n%s\n\n%s' % (
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      version, datetime.date.today().isoformat(),
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      'Supports Chrome v%s-%s' % _GetSupportedChromeVersions(),
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      '\n'.join(fixed_issues),
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      old_notes)
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  with open(temp_notes_fname, 'w') as f:
325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    f.write(new_notes)
326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if slave_utils.GSUtilCopy(temp_notes_fname, notes_url, mimetype='text/plain'):
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    util.MarkBuildStepError()
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _MaybeUpdateLatestRelease(version):
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Update the file LATEST_RELEASE with the latest release version number."""
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  latest_release_fname = 'LATEST_RELEASE'
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  latest_release_url = '%s/%s' % (GS_CHROMEDRIVER_BUCKET, latest_release_fname)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # Check if LATEST_RELEASE is up-to-date.
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  latest_released_version = _GetWebPageContent(
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      '%s/%s' % (GS_CHROMEDRIVER_RELEASE_URL, latest_release_fname))
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if version == latest_released_version:
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # Check if chromedriver was released on all supported platforms.
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  supported_platforms = ['linux32', 'linux64', 'mac32', 'win32']
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for platform in supported_platforms:
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if not _WasReleased(version, platform):
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  util.MarkBuildStepStart('updating LATEST_RELEASE to %s' % version)
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  temp_latest_release_fname = tempfile.mkstemp()[1]
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  with open(temp_latest_release_fname, 'w') as f:
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    f.write(version)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if slave_utils.GSUtilCopy(temp_latest_release_fname, latest_release_url,
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            mimetype='text/plain'):
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util.MarkBuildStepError()
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _CleanTmpDir():
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  tmp_dir = tempfile.gettempdir()
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  print 'cleaning temp directory:', tmp_dir
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for file_name in os.listdir(tmp_dir):
3620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    file_path = os.path.join(tmp_dir, file_name)
3630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if os.path.isdir(file_path):
3640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      print 'deleting sub-directory', file_path
3650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      shutil.rmtree(file_path, True)
3660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if file_name.startswith('chromedriver_'):
3670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      print 'deleting file', file_path
3680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      os.remove(file_path)
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _WaitForLatestSnapshot(revision):
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  util.MarkBuildStepStart('wait_for_snapshot')
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  while True:
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    snapshot_revision = archive.GetLatestRevision(archive.Site.SNAPSHOT)
375d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if int(snapshot_revision) >= int(revision):
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    util.PrintAndFlush('Waiting for snapshot >= %s, found %s' %
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       (revision, snapshot_revision))
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    time.sleep(60)
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision)
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _AddToolsToPath(platform_name):
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Add some tools like Ant and Java to PATH for testing steps to use."""
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  paths = []
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_message = ''
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if platform_name == 'win32':
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    paths = [
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        # Path to Ant and Java, required for the java acceptance tests.
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        'C:\\Program Files (x86)\\Java\\ant\\bin',
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        'C:\\Program Files (x86)\\Java\\jre\\bin',
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ]
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_message = ('Java test steps will fail as expected and '
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     'they can be ignored.\n'
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     'Ant, Java or others might not be installed on bot.\n'
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     'Please refer to page "WATERFALL" on site '
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     'go/chromedriver.')
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if paths:
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util.MarkBuildStepStart('Add tools to PATH')
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    path_missing = False
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for path in paths:
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if not os.path.isdir(path) or not os.listdir(path):
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        print 'Directory "%s" is not found or empty.' % path
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        path_missing = True
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if path_missing:
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      print error_message
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      util.MarkBuildStepError()
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    os.environ['PATH'] += os.pathsep + os.pathsep.join(paths)
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def main():
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser = optparse.OptionParser()
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option(
4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      '', '--android-packages',
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      help=('Comma separated list of application package names, '
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            'if running tests on Android.'))
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option(
41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      '-r', '--revision', type='int', help='Chromium revision')
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parser.add_option(
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      '', '--update-log', action='store_true',
42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      help='Update the test results log (only applicable to Android)')
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options, _ = parser.parse_args()
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bitness = '32'
426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if util.IsLinux() and platform_module.architecture()[0] == '64bit':
427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bitness = '64'
428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  platform = '%s%s' % (util.GetPlatformName(), bitness)
429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if options.android_packages:
430d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    platform = 'android'
431d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  _CleanTmpDir()
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
434d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if platform == 'android':
43568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if not options.revision and options.update_log:
43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      parser.error('Must supply a --revision with --update-log')
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    _DownloadPrebuilts()
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else:
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if not options.revision:
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parser.error('Must supply a --revision')
441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if platform == 'linux64':
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      _ArchivePrebuilts(options.revision)
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    _WaitForLatestSnapshot(options.revision)
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  _AddToolsToPath(platform)
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cmd = [
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sys.executable,
449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      os.path.join(_THIS_DIR, 'test', 'run_all_tests.py'),
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ]
451d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if platform == 'android':
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    cmd.append('--android-packages=' + options.android_packages)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  passed = (util.RunCommand(cmd) == 0)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  _ArchiveServerLogs()
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
458d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if platform == 'android':
45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if options.update_log:
46068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      util.MarkBuildStepStart('update test result log')
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      _UpdateTestResultsLog(platform, options.revision, passed)
462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  elif passed:
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    _ArchiveGoodBuild(platform, options.revision)
464d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    _MaybeRelease(platform)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if not passed:
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    # Make sure the build is red if there is some uncaught exception during
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    # running run_all_tests.py.
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util.MarkBuildStepStart('run_all_tests.py')
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    util.MarkBuildStepError()
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # Add a "cleanup" step so that errors from runtest.py or bb_device_steps.py
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # (which invoke this script) are kept in thier own build step.
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  util.MarkBuildStepStart('cleanup')
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__':
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main()
479