Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / testing / xvfb.py
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.
5
6 """Runs the test with xvfb on linux. Runs the test normally on other platforms.
7
8 For simplicity in gyp targets, this script just runs the test normal on
9 non-linux platforms.
10 """
11
12 import os
13 import platform
14 import signal
15 import subprocess
16 import sys
17
18 import test_env
19
20
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
29
30
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
41
42
43 def start_xvfb(xvfb_path, display):
44   """Starts a virtual X server that we run the tests in.
45
46   This makes it so we can run the tests even if we didn't start the tests from
47   an X session.
48
49   Args:
50     xvfb_path: Path to Xvfb.
51   """
52   cmd = [xvfb_path, display, '-screen', '0', '1024x768x24', '-ac',
53          '-nolisten', 'tcp']
54   try:
55     proc = subprocess.Popen(
56         cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
57   except OSError:
58     print >> sys.stderr, 'Failed to run %s' % ' '.join(cmd)
59     return
60   return proc
61
62
63 def wait_for_xvfb(xdisplaycheck, env):
64   """Waits for xvfb to be fully initialized by using xdisplaycheck."""
65   try:
66     _logs = subprocess.check_output(
67         [xdisplaycheck],
68         stderr=subprocess.STDOUT,
69         env=env)
70   except OSError:
71     print >> sys.stderr, 'Failed to load %s with cwd=%s' % (
72         xdisplaycheck, os.getcwd())
73     return False
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))
78     return False
79
80   return True
81
82
83 def run_executable(cmd, build_dir, env):
84   """Runs an executable within a xvfb buffer on linux or normally on other
85   platforms.
86
87   Requires that both xvfb and openbox are installed on linux.
88
89   Detects recursion with an environment variable and do not create a recursive X
90   buffer if present.
91   """
92   # First look if we are inside a display.
93   if env.get('_CHROMIUM_INSIDE_XVFB') == '1':
94     # No need to recurse.
95     return test_env.run_executable(cmd, env)
96
97   pid = None
98   xvfb = 'Xvfb'
99   try:
100     if sys.platform == 'linux2':
101       # Defaults to X display 9.
102       display = ':9'
103       xvfb_proc = start_xvfb(xvfb, display)
104       if not xvfb_proc or not xvfb_proc.pid:
105         return 1
106       env['DISPLAY'] = display
107       if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
108         rc = xvfb_proc.poll()
109         if rc is None:
110           print 'Xvfb still running, stopping.'
111           xvfb_proc.terminate()
112         else:
113           print 'Xvfb exited, code %d' % rc
114
115         print 'Xvfb output:'
116         for l in xvfb_proc.communicate()[0].splitlines():
117           print '> %s' % l
118
119         return 3
120       # Inhibit recursion.
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.
124       try:
125         wm_cmd = ['openbox']
126         subprocess.Popen(
127             wm_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
128       except OSError:
129         print >> sys.stderr, 'Failed to run %s' % ' '.join(wm_cmd)
130         return 1
131     return test_env.run_executable(cmd, env)
132   finally:
133     if pid:
134       kill(pid)
135
136
137 def main():
138   if len(sys.argv) < 3:
139     print >> sys.stderr, (
140         'Usage: xvfb.py [path to build_dir] [command args...]')
141     return 2
142   return run_executable(sys.argv[2:], sys.argv[1], os.environ.copy())
143
144
145 if __name__ == "__main__":
146   sys.exit(main())