skia/ext: Early out from analysis when we have more than 1 draw op.
[chromium-blink-merge.git] / testing / xvfb.py
blobb78846983affdb60f8af15da7151cdf2c1779d83
1 #!/usr/bin/env python
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
9 non-linux platforms.
10 """
12 import os
13 import platform
14 import signal
15 import subprocess
16 import sys
18 import test_env
21 def kill(pid):
22 """Kills a process and traps exception if the process doesn't exist anymore.
23 """
24 # If the process doesn't exist, it raises an exception that we can ignore.
25 try:
26 os.kill(pid, signal.SIGKILL)
27 except OSError:
28 pass
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')
40 return xvfb_path
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
47 an X session.
49 Args:
50 xvfb_path: Path to Xvfb.
51 """
52 cmd = [xvfb_path, display, '-screen', '0', '1024x768x24', '-ac']
53 try:
54 proc = subprocess.Popen(
55 cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
56 except OSError:
57 print >> sys.stderr, 'Failed to run %s' % ' '.join(cmd)
58 return
59 return proc
62 def wait_for_xvfb(xdisplaycheck, env):
63 """Waits for xvfb to be fully initialized by using xdisplaycheck."""
64 try:
65 _logs = subprocess.check_output(
66 [xdisplaycheck],
67 stderr=subprocess.STDOUT,
68 env=env)
69 except OSError:
70 print >> sys.stderr, 'Failed to load %s with cwd=%s' % (
71 xdisplaycheck, os.getcwd())
72 return False
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))
77 return False
79 return True
82 def run_executable(cmd, build_dir, env):
83 """Runs an executable within a xvfb buffer on linux or normally on other
84 platforms.
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
89 buffer if present.
90 """
91 # First look if we are inside a display.
92 if env.get('_CHROMIUM_INSIDE_XVFB') == '1':
93 # No need to recurse.
94 return test_env.run_executable(cmd, env)
96 pid = None
97 xvfb = 'Xvfb'
98 try:
99 if sys.platform == 'linux2':
100 # Defaults to X display 9.
101 display = ':9'
102 xvfb_proc = start_xvfb(xvfb, display)
103 if not xvfb_proc or not xvfb_proc.pid:
104 return 1
105 env['DISPLAY'] = display
106 if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
107 rc = xvfb_proc.poll()
108 if rc is None:
109 print 'Xvfb still running, stopping.'
110 xvfb_proc.terminate()
111 else:
112 print 'Xvfb exited, code %d' % rc
114 print 'Xvfb output:'
115 for l in xvfb_proc.communicate()[0].splitlines():
116 print '> %s' % l
118 return 3
119 # Inhibit recursion.
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.
123 try:
124 wm_cmd = ['openbox']
125 subprocess.Popen(
126 wm_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
127 except OSError:
128 print >> sys.stderr, 'Failed to run %s' % ' '.join(wm_cmd)
129 return 1
130 return test_env.run_executable(cmd, env)
131 finally:
132 if pid:
133 kill(pid)
136 def main():
137 if len(sys.argv) < 3:
138 print >> sys.stderr, (
139 'Usage: xvfb.py [path to build_dir] [command args...]')
140 return 2
141 return run_executable(sys.argv[2:], sys.argv[1], os.environ.copy())
144 if __name__ == "__main__":
145 sys.exit(main())