async def test_websocket_resource_management( client, logged_user, socketio_client, client_session_id, ): app = client.server.app socket_registry = get_registry(app) cur_client_session_id = client_session_id() sio = await socketio_client(cur_client_session_id) sid = sio.sid resource_key = { "user_id": str(logged_user["id"]), "client_session_id": cur_client_session_id, } assert await socket_registry.find_keys( ("socket_id", sio.sid)) == [resource_key] assert sio.sid in await socket_registry.find_resources( resource_key, "socket_id") assert len(await socket_registry.find_resources(resource_key, "socket_id")) == 1 # NOTE: the socket.io client needs the websockets package in order to upgrade to websocket transport await sio.disconnect() assert not sio.sid assert not await socket_registry.find_keys(("socket_id", sio.sid)) assert not sid in await socket_registry.find_resources( resource_key, "socket_id") assert not await socket_registry.find_resources(resource_key, "socket_id")
async def disconnect_user_from_socketio(client, sio_connection_data): """disconnect a previously connected socket.io connection""" sio, resource_key = sio_connection_data sid = sio.sid socket_registry = get_registry(client.server.app) await sio.disconnect() assert not sio.sid assert not await socket_registry.find_keys(("socket_id", sio.sid)) assert not sid in await socket_registry.find_resources(resource_key, "socket_id") assert not await socket_registry.find_resources(resource_key, "socket_id")
async def test_websocket_disconnected_after_logout( client, logged_user, socketio_client, client_session_id, expected, mocker, ): app = client.server.app socket_registry = get_registry(app) # connect first socket cur_client_session_id1 = client_session_id() sio = await socketio_client(cur_client_session_id1) socket_logout_mock_callable = mocker.Mock() sio.on("logout", handler=socket_logout_mock_callable) # connect second socket cur_client_session_id2 = client_session_id() sio2 = await socketio_client(cur_client_session_id2) socket_logout_mock_callable2 = mocker.Mock() sio2.on("logout", handler=socket_logout_mock_callable2) # connect third socket cur_client_session_id3 = client_session_id() sio3 = await socketio_client(cur_client_session_id3) socket_logout_mock_callable3 = mocker.Mock() sio3.on("logout", handler=socket_logout_mock_callable3) # logout client with socket 2 logout_url = client.app.router["auth_logout"].url_for() r = await client.post(logout_url, json={"client_session_id": cur_client_session_id2}) assert r.url_obj.path == logout_url.path await assert_status(r, expected) # the socket2 should be gone await sleep(1) assert not sio2.sid socket_logout_mock_callable2.assert_not_called() # the others should receive a logout message through their respective sockets await sleep(3) socket_logout_mock_callable.assert_called_once() socket_logout_mock_callable2.assert_not_called( ) # note 2 should be not called ever socket_logout_mock_callable3.assert_called_once() await sleep(3) # first socket should be closed now assert not sio.sid # second socket also closed assert not sio3.sid
async def connect_to_socketio(client, user, socketio_client_factory: Callable): """Connect a user to a socket.io""" socket_registry = get_registry(client.server.app) cur_client_session_id = f"{uuid4()}" sio = await socketio_client_factory(cur_client_session_id, client) resource_key = { "user_id": str(user["id"]), "client_session_id": cur_client_session_id, } assert await socket_registry.find_keys(("socket_id", sio.sid)) == [resource_key] assert sio.sid in await socket_registry.find_resources(resource_key, "socket_id") assert len(await socket_registry.find_resources(resource_key, "socket_id")) == 1 sio_connection_data = sio, resource_key return sio_connection_data
async def test_websocket_multiple_connections( client, logged_user, socketio_client, client_session_id, ): app = client.server.app socket_registry = get_registry(app) NUMBER_OF_SOCKETS = 5 # connect multiple clients clients = [] for socket_count in range(1, NUMBER_OF_SOCKETS + 1): cur_client_session_id = client_session_id() sio = await socketio_client(cur_client_session_id) resource_key = { "user_id": str(logged_user["id"]), "client_session_id": cur_client_session_id, } assert await socket_registry.find_keys(("socket_id", sio.sid)) == [resource_key] assert [sio.sid] == await socket_registry.find_resources( resource_key, "socket_id" ) assert ( len( await socket_registry.find_resources( {"user_id": str(logged_user["id"]), "client_session_id": "*"}, "socket_id", ) ) == socket_count ) clients.append(sio) for sio in clients: sid = sio.sid await sio.disconnect() # need to attend the disconnect event to pass through the socketio internal queues await sleep(0.1) # must be >= 0.01 to work without issues, added some padding assert not sio.sid assert not await socket_registry.find_keys(("socket_id", sio.sid)) assert not sid in await socket_registry.find_resources( resource_key, "socket_id" ) assert not await socket_registry.find_resources(resource_key, "socket_id")
def redis_enabled_app(redis_client: aioredis.Redis, mocker, mock_env_devel_environment) -> web.Application: # app.cleanup_ctx.append(redis_client) in setup_redis would create a client and connect # to a real redis service. Instead, we mock the get_redis_client access mocker.patch("simcore_service_webserver.redis.get_redis_client", return_value=redis_client) mocker.patch( "simcore_service_webserver.resource_manager.registry.get_redis_client", return_value=redis_client, ) # ------------------ app = create_safe_application() assert setup_settings(app) assert setup_resource_manager(app) assert is_setup_completed("simcore_service_webserver.redis", app) assert get_plugin_settings(app).RESOURCE_MANAGER_RESOURCE_TTL_S == 3 assert get_registry(app) return app
def redis_registry( redis_enabled_app: web.Application) -> RedisResourceRegistry: return get_registry(redis_enabled_app)
def socket_registry(client: TestClient) -> RedisResourceRegistry: app = client.server.app # type: ignore socket_registry = get_registry(app) return socket_registry