Skip to content

Commit 3767bac

Browse files
Merge pull request #68 from benoit-pierre/tests_handling
Rework tests handling
2 parents 881da1d + 4e555e1 commit 3767bac

3 files changed

Lines changed: 136 additions & 8 deletions

File tree

.travis.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,9 @@ install:
1111
- pip install -r requirements.txt
1212
- pip install -r dev-requirements.txt
1313

14-
before_script:
15-
- "export DISPLAY=:99.0"
16-
- "sh -e /etc/init.d/xvfb start"
17-
- sleep 3 # give xvfb some time to start
18-
- xauth generate :99.0 . trusted
19-
2014
# command to run tests
21-
script:
22-
nosetests --exe --with-xunit --with-coverage --cover-html --cover-html-dir=Coverage_report --verbosity=3 test/ examples/run_examples.py
15+
script:
16+
python runtests.py --with-coverage --cover-html --cover-html-dir=Coverage_report
2317

2418
after_success:
2519
- codecov

runtests.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env python
2+
3+
# Python 2/3 compatibility.
4+
from __future__ import print_function
5+
6+
import os
7+
import signal
8+
import subprocess
9+
import sys
10+
import tempfile
11+
12+
from pkg_resources import load_entry_point
13+
14+
15+
class SigException(BaseException):
16+
def __init__(self, signum):
17+
super(SigException, self).__init__()
18+
self.signum = signum
19+
20+
def xsession_sighandler(signum, frame):
21+
raise SigException(signum)
22+
23+
def xserver_start(display, executable='Xvfb', authfile=None):
24+
pid = os.fork()
25+
if pid != 0:
26+
return pid
27+
if authfile is None:
28+
authfile = os.devnull
29+
# This will make the xserver send us a SIGUSR1 when ready.
30+
signal.signal(signal.SIGUSR1, signal.SIG_IGN)
31+
cmd = [
32+
executable,
33+
'-auth', authfile,
34+
'-noreset',
35+
display,
36+
]
37+
print('starting xserver: `{0}`'.format(' '.join(cmd)))
38+
os.execlp(cmd[0], *cmd)
39+
40+
def tests_run(display, authfile=None):
41+
pid = os.fork()
42+
if pid != 0:
43+
return pid
44+
if authfile is None:
45+
authfile = os.devnull
46+
os.environ['DISPLAY'] = display
47+
os.environ['XAUTHORITY'] = authfile
48+
cmd = [
49+
'nosetests',
50+
'--exe', '--with-xunit', '--verbosity=3',
51+
]
52+
has_custom_tests = False
53+
for arg in sys.argv[1:]:
54+
if not arg.startswith('-'):
55+
has_custom_tests = True
56+
cmd.append(arg)
57+
if not has_custom_tests:
58+
cmd.extend(('test/', 'examples/run_examples.py'))
59+
print('running tests: `{0}`'.format(' '.join(cmd)))
60+
sys.argv = cmd
61+
try:
62+
load_entry_point('nose', 'console_scripts', 'nosetests')()
63+
except SystemExit as err:
64+
code = err.code
65+
else:
66+
code = 0
67+
os._exit(code)
68+
69+
70+
def runtests():
71+
72+
cleanup_funcs = []
73+
74+
try:
75+
if hasattr(sys, 'pypy_version_info'):
76+
server_display = ':8'
77+
else:
78+
server_display = ':9'
79+
server_display += ''.join(str(n) for n in sys.version_info[:3])
80+
81+
# Setup a temporary authentication file.
82+
cookie = subprocess.check_output('mcookie').strip()
83+
authfile = tempfile.NamedTemporaryFile(delete=False)
84+
cleanup_funcs.append(lambda: os.unlink(authfile.name))
85+
authfile.close()
86+
subprocess.check_call((
87+
'xauth',
88+
'-f', authfile.name,
89+
'add', server_display, '.', cookie,
90+
))
91+
92+
# Setup signal handler to wait for xserver to be ready.
93+
signal.signal(signal.SIGUSR1, xsession_sighandler)
94+
95+
# Start xserver.
96+
server_pid = xserver_start(server_display, authfile=authfile.name)
97+
cleanup_funcs.append(lambda: os.waitpid(server_pid, 0))
98+
cleanup_funcs.append(lambda: os.kill(server_pid, signal.SIGTERM))
99+
100+
# Give the server 3 seconds to start.
101+
signal.alarm(3)
102+
103+
# Wait for server to be ready.
104+
try:
105+
signal.pause()
106+
except SigException as err:
107+
assert signal.SIGUSR1 == err.signum
108+
signal.alarm(0)
109+
110+
# Run tests.
111+
tests_pid = tests_run(server_display, authfile=authfile.name)
112+
pid, status = os.waitpid(tests_pid, 0)
113+
assert pid == tests_pid
114+
sys.exit(status >> 8)
115+
116+
except KeyboardInterrupt:
117+
sys.exit(1)
118+
119+
finally:
120+
for func in reversed(cleanup_funcs):
121+
func()
122+
123+
124+
if __name__ == '__main__':
125+
runtests()

tox.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[tox]
2+
envlist = py27,py33,py34,py35
3+
skip_missing_interpreters = true
4+
5+
[testenv]
6+
deps=
7+
nose
8+
six>=1.10.0
9+
commands={envpython} runtests.py {posargs}

0 commit comments

Comments
 (0)