Commit b156ae0c authored by Vincent Pelletier's avatar Vincent Pelletier

test: Stop using multiprocessing module.

Too many issues with processes not willing to shutdown.
Instead, spawn threads, use an event to stop caucased while sleeping,
and make it stop its http[s] servers more gracefully.

Increases realiability of tests, especially when checking coverage.
parent 306f0709
...@@ -2,5 +2,4 @@ ...@@ -2,5 +2,4 @@
branch = true branch = true
concurrency = concurrency =
thread thread
multiprocessing
parallel = true parallel = true
...@@ -25,7 +25,6 @@ import datetime ...@@ -25,7 +25,6 @@ import datetime
from getpass import getpass from getpass import getpass
import glob import glob
import os import os
import signal
import socket import socket
from SocketServer import ThreadingMixIn from SocketServer import ThreadingMixIn
import ssl import ssl
...@@ -267,7 +266,7 @@ def updateSSLContext( ...@@ -267,7 +266,7 @@ def updateSSLContext(
None, None,
).not_valid_after - threshold_delta ).not_valid_after - threshold_delta
def main(argv=None): def main(argv=None, until=utils.until):
""" """
Caucase stand-alone http server. Caucase stand-alone http server.
""" """
...@@ -400,19 +399,6 @@ def main(argv=None): ...@@ -400,19 +399,6 @@ def main(argv=None):
) )
args = parser.parse_args(argv) args = parser.parse_args(argv)
# pylint: disable=unused-argument
def onTERM(signum, stack):
"""
Sigterm handler
"""
# The main objective of this signal hander is to fix coverage scores:
# without it, it seems hits generated by this process do not get
# accounted for (atexit not called ?). With it, interpreter shutdown
# seems nicer.
raise SystemExit
# pylint: enable=unused-argument
signal.signal(signal.SIGTERM, onTERM)
base_url = u'http://' + args.netloc.decode('ascii') base_url = u'http://' + args.netloc.decode('ascii')
parsed_base_url = urlparse(base_url) parsed_base_url = urlparse(base_url)
hostname = parsed_base_url.hostname hostname = parsed_base_url.hostname
...@@ -501,7 +487,7 @@ def main(argv=None): ...@@ -501,7 +487,7 @@ def main(argv=None):
startServerThread(https) startServerThread(https)
try: try:
while True: while True:
now = utils.until(next_deadline) now = until(next_deadline)
if now >= next_ssl_update: if now >= next_ssl_update:
next_ssl_update = updateSSLContext( next_ssl_update = updateSSLContext(
https=https, https=https,
...@@ -537,6 +523,9 @@ def main(argv=None): ...@@ -537,6 +523,9 @@ def main(argv=None):
) )
except utils.SleepInterrupt: except utils.SleepInterrupt:
pass pass
finally:
https.shutdown()
http.shutdown()
def manage(argv=None): def manage(argv=None):
""" """
......
...@@ -27,7 +27,6 @@ import errno ...@@ -27,7 +27,6 @@ import errno
import glob import glob
import ipaddress import ipaddress
import os import os
import multiprocessing
import random import random
import shutil import shutil
import socket import socket
...@@ -35,6 +34,7 @@ import sqlite3 ...@@ -35,6 +34,7 @@ import sqlite3
import sys import sys
import tempfile import tempfile
import time import time
import threading
import urlparse import urlparse
import unittest import unittest
from cryptography import x509 from cryptography import x509
...@@ -99,6 +99,7 @@ class CaucaseTest(unittest.TestCase): ...@@ -99,6 +99,7 @@ class CaucaseTest(unittest.TestCase):
self._client_user_crl = os.path.join(client_dir, 'cau.crl.pem') self._client_user_crl = os.path.join(client_dir, 'cau.crl.pem')
# pylint: enable=bad-whitespace # pylint: enable=bad-whitespace
self._server_event = server_event = threading.Event()
self._server_dir = server_dir = os.path.join(data_dir, 'server') self._server_dir = server_dir = os.path.join(data_dir, 'server')
os.mkdir(server_dir) os.mkdir(server_dir)
# pylint: disable=bad-whitespace # pylint: disable=bad-whitespace
...@@ -124,8 +125,6 @@ class CaucaseTest(unittest.TestCase): ...@@ -124,8 +125,6 @@ class CaucaseTest(unittest.TestCase):
""" """
if self._server.is_alive(): if self._server.is_alive():
self._stopServer() self._stopServer()
else:
print 'Server exited with status: %s' % (self._server.exitcode, )
shutil.rmtree(self._data_dir) shutil.rmtree(self._data_dir)
def _restoreServer( def _restoreServer(
...@@ -156,12 +155,24 @@ class CaucaseTest(unittest.TestCase): ...@@ -156,12 +155,24 @@ class CaucaseTest(unittest.TestCase):
return 1 return 1
return 0 return 0
def _serverUntil(self, deadline):
"""
Sleep until deadline is reached or self._server_event is set.
Raises utils.SleepInterrupt if self._server_event is set.
"""
now = datetime.datetime.utcnow()
while now < deadline:
if self._server_event.wait((deadline - now).total_seconds()):
raise utils.SleepInterrupt
now = datetime.datetime.utcnow()
return now
def _startServer(self, *argv): def _startServer(self, *argv):
""" """
Start caucased server Start caucased server
""" """
self._server = server = multiprocessing.Process( self._server_event.clear()
self._server = server = threading.Thread(
target=http.main, target=http.main,
kwargs={ kwargs={
'argv': ( 'argv': (
...@@ -171,6 +182,7 @@ class CaucaseTest(unittest.TestCase): ...@@ -171,6 +182,7 @@ class CaucaseTest(unittest.TestCase):
#'--threshold', '31', #'--threshold', '31',
#'--key-len', '2048', #'--key-len', '2048',
) + argv, ) + argv,
'until': self._serverUntil,
} }
) )
server.daemon = True server.daemon = True
...@@ -189,16 +201,10 @@ class CaucaseTest(unittest.TestCase): ...@@ -189,16 +201,10 @@ class CaucaseTest(unittest.TestCase):
Stop a running caucased server Stop a running caucased server
""" """
server = self._server server = self._server
server.terminate() self._server_event.set()
server.join(.1) server.join(2)
if server.is_alive():
# Sometimes, server survives to a SIGTERM. Maybe an effect of it being
# multi-threaded, or something in python which would catch SystemExit ?
# It does typically succeed on second try, so just do that.
server.terminate()
server.join(.1)
if server.is_alive(): if server.is_alive():
raise ValueError('pid %i does not wish to die' % (server.pid, )) raise ValueError('%r does not wish to die' % (server, ))
def _runClient(self, *argv): def _runClient(self, *argv):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment