|
4 | 4 | import multiprocessing |
5 | 5 | import pytest |
6 | 6 | import socket |
| 7 | +import signal |
| 8 | +import os |
| 9 | +import logging |
7 | 10 |
|
8 | 11 | try: |
9 | 12 | from urllib2 import urlopen |
@@ -49,9 +52,10 @@ class LiveServer(object): |
49 | 52 | :param port: The port to run application. |
50 | 53 | """ |
51 | 54 |
|
52 | | - def __init__(self, app, port): |
| 55 | + def __init__(self, app, port, clean_stop=False): |
53 | 56 | self.app = app |
54 | 57 | self.port = port |
| 58 | + self.clean_stop = clean_stop |
55 | 59 | self._process = None |
56 | 60 |
|
57 | 61 | def start(self): |
@@ -82,7 +86,20 @@ def url(self, url=''): |
82 | 86 | def stop(self): |
83 | 87 | """Stop application process.""" |
84 | 88 | if self._process: |
85 | | - self._process.terminate() |
| 89 | + if self.clean_stop: |
| 90 | + # We wait a maximum of 5 seconds for the server to terminate cleanly |
| 91 | + timeout = 5 |
| 92 | + try: |
| 93 | + os.kill(self._process.pid, signal.SIGINT) |
| 94 | + self._process.join(timeout) |
| 95 | + except Exception as ex: |
| 96 | + logging.error('Failed to join the live server process: %r', ex) |
| 97 | + finally: |
| 98 | + if self._process.is_alive(): |
| 99 | + # If it's still alive, kill it |
| 100 | + self._process.terminate() |
| 101 | + else: |
| 102 | + self._process.terminate() |
86 | 103 |
|
87 | 104 | def __repr__(self): |
88 | 105 | return '<LiveServer listening at %s>' % self.url() |
@@ -123,7 +140,8 @@ def test_server_is_up_and_running(live_server): |
123 | 140 | monkeypatch.setitem(app.config, 'SERVER_NAME', |
124 | 141 | _rewrite_server_name(server_name, str(port))) |
125 | 142 |
|
126 | | - server = LiveServer(app, port) |
| 143 | + clean_stop = request.config.getvalue('live_server_clean_stop') |
| 144 | + server = LiveServer(app, port, clean_stop) |
127 | 145 | if request.config.getvalue('start_live_server'): |
128 | 146 | server.start() |
129 | 147 |
|
|
0 commit comments