OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Helper tools to manage a Virtual X buffer with Xvfb.""" |
| 6 |
| 7 import commands |
| 8 import logging |
| 9 import os |
| 10 import signal |
| 11 import subprocess |
| 12 import tempfile |
| 13 |
| 14 |
| 15 def _XvfbPidFilename(unique_name): |
| 16 """Returns the filename to the Xvfb pid file. This name is unique for each |
| 17 builder. This is used by the linux builders.""" |
| 18 return os.path.join(tempfile.gettempdir(), 'xvfb-%s.pid' % unique_name) |
| 19 |
| 20 |
| 21 def start_virtualx(unique_name, path=None, display=':9'): |
| 22 """Start a virtual X server and set the DISPLAY environment variable so sub |
| 23 processes will use the virtual X server. Also start icewm. This only works |
| 24 on Linux and assumes that xvfb and icewm are installed. |
| 25 |
| 26 Args: |
| 27 unique_name: A unique name to identify this X session that is used for the |
| 28 pid file. |
| 29 E.g., webkit-rel-linux. |
| 30 path: (optional) the path where build outputs are generated, xdisplaycheck |
| 31 will be executed to verify Xvfb correctly started. |
| 32 """ |
| 33 # We use a pid file to make sure we don't have any xvfb processes running |
| 34 # from a previous test run. |
| 35 stop_virtualx(unique_name) |
| 36 |
| 37 # Start a virtual X server that we run the tests in. This makes it so we can |
| 38 # run the tests even if we didn't start the tests from an X session. |
| 39 proc = subprocess.Popen( |
| 40 ['Xvfb', display, '-screen', '0', '1024x768x24', '-ac'], |
| 41 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| 42 xvfb_pid_filename = _XvfbPidFilename(unique_name) |
| 43 open(xvfb_pid_filename, 'w').write(str(proc.pid)) |
| 44 if path: |
| 45 # Verifies that Xvfb has started by using xdisplaycheck. |
| 46 xdisplaycheck_path = os.path.join(path, 'xdisplaycheck') |
| 47 if not os.path.exists(xdisplaycheck_path): |
| 48 raise Exception('%s doesn\'t exist.' % xdisplaycheck_path) |
| 49 logging.info('Verifying Xvfb has started...') |
| 50 status, output = commands.getstatusoutput(xdisplaycheck_path) |
| 51 if status != 0: |
| 52 logging.info('Xvfb return code (None if still running): %s' % proc.poll()) |
| 53 logging.info('Xvfb stdout and stderr:%s' % proc.communicate()) |
| 54 raise Exception(output) |
| 55 logging.info('...OK') |
| 56 # Some ChromeOS tests need a window manager. |
| 57 subprocess.Popen("icewm", stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| 58 return display |
| 59 |
| 60 |
| 61 def stop_virtualx(unique_name): |
| 62 """Try and stop the virtual X server if one was started with StartVirtualX. |
| 63 When the X server dies, it takes down the window manager with it. |
| 64 If a virtual x server is not running, this method does nothing.""" |
| 65 xvfb_pid_filename = _XvfbPidFilename(unique_name) |
| 66 if os.path.exists(xvfb_pid_filename): |
| 67 # If the process doesn't exist, we raise an exception that we can ignore. |
| 68 try: |
| 69 os.kill(int(open(xvfb_pid_filename).read()), signal.SIGKILL) |
| 70 except OSError: |
| 71 pass |
| 72 os.remove(xvfb_pid_filename) |
| 73 |
| 74 |
| 75 class Xvfb(object): |
| 76 def __init__(self, unique_name): |
| 77 self.unique_name = unique_name |
| 78 |
| 79 def start(self, build=None): |
| 80 start_virtualx(self.unique_name, build) |
| 81 |
| 82 def stop(self): |
| 83 stop_virtualx(self.unique_name) |
OLD | NEW |