1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#!/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
return proc
def wait_for_xvfb(xdisplaycheck, env):
"""Waits for xvfb to be fully initialized by using xdisplaycheck."""
try:
_logs = subprocess.check_output(
[xdisplaycheck],
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 as e:
print >> sys.stderr, (
'Xvfb failed to load properly (code %d) according to %s' %
(e.returncode, 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 openbox 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'
xvfb_proc = start_xvfb(xvfb, display)
if not xvfb_proc or not xvfb_proc.pid:
return 1
env['DISPLAY'] = display
if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
rc = xvfb_proc.poll()
if rc is None:
print 'Xvfb still running, stopping.'
xvfb_proc.terminate()
else:
print 'Xvfb exited, code %d' % rc
print 'Xvfb output:'
for l in xvfb_proc.communicate()[0].splitlines():
print '> %s' % l
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:
wm_cmd = ['openbox']
subprocess.Popen(
wm_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
except OSError:
print >> sys.stderr, 'Failed to run %s' % ' '.join(wm_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())
|