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