blob: 4f21b156caf05ee2f768175aede99b53a7ab4d3a [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os
import shutil
import stat
import subprocess
import sys
import tempfile
import time
import urllib2
import zipfile
# URL on omahaproxy.appspot.com which lists cloud storage buckets.
OMAHA_URL = 'https://omahaproxy.appspot.com/all?os=%s&channel=stable'
# URL in cloud storage to download Chrome zip from.
CLOUDSTORAGE_URL = ('https://commondatastorage.googleapis.com/chrome-unsigned'
'/desktop-W15K3Y/%s/%s/chrome-%s.zip')
# Mapping of sys.platform -> platform-specific names and paths.
PLATFORM_MAPPING = {
'linux2': {
'omaha': 'linux',
'cs_dir': 'precise64',
'cs_filename': 'precise64',
'chromepath': 'chrome-precise64/chrome',
'use_xfvb': True,
},
'win32': {
'omaha': 'win',
'cs_dir': 'win',
'cs_filename': 'win',
'chromepath': 'Chrome-bin\\chrome.exe',
'installer_url': ('https://commondatastorage.googleapis.com/'
'chrome-signed/desktop-W15K3Y/%VERSION%/win/'
'%VERSION%_chrome_installer.exe'),
},
'darwin': {
'omaha': 'mac',
'cs_dir': 'mac64',
'cs_filename': 'mac',
'chromepath': ('chrome-mac/Google Chrome.app/'
'Contents/MacOS/Google Chrome'),
'additional_paths': [
('chrome-mac/Google Chrome.app/Contents/Versions/%VERSION%/'
'Google Chrome Helper.app/Contents/MacOS/Google Chrome Helper'),
],
},
}
def StartXvfb():
display = ':99'
xvfb_command = [
'Xvfb',
display,
'-screen',
'0',
'1024x769x24',
'-ac'
]
xvfb_process = subprocess.Popen(
xvfb_command, stdout=open(os.devnull), stderr=open(os.devnull))
time.sleep(0.2)
returncode = xvfb_process.poll()
if returncode is None:
os.environ['DISPLAY'] = display
else:
logging.error('Xvfb did not start, returncode: %s', returncode)
def IsDepotToolsPath(path):
return os.path.isfile(os.path.join(path, 'gclient'))
def FindDepotTools():
# Check if depot_tools is already in PYTHONPATH
for path in sys.path:
if path.rstrip(os.sep).endswith('depot_tools') and IsDepotToolsPath(path):
return path
# Check if depot_tools is in the path
for path in os.environ['PATH'].split(os.pathsep):
if IsDepotToolsPath(path):
return path.rstrip(os.sep)
return None
def DownloadSignedWinChromeStable(url, version):
"""On Windows, use signed Chrome since it may be more stable."""
url = url.replace('%VERSION%', version)
tmpdir = tempfile.mkdtemp()
installer_path = os.path.join(tmpdir, url[url.rindex('/') + 1:])
with open(installer_path, 'wb') as local_file:
local_file.write(urllib2.urlopen(url).read())
depot_tools_path = FindDepotTools()
path_7z = os.path.join(depot_tools_path, 'win_toolchain', '7z', '7z.exe')
command_7z = [path_7z, 'x', '-o' + tmpdir, installer_path]
process_7z = subprocess.Popen(
command_7z, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_7z, err_7z = process_7z.communicate()
command_7z = [path_7z, 'x', '-o' + tmpdir, os.path.join(tmpdir, 'chrome.7z')]
process_7z = subprocess.Popen(
command_7z, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_7z, err_7z = process_7z.communicate()
return tmpdir, version
def DownloadChromeStable():
platform_data = PLATFORM_MAPPING[sys.platform]
omaha_platform = platform_data['omaha']
omaha_url = OMAHA_URL % omaha_platform
response = urllib2.urlopen(omaha_url)
version = response.readlines()[1].split(',')[2]
if 'installer_url' in platform_data:
return DownloadSignedWinChromeStable(
platform_data['installer_url'], version)
cs_url = CLOUDSTORAGE_URL % (
version,
platform_data['cs_dir'],
platform_data['cs_filename'])
tmpdir = tempfile.mkdtemp()
zip_path = os.path.join(tmpdir, 'chrome.zip')
with open(zip_path, 'wb') as local_file:
local_file.write(urllib2.urlopen(cs_url).read())
zf = zipfile.ZipFile(zip_path)
zf.extractall(path=tmpdir)
return tmpdir, version
def main():
try:
platform_data = PLATFORM_MAPPING[sys.platform]
if platform_data.get('use_xfvb'):
StartXvfb()
user_data_dir = tempfile.mkdtemp()
tmpdir, version = DownloadChromeStable()
server_path = os.path.join(os.path.dirname(
os.path.abspath(__file__)), os.pardir, 'run_dev_server')
server_command = [server_path, '--no-install-hooks']
if sys.platform.startswith('win'):
server_command = ['python.exe'] + server_command
server_process = subprocess.Popen(
server_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(5)
chrome_path = os.path.join(
tmpdir, platform_data['chromepath'])
os.chmod(chrome_path, os.stat(chrome_path).st_mode | stat.S_IEXEC)
if platform_data.get('additional_paths'):
for path in platform_data.get('additional_paths'):
path = path.replace('%VERSION%', version)
path = os.path.join(tmpdir, path)
os.chmod(path, os.stat(path).st_mode | stat.S_IEXEC)
chrome_command = [
chrome_path,
'--user-data-dir=%s' % user_data_dir,
'--no-sandbox',
'--no-experiments',
'--no-first-run',
'--noerrdialogs',
'http://localhost:8003/base/tests.html?headless=true&testTypeToRun=all',
]
chrome_process = subprocess.Popen(
chrome_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
server_out, server_err = server_process.communicate()
chrome_process.kill()
if server_process.returncode != 0:
logging.error('Tests failed!')
logging.error('Server stderr:')
logging.error(server_err)
logging.error('Server stdout:')
logging.error(server_out)
else:
print server_out
finally:
# Wait for Chrome to be killed before deleting temp Chrome dir.
time.sleep(5)
shutil.rmtree(tmpdir)
shutil.rmtree(user_data_dir)
sys.exit(server_process.returncode)
if __name__ == "__main__":
main()