134 lines
3.7 KiB
Python
134 lines
3.7 KiB
Python
|
#!/usr/bin/env python
|
||
|
# Copyright (c) 2012 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.
|
||
|
|
||
|
"""Runs the test with xvfb on linux. Runs the test normally on other platforms.
|
||
|
|
||
|
For simplicity in gyp targets, this script just runs the test normal on
|
||
|
non-linux platforms.
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
import platform
|
||
|
import signal
|
||
|
import subprocess
|
||
|
import sys
|
||
|
|
||
|
import test_env
|
||
|
|
||
|
|
||
|
def kill(pid):
|
||
|
"""Kills a process and traps exception if the process doesn't exist anymore.
|
||
|
"""
|
||
|
# If the process doesn't exist, it raises an exception that we can ignore.
|
||
|
try:
|
||
|
os.kill(pid, signal.SIGKILL)
|
||
|
except OSError:
|
||
|
pass
|
||
|
|
||
|
|
||
|
def get_xvfb_path(server_dir):
|
||
|
"""Figures out which X server to use."""
|
||
|
xvfb_path = os.path.join(server_dir, 'Xvfb.' + platform.architecture()[0])
|
||
|
if not os.path.exists(xvfb_path):
|
||
|
xvfb_path = os.path.join(server_dir, 'Xvfb')
|
||
|
if not os.path.exists(xvfb_path):
|
||
|
print >> sys.stderr, (
|
||
|
'No Xvfb found in designated server path: %s' % server_dir)
|
||
|
raise Exception('No virtual server')
|
||
|
return xvfb_path
|
||
|
|
||
|
|
||
|
def start_xvfb(xvfb_path, display):
|
||
|
"""Starts a virtual X server that we run the tests in.
|
||
|
|
||
|
This makes it so we can run the tests even if we didn't start the tests from
|
||
|
an X session.
|
||
|
|
||
|
Args:
|
||
|
xvfb_path: Path to Xvfb.
|
||
|
"""
|
||
|
cmd = [xvfb_path, display, '-screen', '0', '1024x768x24', '-ac']
|
||
|
try:
|
||
|
proc = subprocess.Popen(
|
||
|
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||
|
except OSError:
|
||
|
print >> sys.stderr, 'Failed to run %s' % ' '.join(cmd)
|
||
|
return 0
|
||
|
return proc.pid
|
||
|
|
||
|
|
||
|
def wait_for_xvfb(xdisplaycheck, env):
|
||
|
"""Waits for xvfb to be fully initialized by using xdisplaycheck."""
|
||
|
try:
|
||
|
subprocess.check_call(
|
||
|
[xdisplaycheck],
|
||
|
stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.STDOUT,
|
||
|
env=env)
|
||
|
except OSError:
|
||
|
print >> sys.stderr, 'Failed to load %s with cwd=%s' % (
|
||
|
xdisplaycheck, os.getcwd())
|
||
|
return False
|
||
|
except subprocess.CalledProcessError:
|
||
|
print >> sys.stderr, (
|
||
|
'Xvfb failed to load properly while trying to run %s' % xdisplaycheck)
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
|
||
|
def run_executable(cmd, build_dir, env):
|
||
|
"""Runs an executable within a xvfb buffer on linux or normally on other
|
||
|
platforms.
|
||
|
|
||
|
Requires that both xvfb and icewm are installed on linux.
|
||
|
|
||
|
Detects recursion with an environment variable and do not create a recursive X
|
||
|
buffer if present.
|
||
|
"""
|
||
|
# First look if we are inside a display.
|
||
|
if env.get('_CHROMIUM_INSIDE_XVFB') == '1':
|
||
|
# No need to recurse.
|
||
|
return test_env.run_executable(cmd, env)
|
||
|
|
||
|
pid = None
|
||
|
xvfb = 'Xvfb'
|
||
|
try:
|
||
|
if sys.platform == 'linux2':
|
||
|
# Defaults to X display 9.
|
||
|
display = ':9'
|
||
|
pid = start_xvfb(xvfb, display)
|
||
|
if not pid:
|
||
|
return 1
|
||
|
env['DISPLAY'] = display
|
||
|
if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
|
||
|
return 3
|
||
|
# Inhibit recursion.
|
||
|
env['_CHROMIUM_INSIDE_XVFB'] = '1'
|
||
|
# Some ChromeOS tests need a window manager. Technically, it could be
|
||
|
# another script but that would be overkill.
|
||
|
try:
|
||
|
ice_cmd = ['icewm']
|
||
|
subprocess.Popen(
|
||
|
ice_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
|
||
|
except OSError:
|
||
|
print >> sys.stderr, 'Failed to run %s' % ' '.join(ice_cmd)
|
||
|
return 1
|
||
|
return test_env.run_executable(cmd, env)
|
||
|
finally:
|
||
|
if pid:
|
||
|
kill(pid)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
if len(sys.argv) < 3:
|
||
|
print >> sys.stderr, (
|
||
|
'Usage: xvfb.py [path to build_dir] [command args...]')
|
||
|
return 2
|
||
|
return run_executable(sys.argv[2:], sys.argv[1], os.environ.copy())
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
sys.exit(main())
|