2017-01-28 01:34:21 +00:00
|
|
|
import multiprocessing
|
|
|
|
import random
|
|
|
|
import signal
|
2018-11-04 05:04:12 +00:00
|
|
|
import pickle
|
2018-09-29 18:54:47 +01:00
|
|
|
import pytest
|
2017-01-08 17:55:08 +00:00
|
|
|
|
2018-03-16 04:28:52 +00:00
|
|
|
from sanic.testing import HOST, PORT
|
2018-11-04 05:04:12 +00:00
|
|
|
from sanic.response import text
|
2016-10-18 09:22:49 +01:00
|
|
|
|
|
|
|
|
2018-09-29 18:54:47 +01:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
not hasattr(signal, 'SIGALRM'),
|
|
|
|
reason='SIGALRM is not implemented for this platform, we have to come '
|
|
|
|
'up with another timeout strategy to test these'
|
|
|
|
)
|
2018-08-26 15:43:14 +01:00
|
|
|
def test_multiprocessing(app):
|
2017-01-28 01:34:21 +00:00
|
|
|
"""Tests that the number of children we produce is correct"""
|
|
|
|
# Selects a number at random so we can spot check
|
2018-09-29 18:54:47 +01:00
|
|
|
num_workers = random.choice(range(2, multiprocessing.cpu_count() * 2 + 1))
|
2017-01-28 01:34:21 +00:00
|
|
|
process_list = set()
|
2016-12-26 22:37:05 +00:00
|
|
|
|
2017-01-28 01:34:21 +00:00
|
|
|
def stop_on_alarm(*args):
|
|
|
|
for process in multiprocessing.active_children():
|
|
|
|
process_list.add(process.pid)
|
|
|
|
process.terminate()
|
2016-12-26 22:37:05 +00:00
|
|
|
|
2017-01-28 01:34:21 +00:00
|
|
|
signal.signal(signal.SIGALRM, stop_on_alarm)
|
2018-03-16 05:06:58 +00:00
|
|
|
signal.alarm(3)
|
2018-03-16 04:28:52 +00:00
|
|
|
app.run(HOST, PORT, workers=num_workers)
|
2016-12-26 22:37:05 +00:00
|
|
|
|
2017-01-28 01:34:21 +00:00
|
|
|
assert len(process_list) == num_workers
|
2018-11-04 05:04:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_multiprocessing_with_blueprint(app):
|
|
|
|
from sanic import Blueprint
|
|
|
|
# Selects a number at random so we can spot check
|
|
|
|
num_workers = random.choice(range(2, multiprocessing.cpu_count() * 2 + 1))
|
|
|
|
process_list = set()
|
|
|
|
|
|
|
|
def stop_on_alarm(*args):
|
|
|
|
for process in multiprocessing.active_children():
|
|
|
|
process_list.add(process.pid)
|
|
|
|
process.terminate()
|
|
|
|
|
|
|
|
signal.signal(signal.SIGALRM, stop_on_alarm)
|
|
|
|
signal.alarm(3)
|
|
|
|
|
|
|
|
bp = Blueprint('test_text')
|
|
|
|
app.blueprint(bp)
|
|
|
|
app.run(HOST, PORT, workers=num_workers)
|
|
|
|
|
|
|
|
assert len(process_list) == num_workers
|
|
|
|
|
|
|
|
|
|
|
|
# this function must be outside a test function so that it can be
|
|
|
|
# able to be pickled (local functions cannot be pickled).
|
|
|
|
def handler(request):
|
|
|
|
return text('Hello')
|
|
|
|
|
|
|
|
# Muliprocessing on Windows requires app to be able to be pickled
|
|
|
|
@pytest.mark.parametrize('protocol', [3, 4])
|
|
|
|
def test_pickle_app(app, protocol):
|
|
|
|
app.route('/')(handler)
|
|
|
|
p_app = pickle.dumps(app, protocol=protocol)
|
|
|
|
up_p_app = pickle.loads(p_app)
|
|
|
|
assert up_p_app
|
|
|
|
request, response = app.test_client.get('/')
|
|
|
|
assert response.text == 'Hello'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('protocol', [3, 4])
|
2018-11-04 05:27:25 +00:00
|
|
|
def test_pickle_app_with_bp(app, protocol):
|
2018-11-04 05:04:12 +00:00
|
|
|
from sanic import Blueprint
|
|
|
|
bp = Blueprint('test_text')
|
|
|
|
bp.route('/')(handler)
|
|
|
|
app.blueprint(bp)
|
|
|
|
p_app = pickle.dumps(app, protocol=protocol)
|
|
|
|
up_p_app = pickle.loads(p_app)
|
|
|
|
assert up_p_app
|
|
|
|
request, response = app.test_client.get('/')
|
|
|
|
assert app.is_request_stream is False
|
|
|
|
assert response.text == 'Hello'
|