|
|
@ -31,140 +31,142 @@ def _run(coro): |
|
|
|
@unittest.skipIf(sys.version_info < (3, 5), 'only for Python 3.5+') |
|
|
|
class TestAsyncManager(unittest.TestCase): |
|
|
|
def setUp(self): |
|
|
|
id = 0 |
|
|
|
|
|
|
|
def generate_id(): |
|
|
|
nonlocal id |
|
|
|
id += 1 |
|
|
|
return str(id) |
|
|
|
|
|
|
|
mock_server = mock.MagicMock() |
|
|
|
mock_server._emit_internal = AsyncMock() |
|
|
|
mock_server.eio.generate_id = generate_id |
|
|
|
self.bm = asyncio_manager.AsyncManager() |
|
|
|
self.bm.set_server(mock_server) |
|
|
|
self.bm.initialize() |
|
|
|
|
|
|
|
def test_connect(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
assert None in self.bm.rooms['/foo'] |
|
|
|
assert '123' in self.bm.rooms['/foo'] |
|
|
|
assert '123' in self.bm.rooms['/foo'][None] |
|
|
|
assert '123' in self.bm.rooms['/foo']['123'] |
|
|
|
assert self.bm.rooms['/foo'] == { |
|
|
|
None: {'123': True}, |
|
|
|
'123': {'123': True}, |
|
|
|
} |
|
|
|
assert sid in self.bm.rooms['/foo'] |
|
|
|
assert sid in self.bm.rooms['/foo'][None] |
|
|
|
assert sid in self.bm.rooms['/foo'][sid] |
|
|
|
assert dict(self.bm.rooms['/foo'][None]) == {sid: '123'} |
|
|
|
assert dict(self.bm.rooms['/foo'][sid]) == {sid: '123'} |
|
|
|
assert self.bm.sid_from_eio_sid('123', '/foo') == sid |
|
|
|
|
|
|
|
def test_pre_disconnect(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.pre_disconnect('123', '/foo') |
|
|
|
assert self.bm.pending_disconnect == {'/foo': ['123']} |
|
|
|
assert not self.bm.is_connected('123', '/foo') |
|
|
|
self.bm.pre_disconnect('456', '/foo') |
|
|
|
assert self.bm.pending_disconnect == {'/foo': ['123', '456']} |
|
|
|
assert not self.bm.is_connected('456', '/foo') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
assert self.bm.pending_disconnect == {'/foo': ['456']} |
|
|
|
self.bm.disconnect('456', '/foo') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
assert self.bm.is_connected(sid1, '/foo') |
|
|
|
assert self.bm.pre_disconnect(sid1, '/foo') == '123' |
|
|
|
assert self.bm.pending_disconnect == {'/foo': [sid1]} |
|
|
|
assert not self.bm.is_connected(sid1, '/foo') |
|
|
|
assert self.bm.pre_disconnect(sid2, '/foo') == '456' |
|
|
|
assert self.bm.pending_disconnect == {'/foo': [sid1, sid2]} |
|
|
|
assert not self.bm.is_connected(sid2, '/foo') |
|
|
|
self.bm.disconnect(sid1, '/foo') |
|
|
|
assert self.bm.pending_disconnect == {'/foo': [sid2]} |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
assert self.bm.pending_disconnect == {} |
|
|
|
|
|
|
|
def test_disconnect(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.enter_room('456', '/foo', 'baz') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
assert self.bm.rooms['/foo'] == { |
|
|
|
None: {'456': True}, |
|
|
|
'456': {'456': True}, |
|
|
|
'baz': {'456': True}, |
|
|
|
} |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'baz') |
|
|
|
self.bm.disconnect(sid1, '/foo') |
|
|
|
assert dict(self.bm.rooms['/foo'][None]) == {sid2: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo'][sid2]) == {sid2: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo']['baz']) == {sid2: '456'} |
|
|
|
|
|
|
|
def test_disconnect_default_namespace(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
assert self.bm.is_connected('123', '/') |
|
|
|
assert self.bm.is_connected('123', '/foo') |
|
|
|
self.bm.disconnect('123', '/') |
|
|
|
assert not self.bm.is_connected('123', '/') |
|
|
|
assert self.bm.is_connected('123', '/foo') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
assert not self.bm.is_connected('123', '/foo') |
|
|
|
assert self.bm.rooms['/'] == { |
|
|
|
None: {'456': True}, |
|
|
|
'456': {'456': True}, |
|
|
|
} |
|
|
|
assert self.bm.rooms['/foo'] == { |
|
|
|
None: {'456': True}, |
|
|
|
'456': {'456': True}, |
|
|
|
} |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('123', '/foo') |
|
|
|
sid3 = self.bm.connect('456', '/') |
|
|
|
sid4 = self.bm.connect('456', '/foo') |
|
|
|
assert self.bm.is_connected(sid1, '/') |
|
|
|
assert self.bm.is_connected(sid2, '/foo') |
|
|
|
assert not self.bm.is_connected(sid2, '/') |
|
|
|
assert not self.bm.is_connected(sid1, '/foo') |
|
|
|
self.bm.disconnect(sid1, '/') |
|
|
|
assert not self.bm.is_connected(sid1, '/') |
|
|
|
assert self.bm.is_connected(sid2, '/foo') |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
assert not self.bm.is_connected(sid2, '/foo') |
|
|
|
assert dict(self.bm.rooms['/'][None]) == {sid3: '456'} |
|
|
|
assert dict(self.bm.rooms['/'][sid3]) == {sid3: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo'][None]) == {sid4: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo'][sid4]) == {sid4: '456'} |
|
|
|
|
|
|
|
def test_disconnect_twice(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.disconnect('123', '/') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
self.bm.disconnect('123', '/') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
assert self.bm.rooms['/'] == { |
|
|
|
None: {'456': True}, |
|
|
|
'456': {'456': True}, |
|
|
|
} |
|
|
|
assert self.bm.rooms['/foo'] == { |
|
|
|
None: {'456': True}, |
|
|
|
'456': {'456': True}, |
|
|
|
} |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('123', '/foo') |
|
|
|
sid3 = self.bm.connect('456', '/') |
|
|
|
sid4 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.disconnect(sid1, '/') |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
self.bm.disconnect(sid1, '/') |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
assert dict(self.bm.rooms['/'][None]) == {sid3: '456'} |
|
|
|
assert dict(self.bm.rooms['/'][sid3]) == {sid3: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo'][None]) == {sid4: '456'} |
|
|
|
assert dict(self.bm.rooms['/foo'][sid4]) == {sid4: '456'} |
|
|
|
|
|
|
|
def test_disconnect_all(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.enter_room('456', '/foo', 'baz') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
self.bm.disconnect('456', '/foo') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'baz') |
|
|
|
self.bm.disconnect(sid1, '/foo') |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
assert self.bm.rooms == {} |
|
|
|
|
|
|
|
def test_disconnect_with_callbacks(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm._generate_ack_id('123', '/', 'f') |
|
|
|
self.bm._generate_ack_id('123', '/foo', 'g') |
|
|
|
self.bm.disconnect('123', '/foo') |
|
|
|
assert '/foo' not in self.bm.callbacks['123'] |
|
|
|
self.bm.disconnect('123', '/') |
|
|
|
assert '123' not in self.bm.callbacks |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('123', '/foo') |
|
|
|
sid3 = self.bm.connect('456', '/foo') |
|
|
|
self.bm._generate_ack_id(sid1, 'f') |
|
|
|
self.bm._generate_ack_id(sid2, 'g') |
|
|
|
self.bm._generate_ack_id(sid3, 'h') |
|
|
|
self.bm.disconnect(sid2, '/foo') |
|
|
|
assert sid2 not in self.bm.callbacks |
|
|
|
self.bm.disconnect(sid1, '/') |
|
|
|
assert sid1 not in self.bm.callbacks |
|
|
|
assert sid3 in self.bm.callbacks |
|
|
|
|
|
|
|
def test_trigger_sync_callback(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('123', '/foo') |
|
|
|
cb = mock.MagicMock() |
|
|
|
id1 = self.bm._generate_ack_id('123', '/', cb) |
|
|
|
id2 = self.bm._generate_ack_id('123', '/foo', cb) |
|
|
|
_run(self.bm.trigger_callback('123', '/', id1, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback('123', '/foo', id2, ['bar', 'baz'])) |
|
|
|
id1 = self.bm._generate_ack_id(sid1, cb) |
|
|
|
id2 = self.bm._generate_ack_id(sid2, cb) |
|
|
|
_run(self.bm.trigger_callback(sid1, id1, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback(sid2, id2, ['bar', 'baz'])) |
|
|
|
assert cb.call_count == 2 |
|
|
|
cb.assert_any_call('foo') |
|
|
|
cb.assert_any_call('bar', 'baz') |
|
|
|
|
|
|
|
def test_trigger_async_callback(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('123', '/foo') |
|
|
|
cb = AsyncMock() |
|
|
|
id1 = self.bm._generate_ack_id('123', '/', cb) |
|
|
|
id2 = self.bm._generate_ack_id('123', '/foo', cb) |
|
|
|
_run(self.bm.trigger_callback('123', '/', id1, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback('123', '/foo', id2, ['bar', 'baz'])) |
|
|
|
id1 = self.bm._generate_ack_id(sid1, cb) |
|
|
|
id2 = self.bm._generate_ack_id(sid2, cb) |
|
|
|
_run(self.bm.trigger_callback(sid1, id1, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback(sid2, id2, ['bar', 'baz'])) |
|
|
|
assert cb.mock.call_count == 2 |
|
|
|
cb.mock.assert_any_call('foo') |
|
|
|
cb.mock.assert_any_call('bar', 'baz') |
|
|
|
|
|
|
|
def test_invalid_callback(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
sid = self.bm.connect('123', '/') |
|
|
|
cb = mock.MagicMock() |
|
|
|
id = self.bm._generate_ack_id('123', '/', cb) |
|
|
|
id = self.bm._generate_ack_id(sid, cb) |
|
|
|
|
|
|
|
# these should not raise an exception |
|
|
|
_run(self.bm.trigger_callback('124', '/', id, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback('123', '/foo', id, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback('123', '/', id + 1, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback('xxx', id, ['foo'])) |
|
|
|
_run(self.bm.trigger_callback(sid, id + 1, ['foo'])) |
|
|
|
assert cb.mock.call_count == 0 |
|
|
|
|
|
|
|
def test_get_namespaces(self): |
|
|
@ -177,30 +179,32 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
assert '/foo' in namespaces |
|
|
|
|
|
|
|
def test_get_participants(self): |
|
|
|
self.bm.connect('123', '/') |
|
|
|
self.bm.connect('456', '/') |
|
|
|
self.bm.connect('789', '/') |
|
|
|
self.bm.disconnect('789', '/') |
|
|
|
assert '789' not in self.bm.rooms['/'][None] |
|
|
|
sid1 = self.bm.connect('123', '/') |
|
|
|
sid2 = self.bm.connect('456', '/') |
|
|
|
sid3 = self.bm.connect('789', '/') |
|
|
|
self.bm.disconnect(sid3, '/') |
|
|
|
assert sid3 not in self.bm.rooms['/'][None] |
|
|
|
participants = list(self.bm.get_participants('/', None)) |
|
|
|
assert len(participants) == 2 |
|
|
|
assert '789' not in participants |
|
|
|
assert (sid1, '123') in participants |
|
|
|
assert (sid2, '456') in participants |
|
|
|
assert (sid3, '789') not in participants |
|
|
|
|
|
|
|
def test_leave_invalid_room(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.leave_room('123', '/foo', 'baz') |
|
|
|
self.bm.leave_room('123', '/bar', 'baz') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
self.bm.leave_room(sid, '/foo', 'baz') |
|
|
|
self.bm.leave_room(sid, '/bar', 'baz') |
|
|
|
|
|
|
|
def test_no_room(self): |
|
|
|
rooms = self.bm.get_rooms('123', '/foo') |
|
|
|
assert [] == rooms |
|
|
|
|
|
|
|
def test_close_room(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.connect('789', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.enter_room(sid, '/foo', 'bar') |
|
|
|
self.bm.enter_room(sid, '/foo', 'bar') |
|
|
|
_run(self.bm.close_room('bar', '/foo')) |
|
|
|
assert 'bar' not in self.bm.rooms['/foo'] |
|
|
|
|
|
|
@ -208,19 +212,19 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
self.bm.close_room('bar', '/foo') |
|
|
|
|
|
|
|
def test_rooms(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
r = self.bm.get_rooms('123', '/foo') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room(sid, '/foo', 'bar') |
|
|
|
r = self.bm.get_rooms(sid, '/foo') |
|
|
|
assert len(r) == 2 |
|
|
|
assert '123' in r |
|
|
|
assert sid in r |
|
|
|
assert 'bar' in r |
|
|
|
|
|
|
|
def test_emit_to_sid(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
_run( |
|
|
|
self.bm.emit( |
|
|
|
'my event', {'foo': 'bar'}, namespace='/foo', room='123' |
|
|
|
'my event', {'foo': 'bar'}, namespace='/foo', room=sid |
|
|
|
) |
|
|
|
) |
|
|
|
self.bm.server._emit_internal.mock.assert_called_once_with( |
|
|
@ -228,10 +232,10 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_emit_to_room(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('456', '/foo', 'bar') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'bar') |
|
|
|
self.bm.connect('789', '/foo') |
|
|
|
_run( |
|
|
|
self.bm.emit( |
|
|
@ -247,10 +251,10 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_emit_to_all(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('456', '/foo', 'bar') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'bar') |
|
|
|
self.bm.connect('789', '/foo') |
|
|
|
self.bm.connect('abc', '/bar') |
|
|
|
_run(self.bm.emit('my event', {'foo': 'bar'}, namespace='/foo')) |
|
|
@ -266,15 +270,15 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_emit_to_all_skip_one(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('456', '/foo', 'bar') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'bar') |
|
|
|
self.bm.connect('789', '/foo') |
|
|
|
self.bm.connect('abc', '/bar') |
|
|
|
_run( |
|
|
|
self.bm.emit( |
|
|
|
'my event', {'foo': 'bar'}, namespace='/foo', skip_sid='456' |
|
|
|
'my event', {'foo': 'bar'}, namespace='/foo', skip_sid=sid2 |
|
|
|
) |
|
|
|
) |
|
|
|
assert self.bm.server._emit_internal.mock.call_count == 2 |
|
|
@ -286,18 +290,18 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_emit_to_all_skip_two(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room('123', '/foo', 'bar') |
|
|
|
self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room('456', '/foo', 'bar') |
|
|
|
self.bm.connect('789', '/foo') |
|
|
|
sid1 = self.bm.connect('123', '/foo') |
|
|
|
self.bm.enter_room(sid1, '/foo', 'bar') |
|
|
|
sid2 = self.bm.connect('456', '/foo') |
|
|
|
self.bm.enter_room(sid2, '/foo', 'bar') |
|
|
|
sid3 = self.bm.connect('789', '/foo') |
|
|
|
self.bm.connect('abc', '/bar') |
|
|
|
_run( |
|
|
|
self.bm.emit( |
|
|
|
'my event', |
|
|
|
{'foo': 'bar'}, |
|
|
|
namespace='/foo', |
|
|
|
skip_sid=['123', '789'], |
|
|
|
skip_sid=[sid1, sid3], |
|
|
|
) |
|
|
|
) |
|
|
|
assert self.bm.server._emit_internal.mock.call_count == 1 |
|
|
@ -306,7 +310,7 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
) |
|
|
|
|
|
|
|
def test_emit_with_callback(self): |
|
|
|
self.bm.connect('123', '/foo') |
|
|
|
sid = self.bm.connect('123', '/foo') |
|
|
|
self.bm._generate_ack_id = mock.MagicMock() |
|
|
|
self.bm._generate_ack_id.return_value = 11 |
|
|
|
_run( |
|
|
@ -314,7 +318,7 @@ class TestAsyncManager(unittest.TestCase): |
|
|
|
'my event', {'foo': 'bar'}, namespace='/foo', callback='cb' |
|
|
|
) |
|
|
|
) |
|
|
|
self.bm._generate_ack_id.assert_called_once_with('123', '/foo', 'cb') |
|
|
|
self.bm._generate_ack_id.assert_called_once_with(sid, 'cb') |
|
|
|
self.bm.server._emit_internal.mock.assert_called_once_with( |
|
|
|
'123', 'my event', {'foo': 'bar'}, '/foo', 11 |
|
|
|
) |
|
|
|