summaryrefslogtreecommitdiff
path: root/chromium/testing/xvfb.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/testing/xvfb.py')
-rwxr-xr-xchromium/testing/xvfb.py133
1 files changed, 133 insertions, 0 deletions
diff --git a/chromium/testing/xvfb.py b/chromium/testing/xvfb.py
new file mode 100755
index 00000000000..6ac00567101
--- /dev/null
+++ b/chromium/testing/xvfb.py
@@ -0,0 +1,133 @@
+#!/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 0
+ return proc.pid
+
+
+def wait_for_xvfb(xdisplaycheck, env):
+ """Waits for xvfb to be fully initialized by using xdisplaycheck."""
+ try:
+ subprocess.check_call(
+ [xdisplaycheck],
+ stdout=subprocess.PIPE,
+ 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:
+ print >> sys.stderr, (
+ 'Xvfb failed to load properly while trying to run %s' % 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 icewm 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'
+ pid = start_xvfb(xvfb, display)
+ if not pid:
+ return 1
+ env['DISPLAY'] = display
+ if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
+ 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:
+ ice_cmd = ['icewm']
+ subprocess.Popen(
+ ice_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
+ except OSError:
+ print >> sys.stderr, 'Failed to run %s' % ' '.join(ice_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())