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' 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGS_GIT_LOG_URL = ( 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'https://chromium.googlesource.com/chromium/src/+/%s?format=json') 36116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGS_SEARCH_PATTERN = ( 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci r'Cr-Commit-Position: refs/heads/master@{#(\d+)}') 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCR_REV_URL = 'https://cr-rev.appspot.com/_ah/api/crrev/v1/redirect/%s' 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)SCRIPT_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir, os.pardir, 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) os.pardir, os.pardir, os.pardir, 'scripts') 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)SITE_CONFIG_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir, 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) os.pardir, os.pardir, os.pardir, os.pardir, 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 'site_config') 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)sys.path.append(SCRIPT_DIR) 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)sys.path.append(SITE_CONFIG_DIR) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import archive 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import chrome_paths 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)from slave import gsutil_download 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)from slave import slave_utils 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import util 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _ArchivePrebuilts(revision): 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Uploads the prebuilts to google storage.""" 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.MarkBuildStepStart('archive prebuilts') 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir(['chromedriver']), 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'chromedriver')) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if slave_utils.GSUtilCopy( 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) zip_path, 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) '%s/%s' % (GS_PREBUILTS_URL, 'r%s.zip' % revision)): 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util.MarkBuildStepError() 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)def _ArchiveServerLogs(): 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) """Uploads chromedriver server logs to google storage.""" 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) util.MarkBuildStepStart('archive chromedriver server logs') 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for server_log in glob.glob(os.path.join(tempfile.gettempdir(), 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'chromedriver_*')): 710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base_name = os.path.basename(server_log) 720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) util.AddLink(base_name, '%s/%s' % (SERVER_LOGS_LINK, base_name)) 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) slave_utils.GSUtilCopy( 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) server_log, 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) '%s/%s' % (GS_SERVER_LOGS_URL, base_name), 760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) mimetype='text/plain') 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _DownloadPrebuilts(): 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Downloads the most recent prebuilts from google storage.""" 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.MarkBuildStepStart('Download latest chromedriver') 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) zip_path = os.path.join(util.MakeTempDir(), 'build.zip') 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if gsutil_download.DownloadLatestFile(GS_PREBUILTS_URL, 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GS_PREBUILTS_URL + '/r', 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch zip_path): 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util.MarkBuildStepError() 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.Unzip(zip_path, chrome_paths.GetBuildDir(['host_forwarder'])) 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetTestResultsLog(platform): 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Gets the test results log for the given platform. 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Args: 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) platform: The platform that the test results log is for. 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Returns: 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) A dictionary where the keys are SVN revisions and the values are booleans 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) indicating whether the tests passed. 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) temp_log = tempfile.mkstemp()[1] 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log_name = TEST_LOG_FORMAT % platform 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = slave_utils.GSUtilDownloadFile( 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) '%s/%s' % (GS_CHROMEDRIVER_DATA_BUCKET, log_name), temp_log) 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if result: 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return {} 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) with open(temp_log, 'rb') as log_file: 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) json_dict = json.load(log_file) 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Workaround for json encoding dictionary keys as strings. 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return dict([(int(v[0]), v[1]) for v in json_dict.items()]) 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _PutTestResultsLog(platform, test_results_log): 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Pushes the given test results log to google storage.""" 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) temp_dir = util.MakeTempDir() 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log_name = TEST_LOG_FORMAT % platform 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_path = os.path.join(temp_dir, log_name) 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) with open(log_path, 'wb') as log_file: 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) json.dump(test_results_log, log_file) 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if slave_utils.GSUtilCopyFile(log_path, GS_CHROMEDRIVER_DATA_BUCKET): 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) raise Exception('Failed to upload test results log to google storage') 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _UpdateTestResultsLog(platform, revision, passed): 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Updates the test results log for the given platform. 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Args: 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) platform: The platform name. 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) revision: The SVN revision number. 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) passed: Boolean indicating whether the tests passed at this revision. 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert isinstance(revision, int), 'The revision must be an integer' 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log = _GetTestResultsLog(platform) 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if len(log) > 500: 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) del log[min(log.keys())] 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert revision not in log, 'Results already exist for revision %s' % revision 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log[revision] = bool(passed) 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) _PutTestResultsLog(platform, log) 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetVersion(): 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Get the current chromedriver version.""" 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) with open(os.path.join(_THIS_DIR, 'VERSION'), 'r') as f: 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return f.read().strip() 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _GetSupportedChromeVersions(): 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Get the minimum and maximum supported Chrome versions. 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Returns: 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) A tuple of the form (min_version, max_version). 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) # Minimum supported Chrome version is embedded as: 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0}; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) with open(os.path.join(_THIS_DIR, 'chrome', 'version.cc'), 'r') as f: 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) lines = f.readlines() 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome_min_version_line = [ 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) x for x in lines if 'kMinimumSupportedChromeVersion' in x] 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0] 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f: 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) chrome_max_version = f.readlines()[0].split('=')[1].strip() 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return (chrome_min_version, chrome_max_version) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _RevisionState(test_results_log, revision): 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Check the state of tests at a given SVN revision. 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Considers tests as having passed at a revision if they passed at revisons both 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) before and after. 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Args: 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) test_results_log: A test results log dictionary from _GetTestResultsLog(). 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) revision: The revision to check at. 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Returns: 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 'passed', 'failed', or 'unknown' 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert isinstance(revision, int), 'The revision must be an integer' 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) keys = sorted(test_results_log.keys()) 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Return passed if the exact revision passed on Android. 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if revision in test_results_log: 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 'passed' if test_results_log[revision] else 'failed' 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Tests were not run on this exact revision on Android. 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) index = bisect.bisect_right(keys, revision) 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Tests have not yet run on Android at or above this revision. 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if index == len(test_results_log): 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 'unknown' 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # No log exists for any prior revision, assume it failed. 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if index == 0: 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 'failed' 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Return passed if the revisions on both sides passed. 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if test_results_log[keys[index]] and test_results_log[keys[index - 1]]: 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 'passed' 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 'failed' 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _ArchiveGoodBuild(platform, revision): 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Archive chromedriver binary if the build is green.""" 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert platform != 'android' 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.MarkBuildStepStart('archive build') 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) server_name = 'chromedriver' 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if util.IsWindows(): 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) server_name += '.exe' 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir([server_name]), 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) server_name)) 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) build_name = 'chromedriver_%s_%s.%s.zip' % ( 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) platform, _GetVersion(), revision) 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) build_url = '%s/%s' % (GS_CONTINUOUS_URL, build_name) 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if slave_utils.GSUtilCopy(zip_path, build_url): 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.MarkBuildStepError() 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (latest_fd, latest_file) = tempfile.mkstemp() 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os.write(latest_fd, build_name) 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os.close(latest_fd) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) latest_url = '%s/latest_%s' % (GS_CONTINUOUS_URL, platform) 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if slave_utils.GSUtilCopy(latest_file, latest_url, mimetype='text/plain'): 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) util.MarkBuildStepError() 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os.remove(latest_file) 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _WasReleased(version, platform): 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Check if the specified version is released for the given platform.""" 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result, _ = slave_utils.GSUtilListBucket( 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '%s/%s/chromedriver_%s.zip' % (GS_CHROMEDRIVER_BUCKET, version, platform), 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) []) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result == 0 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)def _MaybeRelease(platform): 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Releases a release candidate if conditions are right.""" 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert platform != 'android' 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version = _GetVersion() 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Check if the current version has already been released. 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if _WasReleased(version, platform): 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Fetch Android test results. 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) android_test_results = _GetTestResultsLog('android') 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Fetch release candidates. 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result, output = slave_utils.GSUtilListBucket( 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) '%s/chromedriver_%s_%s*' % ( 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GS_CONTINUOUS_URL, platform, version), 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) []) 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert result == 0 and output, 'No release candidates found' 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidate_pattern = re.compile( 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) r'.*/chromedriver_%s_%s\.(\d+)\.zip$' % (platform, version)) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidates = [] 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for line in output.strip().split('\n'): 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = candidate_pattern.match(line) 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not result: 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print 'Ignored line "%s"' % line 2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) continue 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidates.append(int(result.group(1))) 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Release the latest candidate build that passed Android, if any. 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # In this way, if a hot fix is needed, we can delete the release from 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # the chromedriver bucket instead of bumping up the release version number. 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidates.sort(reverse=True) 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for revision in candidates: 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) android_result = _RevisionState(android_test_results, revision) 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if android_result == 'failed': 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) print 'Android tests did not pass at revision', revision 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elif android_result == 'passed': 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) print 'Android tests passed at revision', revision 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidate = 'chromedriver_%s_%s.%s.zip' % (platform, version, revision) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _Release('%s/%s' % (GS_CONTINUOUS_URL, candidate), version, platform) 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else: 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) print 'Android tests have not run at a revision as recent as', revision 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _Release(build, version, platform): 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Releases the given candidate build.""" 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) release_name = 'chromedriver_%s.zip' % platform 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.MarkBuildStepStart('releasing %s' % release_name) 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu temp_dir = util.MakeTempDir() 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu slave_utils.GSUtilCopy(build, temp_dir) 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu zip_path = os.path.join(temp_dir, os.path.basename(build)) 2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if util.IsLinux(): 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu util.Unzip(zip_path, temp_dir) 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu server_path = os.path.join(temp_dir, 'chromedriver') 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu util.RunCommand(['strip', server_path]) 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu zip_path = util.Zip(server_path) 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) slave_utils.GSUtilCopy( 2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu zip_path, '%s/%s/%s' % (GS_CHROMEDRIVER_BUCKET, version, release_name)) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _MaybeUploadReleaseNotes(version) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _MaybeUpdateLatestRelease(version) 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _GetWebPageContent(url): 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Return the content of the web page specified by the given url.""" 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return urllib2.urlopen(url).read() 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _MaybeUploadReleaseNotes(version): 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Upload release notes if conditions are right.""" 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Check if the current version has already been released. 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) notes_name = 'notes.txt' 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) notes_url = '%s/%s/%s' % (GS_CHROMEDRIVER_BUCKET, version, notes_name) 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) prev_version = '.'.join([version.split('.')[0], 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) str(int(version.split('.')[1]) - 1)]) 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) prev_notes_url = '%s/%s/%s' % ( 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GS_CHROMEDRIVER_BUCKET, prev_version, notes_name) 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result, _ = slave_utils.GSUtilListBucket(notes_url, []) 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if result == 0: 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fixed_issues = [] 319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) query = ('https://code.google.com/p/chromedriver/issues/csv?' 320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'q=status%3AToBeReleased&colspec=ID%20Summary') 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) issues = StringIO.StringIO(_GetWebPageContent(query).split('\n', 1)[1]) 322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for issue in csv.reader(issues): 323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if not issue: 324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) continue 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) issue_id = issue[0] 326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) desc = issue[1] 327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) labels = issue[2] 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fixed_issues += ['Resolved issue %s: %s [%s]' % (issue_id, desc, labels)] 329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) old_notes = '' 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) temp_notes_fname = tempfile.mkstemp()[1] 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if not slave_utils.GSUtilDownloadFile(prev_notes_url, temp_notes_fname): 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) with open(temp_notes_fname, 'rb') as f: 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) old_notes = f.read() 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_notes = '----------ChromeDriver v%s (%s)----------\n%s\n%s\n\n%s' % ( 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) version, datetime.date.today().isoformat(), 3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'Supports Chrome v%s-%s' % _GetSupportedChromeVersions(), 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '\n'.join(fixed_issues), 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) old_notes) 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) with open(temp_notes_fname, 'w') as f: 342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) f.write(new_notes) 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if slave_utils.GSUtilCopy(temp_notes_fname, notes_url, mimetype='text/plain'): 345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util.MarkBuildStepError() 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _MaybeUpdateLatestRelease(version): 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Update the file LATEST_RELEASE with the latest release version number.""" 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) latest_release_fname = 'LATEST_RELEASE' 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) latest_release_url = '%s/%s' % (GS_CHROMEDRIVER_BUCKET, latest_release_fname) 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Check if LATEST_RELEASE is up-to-date. 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) latest_released_version = _GetWebPageContent( 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '%s/%s' % (GS_CHROMEDRIVER_RELEASE_URL, latest_release_fname)) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if version == latest_released_version: 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Check if chromedriver was released on all supported platforms. 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) supported_platforms = ['linux32', 'linux64', 'mac32', 'win32'] 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for platform in supported_platforms: 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not _WasReleased(version, platform): 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepStart('updating LATEST_RELEASE to %s' % version) 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) temp_latest_release_fname = tempfile.mkstemp()[1] 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with open(temp_latest_release_fname, 'w') as f: 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(version) 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if slave_utils.GSUtilCopy(temp_latest_release_fname, latest_release_url, 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mimetype='text/plain'): 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepError() 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _CleanTmpDir(): 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tmp_dir = tempfile.gettempdir() 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) print 'cleaning temp directory:', tmp_dir 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for file_name in os.listdir(tmp_dir): 3790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_path = os.path.join(tmp_dir, file_name) 3800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if os.path.isdir(file_path): 3810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) print 'deleting sub-directory', file_path 3820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) shutil.rmtree(file_path, True) 3830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if file_name.startswith('chromedriver_'): 3840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) print 'deleting file', file_path 3850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) os.remove(file_path) 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidef _GetCommitPositionFromGitHash(snapshot_hashcode): 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci json_url = GS_GIT_LOG_URL % snapshot_hashcode 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch try: 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response = urllib2.urlopen(json_url) 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch except urllib2.HTTPError as error: 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch util.PrintAndFlush('HTTP Error %d' % error.getcode()) 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch except urllib2.URLError as error: 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch util.PrintAndFlush('URL Error %s' % error.message) 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return None 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data = json.loads(response.read()[4:]) 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if 'message' in data: 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch message = data['message'].split('\n') 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch message = [line for line in message if line.strip()] 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch search_pattern = re.compile(GS_SEARCH_PATTERN) 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = search_pattern.search(message[len(message)-1]) 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if result: 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return result.group(1) 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch util.PrintAndFlush('Failed to get svn revision number for %s' % 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch snapshot_hashcode) 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return None 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidef _GetGitHashFromCommitPosition(commit_position): 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci json_url = CR_REV_URL % commit_position 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci try: 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response = urllib2.urlopen(json_url) 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci except urllib2.HTTPError as error: 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci util.PrintAndFlush('HTTP Error %d' % error.getcode()) 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci except urllib2.URLError as error: 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci util.PrintAndFlush('URL Error %s' % error.message) 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci data = json.loads(response.read()) 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if 'git_sha' in data: 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return data['git_sha'] 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci util.PrintAndFlush('Failed to get git hash for %s' % commit_position) 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _WaitForLatestSnapshot(revision): 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util.MarkBuildStepStart('wait_for_snapshot') 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def _IsRevisionNumber(revision): 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if isinstance(revision, int): 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return True 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else: 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return revision.isdigit() 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) while True: 436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) snapshot_revision = archive.GetLatestSnapshotVersion() 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if not _IsRevisionNumber(snapshot_revision): 4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci snapshot_revision = _GetCommitPositionFromGitHash(snapshot_revision) 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if revision is not None and snapshot_revision is not None: 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if int(snapshot_revision) >= int(revision): 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (revision, snapshot_revision)) 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) time.sleep(60) 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision) 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def _AddToolsToPath(platform_name): 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Add some tools like Ant and Java to PATH for testing steps to use.""" 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) paths = [] 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_message = '' 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if platform_name == 'win32': 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) paths = [ 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Path to Ant and Java, required for the java acceptance tests. 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'C:\\Program Files (x86)\\Java\\ant\\bin', 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'C:\\Program Files (x86)\\Java\\jre\\bin', 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ] 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_message = ('Java test steps will fail as expected and ' 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'they can be ignored.\n' 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Ant, Java or others might not be installed on bot.\n' 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Please refer to page "WATERFALL" on site ' 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'go/chromedriver.') 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if paths: 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepStart('Add tools to PATH') 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path_missing = False 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for path in paths: 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not os.path.isdir(path) or not os.listdir(path): 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print 'Directory "%s" is not found or empty.' % path 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path_missing = True 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if path_missing: 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) print error_message 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepError() 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) os.environ['PATH'] += os.pathsep + os.pathsep.join(paths) 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def main(): 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser = optparse.OptionParser() 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option( 4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '', '--android-packages', 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) help=('Comma separated list of application package names, ' 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'if running tests on Android.')) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option( 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '-r', '--revision', help='Chromium revision') 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parser.add_option( 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '', '--update-log', action='store_true', 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) help='Update the test results log (only applicable to Android)') 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options, _ = parser.parse_args() 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bitness = '32' 491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if util.IsLinux() and platform_module.architecture()[0] == '64bit': 492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bitness = '64' 493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) platform = '%s%s' % (util.GetPlatformName(), bitness) 494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if options.android_packages: 495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) platform = 'android' 496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _CleanTmpDir() 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if not options.revision: 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci commit_position = None 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci elif options.revision.isdigit(): 5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci commit_position = options.revision 5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else: 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci commit_position = _GetCommitPositionFromGitHash(options.revision) 5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if platform == 'android': 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if not options.revision and options.update_log: 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) parser.error('Must supply a --revision with --update-log') 5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) _DownloadPrebuilts() 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if not options.revision: 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.error('Must supply a --revision') 513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if platform == 'linux64': 5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _ArchivePrebuilts(commit_position) 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _WaitForLatestSnapshot(commit_position) 51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _AddToolsToPath(platform) 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd = [ 52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sys.executable, 521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch os.path.join(_THIS_DIR, 'test', 'run_all_tests.py'), 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ] 523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if platform == 'android': 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cmd.append('--android-packages=' + options.android_packages) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) passed = (util.RunCommand(cmd) == 0) 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) _ArchiveServerLogs() 5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if platform == 'android': 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if options.update_log: 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) util.MarkBuildStepStart('update test result log') 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _UpdateTestResultsLog(platform, commit_position, passed) 534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) elif passed: 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _ArchiveGoodBuild(platform, commit_position) 536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) _MaybeRelease(platform) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not passed: 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Make sure the build is red if there is some uncaught exception during 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # running run_all_tests.py. 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepStart('run_all_tests.py') 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepError() 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Add a "cleanup" step so that errors from runtest.py or bb_device_steps.py 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # (which invoke this script) are kept in thier own build step. 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.MarkBuildStepStart('cleanup') 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__': 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) main() 551