1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#!/usr/bin/env python 2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Copyright 2015 The Chromium Authors. All rights reserved. 3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Use of this source code is governed by a BSD-style license that can be 4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# found in the LICENSE file. 5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport logging 7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport os 8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport shutil 9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport stat 10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport subprocess 11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport sys 12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport tempfile 13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport time 14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport urllib2 15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport zipfile 16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# URL on omahaproxy.appspot.com which lists cloud storage buckets. 18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikOMAHA_URL = 'https://omahaproxy.appspot.com/all?os=%s&channel=stable' 19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# URL in cloud storage to download Chrome zip from. 21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikCLOUDSTORAGE_URL = ('https://commondatastorage.googleapis.com/chrome-unsigned' 22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '/desktop-W15K3Y/%s/%s/chrome-%s.zip') 23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Mapping of sys.platform -> platform-specific names and paths. 25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikPLATFORM_MAPPING = { 26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'linux2': { 27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'omaha': 'linux', 28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_dir': 'precise64', 29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_filename': 'precise64', 30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'chromepath': 'chrome-precise64/chrome', 31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'use_xfvb': True, 32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'win32': { 34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'omaha': 'win', 35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_dir': 'win', 36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_filename': 'win', 37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'chromepath': 'Chrome-bin\\chrome.exe', 38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'installer_url': ('https://commondatastorage.googleapis.com/' 39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'chrome-signed/desktop-W15K3Y/%VERSION%/win/' 40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '%VERSION%_chrome_installer.exe'), 41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'darwin': { 43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'omaha': 'mac', 44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_dir': 'mac64', 45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'cs_filename': 'mac', 46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'chromepath': ('chrome-mac/Google Chrome.app/' 47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'Contents/MacOS/Google Chrome'), 48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'additional_paths': [ 49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ('chrome-mac/Google Chrome.app/Contents/Versions/%VERSION%/' 50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'Google Chrome Helper.app/Contents/MacOS/Google Chrome Helper'), 51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ], 52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik} 54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef StartXvfb(): 57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik display = ':99' 58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik xvfb_command = [ 59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'Xvfb', 60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik display, 61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '-screen', 62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '0', 63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '1024x769x24', 64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '-ac' 65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ] 66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik xvfb_process = subprocess.Popen( 67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik xvfb_command, stdout=open(os.devnull), stderr=open(os.devnull)) 68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik time.sleep(0.2) 69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik returncode = xvfb_process.poll() 70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if returncode is None: 71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik os.environ['DISPLAY'] = display 72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error('Xvfb did not start, returncode: %s', returncode) 74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef IsDepotToolsPath(path): 77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return os.path.isfile(os.path.join(path, 'gclient')) 78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef FindDepotTools(): 81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Check if depot_tools is already in PYTHONPATH 82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for path in sys.path: 83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if path.rstrip(os.sep).endswith('depot_tools') and IsDepotToolsPath(path): 84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return path 85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Check if depot_tools is in the path 87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for path in os.environ['PATH'].split(os.pathsep): 88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if IsDepotToolsPath(path): 89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return path.rstrip(os.sep) 90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return None 92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef DownloadSignedWinChromeStable(url, version): 95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """On Windows, use signed Chrome since it may be more stable.""" 96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik url = url.replace('%VERSION%', version) 97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tmpdir = tempfile.mkdtemp() 98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik installer_path = os.path.join(tmpdir, url[url.rindex('/') + 1:]) 99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik with open(installer_path, 'wb') as local_file: 100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik local_file.write(urllib2.urlopen(url).read()) 101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik depot_tools_path = FindDepotTools() 102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik path_7z = os.path.join(depot_tools_path, 'win_toolchain', '7z', '7z.exe') 103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik command_7z = [path_7z, 'x', '-o' + tmpdir, installer_path] 104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik process_7z = subprocess.Popen( 105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik command_7z, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik out_7z, err_7z = process_7z.communicate() 107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik command_7z = [path_7z, 'x', '-o' + tmpdir, os.path.join(tmpdir, 'chrome.7z')] 108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik process_7z = subprocess.Popen( 109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik command_7z, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik out_7z, err_7z = process_7z.communicate() 111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return tmpdir, version 112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef DownloadChromeStable(): 115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik platform_data = PLATFORM_MAPPING[sys.platform] 116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik omaha_platform = platform_data['omaha'] 117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik omaha_url = OMAHA_URL % omaha_platform 118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik response = urllib2.urlopen(omaha_url) 119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik version = response.readlines()[1].split(',')[2] 120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if 'installer_url' in platform_data: 121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return DownloadSignedWinChromeStable( 122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik platform_data['installer_url'], version) 123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik cs_url = CLOUDSTORAGE_URL % ( 124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik version, 125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik platform_data['cs_dir'], 126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik platform_data['cs_filename']) 127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tmpdir = tempfile.mkdtemp() 128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik zip_path = os.path.join(tmpdir, 'chrome.zip') 129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik with open(zip_path, 'wb') as local_file: 130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik local_file.write(urllib2.urlopen(cs_url).read()) 131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik zf = zipfile.ZipFile(zip_path) 132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik zf.extractall(path=tmpdir) 133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return tmpdir, version 134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef main(): 137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik try: 138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik platform_data = PLATFORM_MAPPING[sys.platform] 139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if platform_data.get('use_xfvb'): 140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik StartXvfb() 141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik user_data_dir = tempfile.mkdtemp() 142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tmpdir, version = DownloadChromeStable() 143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_path = os.path.join(os.path.dirname( 144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik os.path.abspath(__file__)), os.pardir, 'run_dev_server') 145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_command = [server_path, '--no-install-hooks'] 146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if sys.platform.startswith('win'): 147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_command = ['python.exe'] + server_command 148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_process = subprocess.Popen( 149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik time.sleep(5) 151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_path = os.path.join( 153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tmpdir, platform_data['chromepath']) 154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik os.chmod(chrome_path, os.stat(chrome_path).st_mode | stat.S_IEXEC) 155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if platform_data.get('additional_paths'): 156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for path in platform_data.get('additional_paths'): 157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik path = path.replace('%VERSION%', version) 158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik path = os.path.join(tmpdir, path) 159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik os.chmod(path, os.stat(path).st_mode | stat.S_IEXEC) 160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_command = [ 161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_path, 162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '--user-data-dir=%s' % user_data_dir, 163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '--no-sandbox', 164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '--no-experiments', 165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '--no-first-run', 166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik '--noerrdialogs', 167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'http://localhost:8003/base/tests.html?headless=true&testTypeToRun=all', 168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ] 169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_process = subprocess.Popen( 170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server_out, server_err = server_process.communicate() 172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik chrome_process.kill() 173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if server_process.returncode != 0: 174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error('Tests failed!') 175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error('Server stderr:') 176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error(server_err) 177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error('Server stdout:') 178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik logging.error(server_out) 179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik print server_out 181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik finally: 182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Wait for Chrome to be killed before deleting temp Chrome dir. 183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik time.sleep(5) 184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik shutil.rmtree(tmpdir) 185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik shutil.rmtree(user_data_dir) 186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik sys.exit(server_process.returncode) 188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikif __name__ == "__main__": 192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik main() 193