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']
54 proc
= subprocess
.Popen(
55 cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.STDOUT
)
57 print >> sys
.stderr
, 'Failed to run %s' % ' '.join(cmd
)
62 def wait_for_xvfb(xdisplaycheck
, env
):
63 """Waits for xvfb to be fully initialized by using xdisplaycheck."""
65 _logs
= subprocess
.check_output(
67 stderr
=subprocess
.STDOUT
,
70 print >> sys
.stderr
, 'Failed to load %s with cwd=%s' % (
71 xdisplaycheck
, os
.getcwd())
73 except subprocess
.CalledProcessError
as e
:
74 print >> sys
.stderr
, (
75 'Xvfb failed to load properly (code %d) according to %s' %
76 (e
.returncode
, xdisplaycheck
))
82 def run_executable(cmd
, build_dir
, env
):
83 """Runs an executable within a xvfb buffer on linux or normally on other
86 Requires that both xvfb and openbox are installed on linux.
88 Detects recursion with an environment variable and do not create a recursive X
91 # First look if we are inside a display.
92 if env
.get('_CHROMIUM_INSIDE_XVFB') == '1':
94 return test_env
.run_executable(cmd
, env
)
99 if sys
.platform
== 'linux2':
100 # Defaults to X display 9.
102 xvfb_proc
= start_xvfb(xvfb
, display
)
103 if not xvfb_proc
or not xvfb_proc
.pid
:
105 env
['DISPLAY'] = display
106 if not wait_for_xvfb(os
.path
.join(build_dir
, 'xdisplaycheck'), env
):
107 rc
= xvfb_proc
.poll()
109 print 'Xvfb still running, stopping.'
110 xvfb_proc
.terminate()
112 print 'Xvfb exited, code %d' % rc
115 for l
in xvfb_proc
.communicate()[0].splitlines():
120 env
['_CHROMIUM_INSIDE_XVFB'] = '1'
121 # Some ChromeOS tests need a window manager. Technically, it could be
122 # another script but that would be overkill.
126 wm_cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.STDOUT
, env
=env
)
128 print >> sys
.stderr
, 'Failed to run %s' % ' '.join(wm_cmd
)
130 return test_env
.run_executable(cmd
, env
)
137 if len(sys
.argv
) < 3:
138 print >> sys
.stderr
, (
139 'Usage: xvfb.py [path to build_dir] [command args...]')
141 return run_executable(sys
.argv
[2:], sys
.argv
[1], os
.environ
.copy())
144 if __name__
== "__main__":