2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Runs the test with xvfb on linux. Runs the test normally on other platforms.
8 For simplicity in gyp targets, this script just runs the test normal on
22 """Kills a process and traps exception if the process doesn't exist anymore.
24 # If the process doesn't exist, it raises an exception that we can ignore.
26 os
.kill(pid
, signal
.SIGKILL
)
31 def get_xvfb_path(server_dir
):
32 """Figures out which X server to use."""
33 xvfb_path
= os
.path
.join(server_dir
, 'Xvfb.' + platform
.architecture()[0])
34 if not os
.path
.exists(xvfb_path
):
35 xvfb_path
= os
.path
.join(server_dir
, 'Xvfb')
36 if not os
.path
.exists(xvfb_path
):
37 print >> sys
.stderr
, (
38 'No Xvfb found in designated server path: %s' % server_dir
)
39 raise Exception('No virtual server')
43 def start_xvfb(xvfb_path
, display
):
44 """Starts a virtual X server that we run the tests in.
46 This makes it so we can run the tests even if we didn't start the tests from
50 xvfb_path: Path to Xvfb.
52 cmd
= [xvfb_path
, display
, '-screen', '0', '1024x768x24', '-ac',
53 '-nolisten', 'tcp', '-dpi', '96']
55 proc
= subprocess
.Popen(
56 cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.STDOUT
)
58 print >> sys
.stderr
, 'Failed to run %s' % ' '.join(cmd
)
63 def wait_for_xvfb(xdisplaycheck
, env
):
64 """Waits for xvfb to be fully initialized by using xdisplaycheck."""
66 _logs
= subprocess
.check_output(
68 stderr
=subprocess
.STDOUT
,
71 print >> sys
.stderr
, 'Failed to load %s with cwd=%s' % (
72 xdisplaycheck
, os
.getcwd())
74 except subprocess
.CalledProcessError
as e
:
75 print >> sys
.stderr
, (
76 'Xvfb failed to load properly (code %d) according to %s' %
77 (e
.returncode
, xdisplaycheck
))
83 def run_executable(cmd
, build_dir
, env
):
84 """Runs an executable within a xvfb buffer on linux or normally on other
87 Requires that both xvfb and openbox are installed on linux.
89 Detects recursion with an environment variable and do not create a recursive X
92 # First look if we are inside a display.
93 if env
.get('_CHROMIUM_INSIDE_XVFB') == '1':
95 return test_env
.run_executable(cmd
, env
)
100 if sys
.platform
== 'linux2':
101 # Defaults to X display 9.
103 xvfb_proc
= start_xvfb(xvfb
, display
)
104 if not xvfb_proc
or not xvfb_proc
.pid
:
106 env
['DISPLAY'] = display
107 if not wait_for_xvfb(os
.path
.join(build_dir
, 'xdisplaycheck'), env
):
108 rc
= xvfb_proc
.poll()
110 print 'Xvfb still running, stopping.'
111 xvfb_proc
.terminate()
113 print 'Xvfb exited, code %d' % rc
116 for l
in xvfb_proc
.communicate()[0].splitlines():
121 env
['_CHROMIUM_INSIDE_XVFB'] = '1'
122 # Some ChromeOS tests need a window manager. Technically, it could be
123 # another script but that would be overkill.
127 wm_cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.STDOUT
, env
=env
)
129 print >> sys
.stderr
, 'Failed to run %s' % ' '.join(wm_cmd
)
131 return test_env
.run_executable(cmd
, env
)
133 # When the X server dies, it takes down the window manager with it.
134 if xvfb_proc
and xvfb_proc
.pid
:
139 if len(sys
.argv
) < 3:
140 print >> sys
.stderr
, (
141 'Usage: xvfb.py [path to build_dir] [command args...]')
143 return run_executable(sys
.argv
[2:], sys
.argv
[1], os
.environ
.copy())
146 if __name__
== "__main__":