1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
import os
import sys
import subprocess
from dbusmock import DBusTestCase
# This file has been submitted for inclusion in python-dbusmock
# https://github.com/martinpitt/python-dbusmock/pull/44
if sys.version_info[0] < 3:
PIPE_DEVNULL = open(os.devnull, 'wb')
def Popen(*args, **kwargs):
if 'pass_fds' in kwargs:
pass_fds = kwargs['pass_fds']
del kwargs['pass_fds']
else:
pass_fds = []
orig_preexec_fn = kwargs.get('preexec_fn', None)
def _setup():
for fd in range(3, subprocess.MAXFD):
if fd in pass_fds:
continue
try:
os.close(fd)
except OSError:
pass
if orig_preexec_fn:
orig_preexec_fn()
# Don't let subprocess close FDs for us
kwargs['close_fds'] = False
kwargs['preexec_fn'] = _setup
return subprocess.Popen(*args, **kwargs)
else:
PIPE_DEVNULL = subprocess.DEVNULL
Popen = subprocess.Popen
class X11SessionTestCase(DBusTestCase):
#: The display the X server is running on
X_display = -1
#: The X server to start
Xserver = 'Xvfb'
#: Further parameters for the X server
Xserver_args = ['-screen', '0', '1280x1024x24', '+extension', 'GLX']
#: Where to redirect the X stdout and stderr to. Set to None for debugging
#: purposes if the X server is failing for some reason.
Xserver_output = PIPE_DEVNULL
@classmethod
def setUpClass(klass):
klass.start_xorg()
klass.start_system_bus()
klass.start_session_bus()
@classmethod
def start_xorg(klass):
r, w = os.pipe()
klass.xorg = Popen([klass.Xserver, '-displayfd', "%d" % w, '-noreset'] + klass.Xserver_args,
pass_fds=(w,),
stdout=klass.Xserver_output,
stderr=subprocess.STDOUT)
os.close(w)
# The X server will write "%d\n", we need to make sure to read the "\n".
# If the server dies we get zero bytes reads as EOF is reached.
display = b''
while True:
tmp = os.read(r, 1024)
display += tmp
# Break out if the read was empty or the line feed was read
if not tmp or tmp[-1] == b'\n':
break
os.close(r)
try:
display = int(display.strip())
except ValueError:
# This should never happen, the X server didn't return a proper integer.
# Most likely it died for some odd reason.
# Note: Set Xserver_output to None to debug Xvfb startup issues.
klass.stop_xorg()
raise AssertionError('X server reported back no or an invalid display number (%s)' % (display))
klass.X_display = display
# Export information into our environment for tests to use
os.environ['DISPLAY'] = ":%d" % klass.X_display
if 'GNOME_SETUP_DISPLAY' in os.environ:
del os.environ['GNOME_SETUP_DISPLAY']
if 'WAYLAND_DISPLAY' in os.environ:
del os.environ['WAYLAND_DISPLAY']
# Server should still be up and running at this point
assert klass.xorg.poll() is None
return klass.X_display
@classmethod
def stop_xorg(klass):
if hasattr(klass, 'xorg'):
klass.X_display = -1
klass.xorg.terminate()
klass.xorg.wait()
del klass.xorg
@classmethod
def tearDownClass(klass):
DBusTestCase.tearDownClass()
klass.stop_xorg()
|