mirror of
https://github.com/Manuel83/craftbeerpi3
synced 2026-09-19 15:59:07 +02:00
python 3 migration
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
import six
|
||||
if six.PY3:
|
||||
from unittest import mock
|
||||
else:
|
||||
import mock
|
||||
|
||||
from engineio.async_drivers import eventlet as async_eventlet
|
||||
|
||||
|
||||
class TestAsyncEventlet(unittest.TestCase):
|
||||
def setUp(self):
|
||||
logging.getLogger('engineio').setLevel(logging.NOTSET)
|
||||
|
||||
def test_bad_environ(self):
|
||||
wsgi = async_eventlet.WebSocketWSGI(None)
|
||||
environ = {'foo': 'bar'}
|
||||
start_response = 'bar'
|
||||
self.assertRaises(RuntimeError, wsgi, environ, start_response)
|
||||
|
||||
@mock.patch('engineio.async_drivers.eventlet._WebSocketWSGI.__call__',
|
||||
return_value='data')
|
||||
def test_wsgi_call(self, _WebSocketWSGI):
|
||||
_WebSocketWSGI.__call__ = lambda e, s: 'data'
|
||||
environ = {'eventlet.input': mock.MagicMock()}
|
||||
start_response = 'bar'
|
||||
wsgi = async_eventlet.WebSocketWSGI(None)
|
||||
self.assertEqual(wsgi(environ, start_response), 'data')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import six
|
||||
if six.PY3:
|
||||
from unittest import mock
|
||||
else:
|
||||
import mock
|
||||
|
||||
import engineio
|
||||
|
||||
|
||||
class TestWSGIApp(unittest.TestCase):
|
||||
def test_wsgi_routing(self):
|
||||
mock_wsgi_app = mock.MagicMock()
|
||||
mock_eio_app = 'foo'
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app)
|
||||
environ = {'PATH_INFO': '/foo'}
|
||||
start_response = "foo"
|
||||
m(environ, start_response)
|
||||
mock_wsgi_app.assert_called_once_with(environ, start_response)
|
||||
|
||||
def test_eio_routing(self):
|
||||
mock_wsgi_app = 'foo'
|
||||
mock_eio_app = mock.Mock()
|
||||
mock_eio_app.handle_request = mock.MagicMock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app)
|
||||
environ = {'PATH_INFO': '/engine.io/'}
|
||||
start_response = "foo"
|
||||
m(environ, start_response)
|
||||
mock_eio_app.handle_request.assert_called_once_with(environ,
|
||||
start_response)
|
||||
|
||||
def test_static_files(self):
|
||||
root_dir = os.path.dirname(__file__)
|
||||
m = engineio.WSGIApp('foo', None, static_files={
|
||||
'/': root_dir + '/index.html',
|
||||
'/foo': {'content_type': 'text/plain',
|
||||
'filename': root_dir + '/index.html'},
|
||||
'/static': root_dir,
|
||||
'/static/test/': root_dir + '/',
|
||||
})
|
||||
|
||||
def check_path(path, status_code, content_type, body):
|
||||
environ = {'PATH_INFO': path}
|
||||
start_response = mock.MagicMock()
|
||||
r = m(environ, start_response)
|
||||
self.assertEqual(r, [body.encode('utf-8')])
|
||||
start_response.assert_called_once_with(
|
||||
status_code, [('Content-Type', content_type)])
|
||||
|
||||
check_path('/', '200 OK', 'text/html', '<html></html>\n')
|
||||
check_path('/foo', '200 OK', 'text/plain', '<html></html>\n')
|
||||
check_path('/static/index.html', '200 OK', 'text/html',
|
||||
'<html></html>\n')
|
||||
check_path('/static/foo.bar', '404 Not Found', 'text/plain',
|
||||
'Not Found')
|
||||
check_path('/static/test/index.html', '200 OK', 'text/html',
|
||||
'<html></html>\n')
|
||||
check_path('/static/test/', '200 OK', 'text/html', '<html></html>\n')
|
||||
check_path('/bar/foo', '404 Not Found', 'text/plain', 'Not Found')
|
||||
check_path('', '404 Not Found', 'text/plain', 'Not Found')
|
||||
|
||||
m.static_files[''] = 'index.html'
|
||||
check_path('/static/test/', '200 OK', 'text/html',
|
||||
'<html></html>\n')
|
||||
|
||||
m.static_files[''] = {'filename': 'index.html'}
|
||||
check_path('/static/test/', '200 OK', 'text/html',
|
||||
'<html></html>\n')
|
||||
|
||||
m.static_files[''] = {'filename': 'index.html',
|
||||
'content_type': 'image/gif'}
|
||||
check_path('/static/test/', '200 OK', 'image/gif',
|
||||
'<html></html>\n')
|
||||
|
||||
m.static_files[''] = {'filename': 'test.gif'}
|
||||
check_path('/static/test/', '404 Not Found', 'text/plain',
|
||||
'Not Found')
|
||||
|
||||
m.static_files = {}
|
||||
check_path('/static/test/index.html', '404 Not Found', 'text/plain',
|
||||
'Not Found')
|
||||
|
||||
def test_404(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app)
|
||||
environ = {'PATH_INFO': '/foo/bar'}
|
||||
start_response = mock.MagicMock()
|
||||
r = m(environ, start_response)
|
||||
self.assertEqual(r, [b'Not Found'])
|
||||
start_response.assert_called_once_with(
|
||||
"404 Not Found", [('Content-Type', 'text/plain')])
|
||||
|
||||
def test_custom_eio_path(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
mock_eio_app.handle_request = mock.MagicMock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app, engineio_path='foo')
|
||||
environ = {'PATH_INFO': '/engine.io/'}
|
||||
start_response = mock.MagicMock()
|
||||
r = m(environ, start_response)
|
||||
self.assertEqual(r, [b'Not Found'])
|
||||
start_response.assert_called_once_with(
|
||||
"404 Not Found", [('Content-Type', 'text/plain')])
|
||||
|
||||
environ = {'PATH_INFO': '/foo/'}
|
||||
m(environ, start_response)
|
||||
mock_eio_app.handle_request.assert_called_once_with(environ,
|
||||
start_response)
|
||||
|
||||
def test_custom_eio_path_slashes(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
mock_eio_app.handle_request = mock.MagicMock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app,
|
||||
engineio_path='/foo/')
|
||||
environ = {'PATH_INFO': '/foo/'}
|
||||
start_response = mock.MagicMock()
|
||||
m(environ, start_response)
|
||||
mock_eio_app.handle_request.assert_called_once_with(environ,
|
||||
start_response)
|
||||
|
||||
def test_custom_eio_path_leading_slash(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
mock_eio_app.handle_request = mock.MagicMock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app, engineio_path='/foo')
|
||||
environ = {'PATH_INFO': '/foo/'}
|
||||
start_response = mock.MagicMock()
|
||||
m(environ, start_response)
|
||||
mock_eio_app.handle_request.assert_called_once_with(environ,
|
||||
start_response)
|
||||
|
||||
def test_custom_eio_path_trailing_slash(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
mock_eio_app.handle_request = mock.MagicMock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app, engineio_path='foo/')
|
||||
environ = {'PATH_INFO': '/foo/'}
|
||||
start_response = mock.MagicMock()
|
||||
m(environ, start_response)
|
||||
mock_eio_app.handle_request.assert_called_once_with(environ,
|
||||
start_response)
|
||||
|
||||
def test_gunicorn_socket(self):
|
||||
mock_wsgi_app = None
|
||||
mock_eio_app = mock.Mock()
|
||||
m = engineio.WSGIApp(mock_eio_app, mock_wsgi_app)
|
||||
environ = {'gunicorn.socket': 123, 'PATH_INFO': '/foo/bar'}
|
||||
start_response = mock.MagicMock()
|
||||
m(environ, start_response)
|
||||
self.assertIn('eventlet.input', environ)
|
||||
self.assertEqual(environ['eventlet.input'].get_socket(), 123)
|
||||
|
||||
def test_legacy_middleware_class(self):
|
||||
m = engineio.Middleware('eio', 'wsgi', 'eio_path')
|
||||
self.assertEqual(m.engineio_app, 'eio')
|
||||
self.assertEqual(m.wsgi_app, 'wsgi')
|
||||
self.assertEqual(m.static_files, {})
|
||||
self.assertEqual(m.engineio_path, 'eio_path')
|
||||
@@ -0,0 +1,103 @@
|
||||
import unittest
|
||||
|
||||
import six
|
||||
|
||||
from engineio import packet
|
||||
|
||||
|
||||
class TestPacket(unittest.TestCase):
|
||||
def test_encode_default_packet(self):
|
||||
pkt = packet.Packet()
|
||||
self.assertEqual(pkt.packet_type, packet.NOOP)
|
||||
self.assertIsNone(pkt.data)
|
||||
self.assertFalse(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'6')
|
||||
|
||||
def test_decode_default_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'6')
|
||||
self.assertTrue(pkt.encode(), b'6')
|
||||
|
||||
def test_encode_text_packet(self):
|
||||
data = six.text_type('text')
|
||||
pkt = packet.Packet(packet.MESSAGE, data=data)
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, data)
|
||||
self.assertFalse(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'4text')
|
||||
|
||||
def test_decode_text_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'4text')
|
||||
self.assertEqual(pkt.encode(), b'4text')
|
||||
|
||||
def test_encode_binary_packet(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=b'\x01\x02\x03',
|
||||
binary=True)
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, b'\x01\x02\x03')
|
||||
self.assertTrue(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_encode_binary_bytearray_packet(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=bytearray(b'\x01\x02\x03'),
|
||||
binary=True)
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, b'\x01\x02\x03')
|
||||
self.assertTrue(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_encode_binary_b64_packet(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=b'\x01\x02\x03\x04',
|
||||
binary=True)
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, b'\x01\x02\x03\x04')
|
||||
self.assertTrue(pkt.binary)
|
||||
self.assertEqual(pkt.encode(b64=True), b'b4AQIDBA==')
|
||||
|
||||
def test_encode_binary_packet_py3(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=b'\x01\x02\x03')
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, b'\x01\x02\x03')
|
||||
self.assertTrue(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_decode_binary_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'\x04\x01\x02\x03')
|
||||
self.assertTrue(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_decode_binary_bytearray_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=bytearray(b'\x04\x01\x02\x03'))
|
||||
self.assertTrue(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_decode_binary_b64_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'b4AAEC')
|
||||
self.assertTrue(pkt.encode(), b'\x04\x01\x02\x03')
|
||||
|
||||
def test_encode_json_packet(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data={'a': 123, 'b': '456'})
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, {'a': 123, 'b': '456'})
|
||||
self.assertFalse(pkt.binary)
|
||||
self.assertIn(pkt.encode(), [b'4{"a":123,"b":"456"}',
|
||||
b'4{"b":"456","a":123}'])
|
||||
|
||||
def test_decode_json_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'4{"a":123,"b":"456"}')
|
||||
self.assertIn(pkt.encode(), [b'4{"a":123,"b":"456"}',
|
||||
b'4{"b":"456","a":123}'])
|
||||
|
||||
def test_encode_number_packet(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=123)
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
self.assertEqual(pkt.data, 123)
|
||||
self.assertFalse(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'4123')
|
||||
|
||||
def test_decode_number_packet(self):
|
||||
pkt = packet.Packet(encoded_packet=b'4123')
|
||||
self.assertEqual(pkt.packet_type, packet.MESSAGE)
|
||||
# integer payloads are parsed as strings, see
|
||||
# https://github.com/miguelgrinberg/python-engineio/issues/75
|
||||
# for background on this decision
|
||||
self.assertEqual(pkt.data, '123')
|
||||
self.assertFalse(pkt.binary)
|
||||
self.assertEqual(pkt.encode(), b'4123')
|
||||
@@ -0,0 +1,70 @@
|
||||
import unittest
|
||||
|
||||
import six
|
||||
|
||||
from engineio import packet
|
||||
from engineio import payload
|
||||
|
||||
|
||||
class TestPayload(unittest.TestCase):
|
||||
def test_encode_empty_payload(self):
|
||||
p = payload.Payload()
|
||||
self.assertEqual(p.packets, [])
|
||||
self.assertEqual(p.encode(), b'')
|
||||
|
||||
def test_decode_empty_payload(self):
|
||||
p = payload.Payload(encoded_payload=b'')
|
||||
self.assertEqual(p.encode(), b'')
|
||||
|
||||
def test_encode_payload_xhr2(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=six.text_type('abc'))
|
||||
p = payload.Payload([pkt])
|
||||
self.assertEqual(p.packets, [pkt])
|
||||
self.assertEqual(p.encode(), b'\x00\x04\xff4abc')
|
||||
|
||||
def test_decode_payload_xhr2(self):
|
||||
p = payload.Payload(encoded_payload=b'\x00\x04\xff4abc')
|
||||
self.assertEqual(p.encode(), b'\x00\x04\xff4abc')
|
||||
|
||||
def test_encode_payload_xhr_text(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=six.text_type('abc'))
|
||||
p = payload.Payload([pkt])
|
||||
self.assertEqual(p.packets, [pkt])
|
||||
self.assertEqual(p.encode(b64=True), b'4:4abc')
|
||||
|
||||
def test_decode_payload_xhr_text(self):
|
||||
p = payload.Payload(encoded_payload=b'4:4abc')
|
||||
self.assertEqual(p.encode(), b'\x00\x04\xff4abc')
|
||||
|
||||
def test_encode_payload_xhr_binary(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=b'\x00\x01\x02', binary=True)
|
||||
p = payload.Payload([pkt])
|
||||
self.assertEqual(p.packets, [pkt])
|
||||
self.assertEqual(p.encode(b64=True), b'6:b4AAEC')
|
||||
|
||||
def test_decode_payload_xhr_binary(self):
|
||||
p = payload.Payload(encoded_payload=b'6:b4AAEC')
|
||||
self.assertEqual(p.encode(), b'\x01\x04\xff\x04\x00\x01\x02')
|
||||
|
||||
def test_encode_jsonp_payload(self):
|
||||
pkt = packet.Packet(packet.MESSAGE, data=six.text_type('abc'))
|
||||
p = payload.Payload([pkt])
|
||||
self.assertEqual(p.packets, [pkt])
|
||||
self.assertEqual(p.encode(jsonp_index=233),
|
||||
b'___eio[233]("\x00\x04\xff4abc");')
|
||||
self.assertEqual(p.encode(jsonp_index=233, b64=True),
|
||||
b'___eio[233]("4:4abc");')
|
||||
|
||||
def test_decode_jsonp_payload(self):
|
||||
p = payload.Payload(encoded_payload=b'd=4:4abc')
|
||||
self.assertEqual(p.encode(), b'\x00\x04\xff4abc')
|
||||
|
||||
def test_decode_invalid_payload(self):
|
||||
self.assertRaises(ValueError, payload.Payload,
|
||||
encoded_payload=b'bad payload')
|
||||
|
||||
def test_decode_multi_payload(self):
|
||||
p = payload.Payload(encoded_payload=b'4:4abc\x00\x04\xff4def')
|
||||
self.assertEqual(len(p.packets), 2)
|
||||
self.assertEqual(p.packets[0].data, 'abc')
|
||||
self.assertEqual(p.packets[1].data, 'def')
|
||||
@@ -0,0 +1,952 @@
|
||||
import gzip
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
import zlib
|
||||
|
||||
import six
|
||||
if six.PY3:
|
||||
from unittest import mock
|
||||
else:
|
||||
import mock
|
||||
|
||||
from engineio import exceptions
|
||||
from engineio import packet
|
||||
from engineio import payload
|
||||
from engineio import server
|
||||
|
||||
|
||||
original_import_module = importlib.import_module
|
||||
|
||||
|
||||
def _mock_import(module, *args, **kwargs):
|
||||
if module.startswith('engineio.'):
|
||||
return original_import_module(module, *args, **kwargs)
|
||||
return module
|
||||
|
||||
|
||||
class TestServer(unittest.TestCase):
|
||||
_mock_async = mock.MagicMock()
|
||||
_mock_async._async = {
|
||||
'thread': 't',
|
||||
'queue': 'q',
|
||||
'queue_empty': RuntimeError,
|
||||
'websocket': 'w',
|
||||
}
|
||||
|
||||
def _get_mock_socket(self):
|
||||
mock_socket = mock.MagicMock()
|
||||
mock_socket.closed = False
|
||||
mock_socket.closing = False
|
||||
mock_socket.upgraded = False
|
||||
mock_socket.session = {}
|
||||
return mock_socket
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
server.Server._default_monitor_clients = False
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
server.Server._default_monitor_clients = True
|
||||
|
||||
def setUp(self):
|
||||
logging.getLogger('engineio').setLevel(logging.NOTSET)
|
||||
|
||||
def tearDown(self):
|
||||
# restore JSON encoder, in case a test changed it
|
||||
packet.Packet.json = json
|
||||
|
||||
def test_is_asyncio_based(self):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.is_asyncio_based(), False)
|
||||
|
||||
def test_async_modes(self):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.async_modes(), ['eventlet', 'gevent_uwsgi',
|
||||
'gevent', 'threading'])
|
||||
|
||||
def test_create(self):
|
||||
kwargs = {
|
||||
'ping_timeout': 1,
|
||||
'ping_interval': 2,
|
||||
'max_http_buffer_size': 3,
|
||||
'allow_upgrades': False,
|
||||
'http_compression': False,
|
||||
'compression_threshold': 4,
|
||||
'cookie': 'foo',
|
||||
'cors_allowed_origins': ['foo', 'bar', 'baz'],
|
||||
'cors_credentials': False,
|
||||
'async_handlers': False}
|
||||
s = server.Server(**kwargs)
|
||||
for arg in six.iterkeys(kwargs):
|
||||
self.assertEqual(getattr(s, arg), kwargs[arg])
|
||||
|
||||
def test_create_ignores_kwargs(self):
|
||||
server.Server(foo='bar') # this should not raise
|
||||
|
||||
def test_async_mode_threading(self):
|
||||
s = server.Server(async_mode='threading')
|
||||
self.assertEqual(s.async_mode, 'threading')
|
||||
|
||||
import threading
|
||||
try:
|
||||
import queue
|
||||
except ImportError:
|
||||
import Queue as queue
|
||||
|
||||
self.assertEqual(s._async['thread'], threading.Thread)
|
||||
self.assertEqual(s._async['queue'], queue.Queue)
|
||||
self.assertEqual(s._async['websocket'], None)
|
||||
|
||||
def test_async_mode_eventlet(self):
|
||||
s = server.Server(async_mode='eventlet')
|
||||
self.assertEqual(s.async_mode, 'eventlet')
|
||||
|
||||
from eventlet.green import threading
|
||||
from eventlet import queue
|
||||
from engineio.async_drivers import eventlet as async_eventlet
|
||||
|
||||
self.assertEqual(s._async['thread'], threading.Thread)
|
||||
self.assertEqual(s._async['queue'], queue.Queue)
|
||||
self.assertEqual(s._async['websocket'], async_eventlet.WebSocketWSGI)
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_gevent_uwsgi(self, import_module):
|
||||
sys.modules['gevent'] = mock.MagicMock()
|
||||
sys.modules['gevent'].queue = mock.MagicMock()
|
||||
sys.modules['gevent.queue'] = sys.modules['gevent'].queue
|
||||
sys.modules['gevent.queue'].JoinableQueue = 'foo'
|
||||
sys.modules['gevent.queue'].Empty = RuntimeError
|
||||
sys.modules['gevent.event'] = mock.MagicMock()
|
||||
sys.modules['gevent.event'].Event = 'bar'
|
||||
sys.modules['uwsgi'] = mock.MagicMock()
|
||||
s = server.Server(async_mode='gevent_uwsgi')
|
||||
self.assertEqual(s.async_mode, 'gevent_uwsgi')
|
||||
|
||||
from engineio.async_drivers import gevent_uwsgi as async_gevent_uwsgi
|
||||
|
||||
self.assertEqual(s._async['thread'], async_gevent_uwsgi.Thread)
|
||||
self.assertEqual(s._async['queue'], 'foo')
|
||||
self.assertEqual(s._async['queue_empty'], RuntimeError)
|
||||
self.assertEqual(s._async['event'], 'bar')
|
||||
self.assertEqual(s._async['websocket'],
|
||||
async_gevent_uwsgi.uWSGIWebSocket)
|
||||
del sys.modules['gevent']
|
||||
del sys.modules['gevent.queue']
|
||||
del sys.modules['gevent.event']
|
||||
del sys.modules['uwsgi']
|
||||
del sys.modules['engineio.async_drivers.gevent_uwsgi']
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_gevent_uwsgi_without_uwsgi(self, import_module):
|
||||
sys.modules['gevent'] = mock.MagicMock()
|
||||
sys.modules['gevent'].queue = mock.MagicMock()
|
||||
sys.modules['gevent.queue'] = sys.modules['gevent'].queue
|
||||
sys.modules['gevent.queue'].JoinableQueue = 'foo'
|
||||
sys.modules['gevent.queue'].Empty = RuntimeError
|
||||
sys.modules['gevent.event'] = mock.MagicMock()
|
||||
sys.modules['gevent.event'].Event = 'bar'
|
||||
sys.modules['uwsgi'] = None
|
||||
self.assertRaises(ValueError, server.Server,
|
||||
async_mode='gevent_uwsgi')
|
||||
del sys.modules['gevent']
|
||||
del sys.modules['gevent.queue']
|
||||
del sys.modules['gevent.event']
|
||||
del sys.modules['uwsgi']
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_gevent_uwsgi_without_websocket(self, import_module):
|
||||
sys.modules['gevent'] = mock.MagicMock()
|
||||
sys.modules['gevent'].queue = mock.MagicMock()
|
||||
sys.modules['gevent.queue'] = sys.modules['gevent'].queue
|
||||
sys.modules['gevent.queue'].JoinableQueue = 'foo'
|
||||
sys.modules['gevent.queue'].Empty = RuntimeError
|
||||
sys.modules['gevent.event'] = mock.MagicMock()
|
||||
sys.modules['gevent.event'].Event = 'bar'
|
||||
sys.modules['uwsgi'] = mock.MagicMock()
|
||||
del sys.modules['uwsgi'].websocket_handshake
|
||||
s = server.Server(async_mode='gevent_uwsgi')
|
||||
self.assertEqual(s.async_mode, 'gevent_uwsgi')
|
||||
|
||||
from engineio.async_drivers import gevent_uwsgi as async_gevent_uwsgi
|
||||
|
||||
self.assertEqual(s._async['thread'], async_gevent_uwsgi.Thread)
|
||||
self.assertEqual(s._async['queue'], 'foo')
|
||||
self.assertEqual(s._async['queue_empty'], RuntimeError)
|
||||
self.assertEqual(s._async['event'], 'bar')
|
||||
self.assertEqual(s._async['websocket'], None)
|
||||
del sys.modules['gevent']
|
||||
del sys.modules['gevent.queue']
|
||||
del sys.modules['gevent.event']
|
||||
del sys.modules['uwsgi']
|
||||
del sys.modules['engineio.async_drivers.gevent_uwsgi']
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_gevent(self, import_module):
|
||||
sys.modules['gevent'] = mock.MagicMock()
|
||||
sys.modules['gevent'].queue = mock.MagicMock()
|
||||
sys.modules['gevent.queue'] = sys.modules['gevent'].queue
|
||||
sys.modules['gevent.queue'].JoinableQueue = 'foo'
|
||||
sys.modules['gevent.queue'].Empty = RuntimeError
|
||||
sys.modules['gevent.event'] = mock.MagicMock()
|
||||
sys.modules['gevent.event'].Event = 'bar'
|
||||
sys.modules['geventwebsocket'] = 'geventwebsocket'
|
||||
s = server.Server(async_mode='gevent')
|
||||
self.assertEqual(s.async_mode, 'gevent')
|
||||
|
||||
from engineio.async_drivers import gevent as async_gevent
|
||||
|
||||
self.assertEqual(s._async['thread'], async_gevent.Thread)
|
||||
self.assertEqual(s._async['queue'], 'foo')
|
||||
self.assertEqual(s._async['queue_empty'], RuntimeError)
|
||||
self.assertEqual(s._async['event'], 'bar')
|
||||
self.assertEqual(s._async['websocket'], async_gevent.WebSocketWSGI)
|
||||
del sys.modules['gevent']
|
||||
del sys.modules['gevent.queue']
|
||||
del sys.modules['gevent.event']
|
||||
del sys.modules['geventwebsocket']
|
||||
del sys.modules['engineio.async_drivers.gevent']
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_gevent_without_websocket(self, import_module):
|
||||
sys.modules['gevent'] = mock.MagicMock()
|
||||
sys.modules['gevent'].queue = mock.MagicMock()
|
||||
sys.modules['gevent.queue'] = sys.modules['gevent'].queue
|
||||
sys.modules['gevent.queue'].JoinableQueue = 'foo'
|
||||
sys.modules['gevent.queue'].Empty = RuntimeError
|
||||
sys.modules['gevent.event'] = mock.MagicMock()
|
||||
sys.modules['gevent.event'].Event = 'bar'
|
||||
sys.modules['geventwebsocket'] = None
|
||||
s = server.Server(async_mode='gevent')
|
||||
self.assertEqual(s.async_mode, 'gevent')
|
||||
|
||||
from engineio.async_drivers import gevent as async_gevent
|
||||
|
||||
self.assertEqual(s._async['thread'], async_gevent.Thread)
|
||||
self.assertEqual(s._async['queue'], 'foo')
|
||||
self.assertEqual(s._async['queue_empty'], RuntimeError)
|
||||
self.assertEqual(s._async['event'], 'bar')
|
||||
self.assertEqual(s._async['websocket'], None)
|
||||
del sys.modules['gevent']
|
||||
del sys.modules['gevent.queue']
|
||||
del sys.modules['gevent.event']
|
||||
del sys.modules['geventwebsocket']
|
||||
del sys.modules['engineio.async_drivers.gevent']
|
||||
|
||||
@unittest.skipIf(sys.version_info < (3, 5), 'only for Python 3.5+')
|
||||
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
||||
def test_async_mode_aiohttp(self, import_module):
|
||||
sys.modules['aiohttp'] = mock.MagicMock()
|
||||
self.assertRaises(ValueError, server.Server, async_mode='aiohttp')
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=[ImportError])
|
||||
def test_async_mode_invalid(self, import_module):
|
||||
self.assertRaises(ValueError, server.Server, async_mode='foo')
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=[_mock_async])
|
||||
def test_async_mode_auto_eventlet(self, import_module):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.async_mode, 'eventlet')
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=[ImportError,
|
||||
_mock_async])
|
||||
def test_async_mode_auto_gevent_uwsgi(self, import_module):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.async_mode, 'gevent_uwsgi')
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=[ImportError,
|
||||
ImportError,
|
||||
_mock_async])
|
||||
def test_async_mode_auto_gevent(self, import_module):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.async_mode, 'gevent')
|
||||
|
||||
@mock.patch('importlib.import_module', side_effect=[ImportError,
|
||||
ImportError,
|
||||
ImportError,
|
||||
_mock_async])
|
||||
def test_async_mode_auto_threading(self, import_module):
|
||||
s = server.Server()
|
||||
self.assertEqual(s.async_mode, 'threading')
|
||||
|
||||
def test_generate_id(self):
|
||||
s = server.Server()
|
||||
self.assertNotEqual(s._generate_id(), s._generate_id())
|
||||
|
||||
def test_on_event(self):
|
||||
s = server.Server()
|
||||
|
||||
@s.on('connect')
|
||||
def foo():
|
||||
pass
|
||||
s.on('disconnect', foo)
|
||||
|
||||
self.assertEqual(s.handlers['connect'], foo)
|
||||
self.assertEqual(s.handlers['disconnect'], foo)
|
||||
|
||||
def test_on_event_invalid(self):
|
||||
s = server.Server()
|
||||
self.assertRaises(ValueError, s.on, 'invalid')
|
||||
|
||||
def test_trigger_event(self):
|
||||
s = server.Server()
|
||||
f = {}
|
||||
|
||||
@s.on('connect')
|
||||
def foo(sid, environ):
|
||||
return sid + environ
|
||||
|
||||
@s.on('message')
|
||||
def bar(sid, data):
|
||||
f['bar'] = sid + data
|
||||
return 'bar'
|
||||
|
||||
r = s._trigger_event('connect', 1, 2, run_async=False)
|
||||
self.assertEqual(r, 3)
|
||||
r = s._trigger_event('message', 3, 4, run_async=True)
|
||||
r.join()
|
||||
self.assertEqual(f['bar'], 7)
|
||||
r = s._trigger_event('message', 5, 6)
|
||||
self.assertEqual(r, 'bar')
|
||||
|
||||
def test_trigger_event_error(self):
|
||||
s = server.Server()
|
||||
|
||||
@s.on('connect')
|
||||
def foo(sid, environ):
|
||||
return 1 / 0
|
||||
|
||||
@s.on('message')
|
||||
def bar(sid, data):
|
||||
return 1 / 0
|
||||
|
||||
r = s._trigger_event('connect', 1, 2, run_async=False)
|
||||
self.assertEqual(r, False)
|
||||
r = s._trigger_event('message', 3, 4, run_async=False)
|
||||
self.assertEqual(r, None)
|
||||
|
||||
def test_session(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
s.sockets['foo'] = mock_socket
|
||||
with s.session('foo') as session:
|
||||
self.assertEqual(session, {})
|
||||
session['username'] = 'bar'
|
||||
self.assertEqual(s.get_session('foo'), {'username': 'bar'})
|
||||
|
||||
def test_close_one_socket(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
s.sockets['foo'] = mock_socket
|
||||
s.disconnect('foo')
|
||||
self.assertEqual(mock_socket.close.call_count, 1)
|
||||
self.assertNotIn('foo', s.sockets)
|
||||
|
||||
def test_close_all_sockets(self):
|
||||
s = server.Server()
|
||||
mock_sockets = {}
|
||||
for sid in ['foo', 'bar', 'baz']:
|
||||
mock_sockets[sid] = self._get_mock_socket()
|
||||
s.sockets[sid] = mock_sockets[sid]
|
||||
s.disconnect()
|
||||
for socket in six.itervalues(mock_sockets):
|
||||
self.assertEqual(socket.close.call_count, 1)
|
||||
self.assertEqual(s.sockets, {})
|
||||
|
||||
def test_upgrades(self):
|
||||
s = server.Server()
|
||||
s.sockets['foo'] = self._get_mock_socket()
|
||||
self.assertEqual(s._upgrades('foo', 'polling'), ['websocket'])
|
||||
self.assertEqual(s._upgrades('foo', 'websocket'), [])
|
||||
s.sockets['foo'].upgraded = True
|
||||
self.assertEqual(s._upgrades('foo', 'polling'), [])
|
||||
self.assertEqual(s._upgrades('foo', 'websocket'), [])
|
||||
s.allow_upgrades = False
|
||||
s.sockets['foo'].upgraded = True
|
||||
self.assertEqual(s._upgrades('foo', 'polling'), [])
|
||||
self.assertEqual(s._upgrades('foo', 'websocket'), [])
|
||||
|
||||
def test_transport(self):
|
||||
s = server.Server()
|
||||
s.sockets['foo'] = self._get_mock_socket()
|
||||
s.sockets['foo'].upgraded = False
|
||||
s.sockets['bar'] = self._get_mock_socket()
|
||||
s.sockets['bar'].upgraded = True
|
||||
self.assertEqual(s.transport('foo'), 'polling')
|
||||
self.assertEqual(s.transport('bar'), 'websocket')
|
||||
|
||||
def test_bad_session(self):
|
||||
s = server.Server()
|
||||
s.sockets['foo'] = 'client'
|
||||
self.assertRaises(KeyError, s._get_socket, 'bar')
|
||||
|
||||
def test_closed_socket(self):
|
||||
s = server.Server()
|
||||
s.sockets['foo'] = self._get_mock_socket()
|
||||
s.sockets['foo'].closed = True
|
||||
self.assertRaises(KeyError, s._get_socket, 'foo')
|
||||
|
||||
def test_jsonp_with_bad_index(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'j=abc'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
|
||||
def test_jsonp_index(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'j=233'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'200 OK')
|
||||
self.assertTrue(r[0].startswith(b'___eio[233]("'))
|
||||
self.assertTrue(r[0].endswith(b'");'))
|
||||
|
||||
def test_connect(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(len(s.sockets), 1)
|
||||
self.assertEqual(start_response.call_count, 1)
|
||||
self.assertEqual(start_response.call_args[0][0], '200 OK')
|
||||
self.assertIn(('Content-Type', 'application/octet-stream'),
|
||||
start_response.call_args[0][1])
|
||||
self.assertEqual(len(r), 1)
|
||||
packets = payload.Payload(encoded_payload=r[0]).packets
|
||||
self.assertEqual(len(packets), 1)
|
||||
self.assertEqual(packets[0].packet_type, packet.OPEN)
|
||||
self.assertIn('upgrades', packets[0].data)
|
||||
self.assertEqual(packets[0].data['upgrades'], ['websocket'])
|
||||
self.assertIn('sid', packets[0].data)
|
||||
|
||||
def test_connect_no_upgrades(self):
|
||||
s = server.Server(allow_upgrades=False)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
packets = payload.Payload(encoded_payload=r[0]).packets
|
||||
self.assertEqual(packets[0].data['upgrades'], [])
|
||||
|
||||
def test_connect_b64_with_1(self):
|
||||
s = server.Server(allow_upgrades=False)
|
||||
s._generate_id = mock.MagicMock(return_value='1')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=1'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertTrue(start_response.call_args[0][0], '200 OK')
|
||||
self.assertIn(('Content-Type', 'text/plain; charset=UTF-8'),
|
||||
start_response.call_args[0][1])
|
||||
s.send('1', b'\x00\x01\x02', binary=True)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=1'}
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(r[0], b'6:b4AAEC')
|
||||
|
||||
def test_connect_b64_with_true(self):
|
||||
s = server.Server(allow_upgrades=False)
|
||||
s._generate_id = mock.MagicMock(return_value='1')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=true'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertTrue(start_response.call_args[0][0], '200 OK')
|
||||
self.assertIn(('Content-Type', 'text/plain; charset=UTF-8'),
|
||||
start_response.call_args[0][1])
|
||||
s.send('1', b'\x00\x01\x02', binary=True)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=true'}
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(r[0], b'6:b4AAEC')
|
||||
|
||||
def test_connect_b64_with_0(self):
|
||||
s = server.Server(allow_upgrades=False)
|
||||
s._generate_id = mock.MagicMock(return_value='1')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=0'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertTrue(start_response.call_args[0][0], '200 OK')
|
||||
self.assertIn(('Content-Type', 'application/octet-stream'),
|
||||
start_response.call_args[0][1])
|
||||
s.send('1', b'\x00\x01\x02', binary=True)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=0'}
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(r[0], b'\x01\x04\xff\x04\x00\x01\x02')
|
||||
|
||||
def test_connect_b64_with_false(self):
|
||||
s = server.Server(allow_upgrades=False)
|
||||
s._generate_id = mock.MagicMock(return_value='1')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=false'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertTrue(start_response.call_args[0][0], '200 OK')
|
||||
self.assertIn(('Content-Type', 'application/octet-stream'),
|
||||
start_response.call_args[0][1])
|
||||
s.send('1', b'\x00\x01\x02', binary=True)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=false'}
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(r[0], b'\x01\x04\xff\x04\x00\x01\x02')
|
||||
|
||||
def test_connect_custom_ping_times(self):
|
||||
s = server.Server(ping_timeout=123, ping_interval=456)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
packets = payload.Payload(encoded_payload=r[0]).packets
|
||||
self.assertEqual(packets[0].data['pingTimeout'], 123000)
|
||||
self.assertEqual(packets[0].data['pingInterval'], 456000)
|
||||
|
||||
@mock.patch('engineio.socket.Socket.poll',
|
||||
side_effect=exceptions.QueueEmpty)
|
||||
def test_connect_bad_poll(self, poll):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
|
||||
@mock.patch('engineio.socket.Socket',
|
||||
return_value=mock.MagicMock(connected=False, closed=False))
|
||||
def test_connect_transport_websocket(self, Socket):
|
||||
s = server.Server()
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
environ = {'REQUEST_METHOD': 'GET',
|
||||
'QUERY_STRING': 'transport=websocket'}
|
||||
start_response = mock.MagicMock()
|
||||
# force socket to stay open, so that we can check it later
|
||||
Socket().closed = False
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(s.sockets['123'].send.call_args[0][0].packet_type,
|
||||
packet.OPEN)
|
||||
|
||||
@mock.patch('engineio.socket.Socket',
|
||||
return_value=mock.MagicMock(connected=False, closed=False))
|
||||
def test_connect_transport_websocket_closed(self, Socket):
|
||||
s = server.Server()
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
environ = {'REQUEST_METHOD': 'GET',
|
||||
'QUERY_STRING': 'transport=websocket'}
|
||||
start_response = mock.MagicMock()
|
||||
|
||||
def mock_handle(environ, start_response):
|
||||
s.sockets['123'].closed = True
|
||||
|
||||
Socket().handle_get_request = mock_handle
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertNotIn('123', s.sockets)
|
||||
|
||||
def test_connect_transport_invalid(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'transport=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
|
||||
def test_connect_cors_headers(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Origin', '*'), headers)
|
||||
self.assertIn(('Access-Control-Allow-Credentials', 'true'), headers)
|
||||
|
||||
def test_connect_cors_allowed_origin(self):
|
||||
s = server.Server(cors_allowed_origins=['a', 'b'])
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '',
|
||||
'HTTP_ORIGIN': 'b'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Origin', 'b'), headers)
|
||||
|
||||
def test_connect_cors_not_allowed_origin(self):
|
||||
s = server.Server(cors_allowed_origins=['a', 'b'])
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '',
|
||||
'HTTP_ORIGIN': 'c'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertNotIn(('Access-Control-Allow-Origin', 'c'), headers)
|
||||
self.assertNotIn(('Access-Control-Allow-Origin', '*'), headers)
|
||||
|
||||
def test_connect_cors_headers_all_origins(self):
|
||||
s = server.Server(cors_allowed_origins='*')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Origin', '*'), headers)
|
||||
self.assertIn(('Access-Control-Allow-Credentials', 'true'), headers)
|
||||
|
||||
def test_connect_cors_headers_one_origin(self):
|
||||
s = server.Server(cors_allowed_origins='a')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '',
|
||||
'HTTP_ORIGIN': 'a'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Origin', 'a'), headers)
|
||||
self.assertIn(('Access-Control-Allow-Credentials', 'true'), headers)
|
||||
|
||||
def test_connect_cors_headers_one_origin_not_allowed(self):
|
||||
s = server.Server(cors_allowed_origins='a')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '',
|
||||
'HTTP_ORIGIN': 'b'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertNotIn(('Access-Control-Allow-Origin', 'b'), headers)
|
||||
self.assertNotIn(('Access-Control-Allow-Origin', '*'), headers)
|
||||
|
||||
def test_connect_cors_no_credentials(self):
|
||||
s = server.Server(cors_credentials=False)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertNotIn(('Access-Control-Allow-Credentials', 'true'), headers)
|
||||
|
||||
def test_cors_options(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'OPTIONS', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Methods', 'OPTIONS, GET, POST'),
|
||||
headers)
|
||||
|
||||
def test_cors_request_headers(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET',
|
||||
'HTTP_ACCESS_CONTROL_REQUEST_HEADERS': 'Foo, Bar'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
headers = start_response.call_args[0][1]
|
||||
self.assertIn(('Access-Control-Allow-Headers', 'Foo, Bar'), headers)
|
||||
|
||||
def test_connect_event(self):
|
||||
s = server.Server()
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
mock_event = mock.MagicMock()
|
||||
s.on('connect')(mock_event)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
mock_event.assert_called_once_with('123', environ)
|
||||
self.assertEqual(len(s.sockets), 1)
|
||||
|
||||
def test_connect_event_rejects(self):
|
||||
s = server.Server()
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
mock_event = mock.MagicMock(return_value=False)
|
||||
s.on('connect')(mock_event)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(len(s.sockets), 0)
|
||||
self.assertEqual(start_response.call_args[0][0], '401 UNAUTHORIZED')
|
||||
|
||||
def test_method_not_found(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'PUT', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'405 METHOD NOT FOUND')
|
||||
|
||||
def test_get_request_with_bad_sid(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
|
||||
def test_post_request_with_bad_sid(self):
|
||||
s = server.Server()
|
||||
environ = {'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
|
||||
def test_send(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
s.sockets['foo'] = mock_socket
|
||||
s.send('foo', 'hello')
|
||||
self.assertEqual(mock_socket.send.call_count, 1)
|
||||
self.assertEqual(mock_socket.send.call_args[0][0].packet_type,
|
||||
packet.MESSAGE)
|
||||
self.assertEqual(mock_socket.send.call_args[0][0].data, 'hello')
|
||||
|
||||
def test_send_unknown_socket(self):
|
||||
s = server.Server()
|
||||
# just ensure no exceptions are raised
|
||||
s.send('foo', 'hello')
|
||||
|
||||
def test_get_request(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'200 OK')
|
||||
self.assertEqual(len(r), 1)
|
||||
packets = payload.Payload(encoded_payload=r[0]).packets
|
||||
self.assertEqual(len(packets), 1)
|
||||
self.assertEqual(packets[0].packet_type, packet.MESSAGE)
|
||||
|
||||
def test_get_request_custom_response(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(side_effect=['resp'])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
self.assertEqual(s.handle_request(environ, start_response), 'resp')
|
||||
|
||||
def test_get_request_closes_socket(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
|
||||
def mock_get_request(*args, **kwargs):
|
||||
mock_socket.closed = True
|
||||
return 'resp'
|
||||
|
||||
mock_socket.handle_get_request = mock_get_request
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
self.assertEqual(s.handle_request(environ, start_response), 'resp')
|
||||
self.assertNotIn('foo', s.sockets)
|
||||
|
||||
def test_get_request_error(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(
|
||||
side_effect=[exceptions.QueueEmpty])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
self.assertEqual(len(s.sockets), 0)
|
||||
|
||||
def test_post_request(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_post_request = mock.MagicMock()
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'200 OK')
|
||||
|
||||
def test_post_request_error(self):
|
||||
s = server.Server()
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_post_request = mock.MagicMock(
|
||||
side_effect=[exceptions.EngineIOError])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertEqual(start_response.call_args[0][0],
|
||||
'400 BAD REQUEST')
|
||||
self.assertNotIn('foo', s.sockets)
|
||||
|
||||
@staticmethod
|
||||
def _gzip_decompress(b):
|
||||
bytesio = six.BytesIO(b)
|
||||
with gzip.GzipFile(fileobj=bytesio, mode='r') as gz:
|
||||
return gz.read()
|
||||
|
||||
def test_gzip_compression(self):
|
||||
s = server.Server(compression_threshold=0)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': 'gzip,deflate'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertIn(('Content-Encoding', 'gzip'),
|
||||
start_response.call_args[0][1])
|
||||
self._gzip_decompress(r[0])
|
||||
|
||||
def test_deflate_compression(self):
|
||||
s = server.Server(compression_threshold=0)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': 'deflate;q=1,gzip'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
self.assertIn(('Content-Encoding', 'deflate'),
|
||||
start_response.call_args[0][1])
|
||||
zlib.decompress(r[0])
|
||||
|
||||
def test_gzip_compression_threshold(self):
|
||||
s = server.Server(compression_threshold=1000)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': 'gzip'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
for header, value in start_response.call_args[0][1]:
|
||||
self.assertNotEqual(header, 'Content-Encoding')
|
||||
self.assertRaises(IOError, self._gzip_decompress, r[0])
|
||||
|
||||
def test_compression_disabled(self):
|
||||
s = server.Server(http_compression=False, compression_threshold=0)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': 'gzip'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
for header, value in start_response.call_args[0][1]:
|
||||
self.assertNotEqual(header, 'Content-Encoding')
|
||||
self.assertRaises(IOError, self._gzip_decompress, r[0])
|
||||
|
||||
def test_compression_unknown(self):
|
||||
s = server.Server(compression_threshold=0)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': 'rar'}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
for header, value in start_response.call_args[0][1]:
|
||||
self.assertNotEqual(header, 'Content-Encoding')
|
||||
self.assertRaises(IOError, self._gzip_decompress, r[0])
|
||||
|
||||
def test_compression_no_encoding(self):
|
||||
s = server.Server(compression_threshold=0)
|
||||
mock_socket = self._get_mock_socket()
|
||||
mock_socket.handle_get_request = mock.MagicMock(return_value=[
|
||||
packet.Packet(packet.MESSAGE, data='hello')])
|
||||
s.sockets['foo'] = mock_socket
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_ACCEPT_ENCODING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
r = s.handle_request(environ, start_response)
|
||||
for header, value in start_response.call_args[0][1]:
|
||||
self.assertNotEqual(header, 'Content-Encoding')
|
||||
self.assertRaises(IOError, self._gzip_decompress, r[0])
|
||||
|
||||
def test_cookie(self):
|
||||
s = server.Server(cookie='sid')
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
self.assertIn(('Set-Cookie', 'sid=123'),
|
||||
start_response.call_args[0][1])
|
||||
|
||||
def test_no_cookie(self):
|
||||
s = server.Server(cookie=None)
|
||||
s._generate_id = mock.MagicMock(return_value='123')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
for header, value in start_response.call_args[0][1]:
|
||||
self.assertNotEqual(header, 'Set-Cookie')
|
||||
|
||||
def test_logger(self):
|
||||
s = server.Server(logger=False)
|
||||
self.assertEqual(s.logger.getEffectiveLevel(), logging.ERROR)
|
||||
s.logger.setLevel(logging.NOTSET)
|
||||
s = server.Server(logger=True)
|
||||
self.assertEqual(s.logger.getEffectiveLevel(), logging.INFO)
|
||||
s.logger.setLevel(logging.WARNING)
|
||||
s = server.Server(logger=True)
|
||||
self.assertEqual(s.logger.getEffectiveLevel(), logging.WARNING)
|
||||
s.logger.setLevel(logging.NOTSET)
|
||||
my_logger = logging.Logger('foo')
|
||||
s = server.Server(logger=my_logger)
|
||||
self.assertEqual(s.logger, my_logger)
|
||||
|
||||
def test_custom_json(self):
|
||||
# Warning: this test cannot run in parallel with other tests, as it
|
||||
# changes the JSON encoding/decoding functions
|
||||
|
||||
class CustomJSON(object):
|
||||
@staticmethod
|
||||
def dumps(*args, **kwargs):
|
||||
return '*** encoded ***'
|
||||
|
||||
@staticmethod
|
||||
def loads(*args, **kwargs):
|
||||
return '+++ decoded +++'
|
||||
|
||||
server.Server(json=CustomJSON)
|
||||
pkt = packet.Packet(packet.MESSAGE, data={'foo': 'bar'})
|
||||
self.assertEqual(pkt.encode(), b'4*** encoded ***')
|
||||
pkt2 = packet.Packet(encoded_packet=pkt.encode())
|
||||
self.assertEqual(pkt2.data, '+++ decoded +++')
|
||||
|
||||
# restore the default JSON module
|
||||
packet.Packet.json = json
|
||||
|
||||
def test_background_tasks(self):
|
||||
flag = {}
|
||||
|
||||
def bg_task():
|
||||
flag['task'] = True
|
||||
|
||||
s = server.Server()
|
||||
task = s.start_background_task(bg_task)
|
||||
task.join()
|
||||
self.assertIn('task', flag)
|
||||
self.assertTrue(flag['task'])
|
||||
|
||||
def test_sleep(self):
|
||||
s = server.Server()
|
||||
t = time.time()
|
||||
s.sleep(0.1)
|
||||
self.assertTrue(time.time() - t > 0.1)
|
||||
|
||||
def test_create_queue(self):
|
||||
s = server.Server()
|
||||
q = s.create_queue()
|
||||
empty = s.get_queue_empty_exception()
|
||||
self.assertRaises(empty, q.get, timeout=0.01)
|
||||
|
||||
def test_create_event(self):
|
||||
s = server.Server()
|
||||
e = s.create_event()
|
||||
self.assertFalse(e.is_set())
|
||||
e.set()
|
||||
self.assertTrue(e.is_set())
|
||||
|
||||
def test_service_task_started(self):
|
||||
s = server.Server(monitor_clients=True)
|
||||
s._service_task = mock.MagicMock()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_request(environ, start_response)
|
||||
s._service_task.assert_called_once_with()
|
||||
@@ -0,0 +1,424 @@
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import six
|
||||
if six.PY3:
|
||||
from unittest import mock
|
||||
else:
|
||||
import mock
|
||||
|
||||
from engineio import exceptions
|
||||
from engineio import packet
|
||||
from engineio import payload
|
||||
from engineio import socket
|
||||
|
||||
|
||||
class TestSocket(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.bg_tasks = []
|
||||
|
||||
def _get_mock_server(self):
|
||||
mock_server = mock.Mock()
|
||||
mock_server.ping_timeout = 0.2
|
||||
mock_server.ping_interval = 0.2
|
||||
mock_server.async_handlers = True
|
||||
|
||||
try:
|
||||
import queue
|
||||
except ImportError:
|
||||
import Queue as queue
|
||||
import threading
|
||||
mock_server._async = {'threading': threading.Thread,
|
||||
'queue': queue.Queue,
|
||||
'websocket': None}
|
||||
|
||||
def bg_task(target, *args, **kwargs):
|
||||
th = threading.Thread(target=target, args=args, kwargs=kwargs)
|
||||
self.bg_tasks.append(th)
|
||||
th.start()
|
||||
return th
|
||||
|
||||
def create_queue(*args, **kwargs):
|
||||
return queue.Queue(*args, **kwargs)
|
||||
|
||||
mock_server.start_background_task = bg_task
|
||||
mock_server.create_queue = create_queue
|
||||
mock_server.get_queue_empty_exception.return_value = queue.Empty
|
||||
return mock_server
|
||||
|
||||
def _join_bg_tasks(self):
|
||||
for task in self.bg_tasks:
|
||||
task.join()
|
||||
|
||||
def test_create(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
self.assertEqual(s.server, mock_server)
|
||||
self.assertEqual(s.sid, 'sid')
|
||||
self.assertFalse(s.upgraded)
|
||||
self.assertFalse(s.closed)
|
||||
self.assertTrue(hasattr(s.queue, 'get'))
|
||||
self.assertTrue(hasattr(s.queue, 'put'))
|
||||
self.assertTrue(hasattr(s.queue, 'task_done'))
|
||||
self.assertTrue(hasattr(s.queue, 'join'))
|
||||
|
||||
def test_empty_poll(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
self.assertRaises(exceptions.QueueEmpty, s.poll)
|
||||
|
||||
def test_poll(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
pkt1 = packet.Packet(packet.MESSAGE, data='hello')
|
||||
pkt2 = packet.Packet(packet.MESSAGE, data='bye')
|
||||
s.send(pkt1)
|
||||
s.send(pkt2)
|
||||
self.assertEqual(s.poll(), [pkt1, pkt2])
|
||||
|
||||
def test_ping_pong(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.receive(packet.Packet(packet.PING, data='abc'))
|
||||
r = s.poll()
|
||||
self.assertEqual(len(r), 1)
|
||||
self.assertTrue(r[0].encode(), b'3abc')
|
||||
|
||||
def test_message_async_handler(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.receive(packet.Packet(packet.MESSAGE, data='foo'))
|
||||
mock_server._trigger_event.assert_called_once_with('message', 'sid',
|
||||
'foo',
|
||||
run_async=True)
|
||||
|
||||
def test_message_sync_handler(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server.async_handlers = False
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.receive(packet.Packet(packet.MESSAGE, data='foo'))
|
||||
mock_server._trigger_event.assert_called_once_with('message', 'sid',
|
||||
'foo',
|
||||
run_async=False)
|
||||
|
||||
def test_invalid_packet(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
self.assertRaises(exceptions.UnknownPacketError, s.receive,
|
||||
packet.Packet(packet.OPEN))
|
||||
|
||||
def test_timeout(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server.ping_interval = -6
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.last_ping = time.time() - 1
|
||||
s.close = mock.MagicMock()
|
||||
s.send('packet')
|
||||
s.close.assert_called_once_with(wait=False, abort=False)
|
||||
|
||||
def test_polling_read(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'foo')
|
||||
pkt1 = packet.Packet(packet.MESSAGE, data='hello')
|
||||
pkt2 = packet.Packet(packet.MESSAGE, data='bye')
|
||||
s.send(pkt1)
|
||||
s.send(pkt2)
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
packets = s.handle_get_request(environ, start_response)
|
||||
self.assertEqual(packets, [pkt1, pkt2])
|
||||
|
||||
def test_polling_read_error(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'foo')
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo'}
|
||||
start_response = mock.MagicMock()
|
||||
self.assertRaises(exceptions.QueueEmpty, s.handle_get_request, environ,
|
||||
start_response)
|
||||
|
||||
def test_polling_write(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server.max_http_buffer_size = 1000
|
||||
pkt1 = packet.Packet(packet.MESSAGE, data='hello')
|
||||
pkt2 = packet.Packet(packet.MESSAGE, data='bye')
|
||||
p = payload.Payload(packets=[pkt1, pkt2]).encode()
|
||||
s = socket.Socket(mock_server, 'foo')
|
||||
s.receive = mock.MagicMock()
|
||||
environ = {'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo',
|
||||
'CONTENT_LENGTH': len(p), 'wsgi.input': six.BytesIO(p)}
|
||||
s.handle_post_request(environ)
|
||||
self.assertEqual(s.receive.call_count, 2)
|
||||
|
||||
def test_polling_write_too_large(self):
|
||||
mock_server = self._get_mock_server()
|
||||
pkt1 = packet.Packet(packet.MESSAGE, data='hello')
|
||||
pkt2 = packet.Packet(packet.MESSAGE, data='bye')
|
||||
p = payload.Payload(packets=[pkt1, pkt2]).encode()
|
||||
mock_server.max_http_buffer_size = len(p) - 1
|
||||
s = socket.Socket(mock_server, 'foo')
|
||||
s.receive = mock.MagicMock()
|
||||
environ = {'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo',
|
||||
'CONTENT_LENGTH': len(p), 'wsgi.input': six.BytesIO(p)}
|
||||
self.assertRaises(exceptions.ContentTooLongError,
|
||||
s.handle_post_request, environ)
|
||||
|
||||
def test_upgrade_handshake(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'foo')
|
||||
s._upgrade_websocket = mock.MagicMock()
|
||||
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo',
|
||||
'HTTP_CONNECTION': 'Foo,Upgrade,Bar',
|
||||
'HTTP_UPGRADE': 'websocket'}
|
||||
start_response = mock.MagicMock()
|
||||
s.handle_get_request(environ, start_response)
|
||||
s._upgrade_websocket.assert_called_once_with(environ, start_response)
|
||||
|
||||
def test_upgrade(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server._async['websocket'] = mock.MagicMock()
|
||||
mock_ws = mock.MagicMock()
|
||||
mock_server._async['websocket'].return_value = mock_ws
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
environ = "foo"
|
||||
start_response = "bar"
|
||||
s._upgrade_websocket(environ, start_response)
|
||||
mock_server._async['websocket'].assert_called_once_with(
|
||||
s._websocket_handler)
|
||||
mock_ws.assert_called_once_with(environ, start_response)
|
||||
|
||||
def test_upgrade_twice(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server._async['websocket'] = mock.MagicMock()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.upgraded = True
|
||||
environ = "foo"
|
||||
start_response = "bar"
|
||||
self.assertRaises(IOError, s._upgrade_websocket,
|
||||
environ, start_response)
|
||||
|
||||
def test_upgrade_packet(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.receive(packet.Packet(packet.UPGRADE))
|
||||
r = s.poll()
|
||||
self.assertEqual(len(r), 1)
|
||||
self.assertEqual(r[0].encode(), packet.Packet(packet.NOOP).encode())
|
||||
|
||||
def test_upgrade_no_probe(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.return_value = packet.Packet(packet.NOOP).encode(
|
||||
always_bytes=False)
|
||||
s._websocket_handler(ws)
|
||||
self.assertFalse(s.upgraded)
|
||||
|
||||
def test_upgrade_no_upgrade_packet(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
ws = mock.MagicMock()
|
||||
probe = six.text_type('probe')
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.PING, data=probe).encode(
|
||||
always_bytes=False),
|
||||
packet.Packet(packet.NOOP).encode(always_bytes=False)]
|
||||
s._websocket_handler(ws)
|
||||
ws.send.assert_called_once_with(packet.Packet(
|
||||
packet.PONG, data=probe).encode(always_bytes=False))
|
||||
self.assertEqual(s.queue.get().packet_type, packet.NOOP)
|
||||
self.assertFalse(s.upgraded)
|
||||
|
||||
def test_close_packet(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.close = mock.MagicMock()
|
||||
s.receive(packet.Packet(packet.CLOSE))
|
||||
s.close.assert_called_once_with(wait=False, abort=True)
|
||||
|
||||
def test_invalid_packet_type(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
pkt = packet.Packet(packet_type=99)
|
||||
self.assertRaises(exceptions.UnknownPacketError, s.receive, pkt)
|
||||
|
||||
def test_upgrade_not_supported(self):
|
||||
mock_server = self._get_mock_server()
|
||||
mock_server._async['websocket'] = None
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
environ = "foo"
|
||||
start_response = "bar"
|
||||
s._upgrade_websocket(environ, start_response)
|
||||
mock_server._bad_request.assert_called_once_with()
|
||||
|
||||
def test_websocket_read_write(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = False
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
foo = six.text_type('foo')
|
||||
bar = six.text_type('bar')
|
||||
s.poll = mock.MagicMock(side_effect=[
|
||||
[packet.Packet(packet.MESSAGE, data=bar)], exceptions.QueueEmpty])
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.MESSAGE, data=foo).encode(
|
||||
always_bytes=False),
|
||||
None]
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertTrue(s.connected)
|
||||
self.assertTrue(s.upgraded)
|
||||
self.assertEqual(mock_server._trigger_event.call_count, 2)
|
||||
mock_server._trigger_event.assert_has_calls([
|
||||
mock.call('message', 'sid', 'foo', run_async=True),
|
||||
mock.call('disconnect', 'sid', run_async=False)])
|
||||
ws.send.assert_called_with('4bar')
|
||||
|
||||
def test_websocket_upgrade_read_write(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
foo = six.text_type('foo')
|
||||
bar = six.text_type('bar')
|
||||
probe = six.text_type('probe')
|
||||
s.poll = mock.MagicMock(side_effect=[
|
||||
[packet.Packet(packet.MESSAGE, data=bar)], exceptions.QueueEmpty])
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.PING, data=probe).encode(
|
||||
always_bytes=False),
|
||||
packet.Packet(packet.UPGRADE).encode(always_bytes=False),
|
||||
packet.Packet(packet.MESSAGE, data=foo).encode(
|
||||
always_bytes=False),
|
||||
None]
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertTrue(s.upgraded)
|
||||
self.assertEqual(mock_server._trigger_event.call_count, 2)
|
||||
mock_server._trigger_event.assert_has_calls([
|
||||
mock.call('message', 'sid', 'foo', run_async=True),
|
||||
mock.call('disconnect', 'sid', run_async=False)])
|
||||
ws.send.assert_called_with('4bar')
|
||||
|
||||
def test_websocket_upgrade_with_payload(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
probe = six.text_type('probe')
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.PING, data=probe).encode(
|
||||
always_bytes=False),
|
||||
packet.Packet(packet.UPGRADE, data=b'2').encode(
|
||||
always_bytes=False)]
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertTrue(s.upgraded)
|
||||
|
||||
def test_websocket_upgrade_with_backlog(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = True
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
probe = six.text_type('probe')
|
||||
foo = six.text_type('foo')
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.PING, data=probe).encode(
|
||||
always_bytes=False),
|
||||
packet.Packet(packet.UPGRADE, data=b'2').encode(
|
||||
always_bytes=False)]
|
||||
s.upgrading = True
|
||||
s.send(packet.Packet(packet.MESSAGE, data=foo))
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertTrue(s.upgraded)
|
||||
self.assertFalse(s.upgrading)
|
||||
self.assertEqual(s.packet_backlog, [])
|
||||
ws.send.assert_called_with('4foo')
|
||||
|
||||
def test_websocket_read_write_wait_fail(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = False
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
foo = six.text_type('foo')
|
||||
bar = six.text_type('bar')
|
||||
s.poll = mock.MagicMock(side_effect=[
|
||||
[packet.Packet(packet.MESSAGE, data=bar)],
|
||||
[packet.Packet(packet.MESSAGE, data=bar)], exceptions.QueueEmpty])
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.MESSAGE, data=foo).encode(
|
||||
always_bytes=False),
|
||||
RuntimeError]
|
||||
ws.send.side_effect = [None, RuntimeError]
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertEqual(s.closed, True)
|
||||
|
||||
def test_websocket_ignore_invalid_packet(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.connected = False
|
||||
s.queue.join = mock.MagicMock(return_value=None)
|
||||
foo = six.text_type('foo')
|
||||
bar = six.text_type('bar')
|
||||
s.poll = mock.MagicMock(side_effect=[
|
||||
[packet.Packet(packet.MESSAGE, data=bar)], exceptions.QueueEmpty])
|
||||
ws = mock.MagicMock()
|
||||
ws.wait.side_effect = [
|
||||
packet.Packet(packet.OPEN).encode(always_bytes=False),
|
||||
packet.Packet(packet.MESSAGE, data=foo).encode(
|
||||
always_bytes=False),
|
||||
None]
|
||||
s._websocket_handler(ws)
|
||||
self._join_bg_tasks()
|
||||
self.assertTrue(s.connected)
|
||||
self.assertEqual(mock_server._trigger_event.call_count, 2)
|
||||
mock_server._trigger_event.assert_has_calls([
|
||||
mock.call('message', 'sid', foo, run_async=True),
|
||||
mock.call('disconnect', 'sid', run_async=False)])
|
||||
ws.send.assert_called_with('4bar')
|
||||
|
||||
def test_send_after_close(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.close(wait=False)
|
||||
self.assertRaises(exceptions.SocketIsClosedError, s.send,
|
||||
packet.Packet(packet.NOOP))
|
||||
|
||||
def test_close_after_close(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.close(wait=False)
|
||||
self.assertTrue(s.closed)
|
||||
self.assertEqual(mock_server._trigger_event.call_count, 1)
|
||||
mock_server._trigger_event.assert_called_once_with('disconnect', 'sid',
|
||||
run_async=False)
|
||||
s.close()
|
||||
self.assertEqual(mock_server._trigger_event.call_count, 1)
|
||||
|
||||
def test_close_and_wait(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.queue = mock.MagicMock()
|
||||
s.close(wait=True)
|
||||
s.queue.join.assert_called_once_with()
|
||||
|
||||
def test_close_without_wait(self):
|
||||
mock_server = self._get_mock_server()
|
||||
s = socket.Socket(mock_server, 'sid')
|
||||
s.queue = mock.MagicMock()
|
||||
s.close(wait=False)
|
||||
self.assertEqual(s.queue.join.call_count, 0)
|
||||
Reference in New Issue
Block a user