1 # Copyright (c) 2013 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 # pylint: disable=W0702 6 7 import os 8 import signal 9 import subprocess 10 import sys 11 import time 12 13 14 def _IsLinux(): 15 """Return True if on Linux; else False.""" 16 return sys.platform.startswith('linux') 17 18 19 class Xvfb(object): 20 """Class to start and stop Xvfb if relevant. Nop if not Linux.""" 21 22 def __init__(self): 23 self._pid = 0 24 25 def Start(self): 26 """Start Xvfb and set an appropriate DISPLAY environment. Linux only. 27 28 Copied from tools/code_coverage/coverage_posix.py 29 """ 30 if not _IsLinux(): 31 return 32 proc = subprocess.Popen(['Xvfb', ':9', '-screen', '0', '1024x768x24', 33 '-ac'], 34 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 35 self._pid = proc.pid 36 if not self._pid: 37 raise Exception('Could not start Xvfb') 38 os.environ['DISPLAY'] = ':9' 39 40 # Now confirm, giving a chance for it to start if needed. 41 for _ in range(10): 42 proc = subprocess.Popen('xdpyinfo >/dev/null', shell=True) 43 _, retcode = os.waitpid(proc.pid, 0) 44 if retcode == 0: 45 break 46 time.sleep(0.25) 47 if retcode != 0: 48 raise Exception('Could not confirm Xvfb happiness') 49 50 def Stop(self): 51 """Stop Xvfb if needed. Linux only.""" 52 if self._pid: 53 try: 54 os.kill(self._pid, signal.SIGKILL) 55 except: 56 pass 57 del os.environ['DISPLAY'] 58 self._pid = 0 59