Skip to content

Commit 311a074

Browse files
GitHKAndrei Neaguodeimaiz
authored
GC no longer removes projects if user is not GUEST (#1491)
* avoids GC removing projects when not guest * added tests to catch any future issues * [ci skip] fixed comments * refactored test - applied black reformatting - merged 2 tests Co-authored-by: Andrei Neagu <[email protected]> Co-authored-by: Odei Maiz <[email protected]>
1 parent 8866918 commit 311a074

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

services/web/server/src/simcore_service_webserver/resource_manager/garbage_collector.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ async def remove_resources_if_guest_user(
8383
"""When a guest user finishes using the platform its Posgtres
8484
and S3/MinIO entries need to be removed
8585
"""
86+
logger.debug("Will try to remove resources for user '%s' if GUEST", user_id)
87+
if not await is_user_guest(app, user_id):
88+
logger.debug("User is not GUEST, skipping removal of its project resources")
89+
return
90+
8691
logger.debug(
8792
"Removing project '%s' from the database", project_uuid,
8893
)
@@ -91,9 +96,7 @@ async def remove_resources_if_guest_user(
9196
except ProjectNotFoundError:
9297
logging.warning("Project '%s' not found, skipping removal", project_uuid)
9398

94-
logger.debug("Will try to remove resources for user '%s' if GUEST", user_id)
95-
if await is_user_guest(app, user_id):
96-
await delete_user(app, user_id)
99+
await delete_user(app, user_id)
97100

98101

99102
async def garbage_collector_task(app: web.Application):

services/web/server/tests/unit/with_dbs/test_resource_manager.py

+56-3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def client(loop, aiohttp_client, app_cfg, postgres_service):
7272
)
7373
)
7474

75+
7576
@pytest.fixture()
7677
async def logged_user(client, user_role: UserRole):
7778
""" adds a user in db and logs in with client
@@ -321,7 +322,7 @@ async def test_interactive_services_removed_after_logout(
321322
mocked_dynamic_service,
322323
client_session_id,
323324
socketio_client,
324-
storage_subsystem_mock, # when guest user logs out garbage is collected
325+
storage_subsystem_mock, # when guest user logs out garbage is collected
325326
):
326327
set_service_deletion_delay(SERVICE_DELETION_DELAY, client.server.app)
327328
# login - logged_user fixture
@@ -365,7 +366,7 @@ async def test_interactive_services_remain_after_websocket_reconnection_from_2_t
365366
mocked_dynamic_service,
366367
socketio_client,
367368
client_session_id,
368-
storage_subsystem_mock, # when guest user logs out garbage is collected
369+
storage_subsystem_mock, # when guest user logs out garbage is collected
369370
):
370371

371372
set_service_deletion_delay(SERVICE_DELETION_DELAY, client.server.app)
@@ -437,7 +438,7 @@ async def test_interactive_services_removed_per_project(
437438
socketio_client,
438439
client_session_id,
439440
asyncpg_storage_system_mock,
440-
storage_subsystem_mock, # when guest user logs out garbage is collected
441+
storage_subsystem_mock, # when guest user logs out garbage is collected
441442
):
442443
set_service_deletion_delay(SERVICE_DELETION_DELAY, client.server.app)
443444
# create server with delay set to DELAY
@@ -541,3 +542,55 @@ async def test_services_remain_after_closing_one_out_of_two_tabs(
541542
mocked_director_api["stop_service"].assert_has_calls(
542543
[call(client.server.app, service["service_uuid"])]
543544
)
545+
546+
547+
@pytest.mark.parametrize(
548+
"user_role, expect_call",
549+
[(UserRole.USER, False), (UserRole.TESTER, False), (UserRole.GUEST, True)],
550+
)
551+
async def test_websocket_disconnected_remove_or_maintain_files_based_on_role(
552+
loop,
553+
client,
554+
logged_user,
555+
empty_user_project,
556+
mocked_director_api,
557+
mocked_dynamic_service,
558+
client_session_id,
559+
socketio_client,
560+
asyncpg_storage_system_mock,
561+
storage_subsystem_mock, # when guest user logs out garbage is collected
562+
expect_call,
563+
):
564+
set_service_deletion_delay(SERVICE_DELETION_DELAY, client.server.app)
565+
# login - logged_user fixture
566+
# create empty study - empty_user_project fixture
567+
# create dynamic service - mocked_dynamic_service fixture
568+
service = await mocked_dynamic_service(
569+
logged_user["id"], empty_user_project["uuid"]
570+
)
571+
# create websocket
572+
client_session_id1 = client_session_id()
573+
sio = await socketio_client(client_session_id1)
574+
# open project in client 1
575+
await open_project(client, empty_user_project["uuid"], client_session_id1)
576+
# logout
577+
logout_url = client.app.router["auth_logout"].url_for()
578+
r = await client.post(logout_url, json={"client_session_id": client_session_id1})
579+
assert r.url_obj.path == logout_url.path
580+
await assert_status(r, web.HTTPOk)
581+
# ensure sufficient time is wasted here
582+
await sleep(SERVICE_DELETION_DELAY + GARBAGE_COLLECTOR_INTERVAL + 1)
583+
# assert dynamic service is removed
584+
calls = [call(client.server.app, service["service_uuid"])]
585+
mocked_director_api["stop_service"].assert_has_calls(calls)
586+
587+
if expect_call:
588+
# make sure `delete_project_from_db` is called
589+
storage_subsystem_mock[1].assert_called_once()
590+
# make sure `delete_user` is called
591+
asyncpg_storage_system_mock.assert_called_once()
592+
else:
593+
# make sure `delete_project_from_db` not called
594+
storage_subsystem_mock[1].assert_not_called()
595+
# make sure `delete_user` not called
596+
asyncpg_storage_system_mock.assert_not_called()

0 commit comments

Comments
 (0)