diff --git a/backend/src/openarchiefbeheer/utils/tests/e2e.py b/backend/src/openarchiefbeheer/utils/tests/e2e.py index 0302d6e3d..4f9e0f694 100644 --- a/backend/src/openarchiefbeheer/utils/tests/e2e.py +++ b/backend/src/openarchiefbeheer/utils/tests/e2e.py @@ -3,6 +3,7 @@ from django.conf import settings from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.cache import cache +from django.test.testcases import LiveServerThread, QuietWSGIRequestHandler from playwright.async_api import async_playwright @@ -44,9 +45,28 @@ async def browser_page_with_tracing(): await browser.close() +class LiveServerThreadWithReuse(LiveServerThread): + """Live server thread with reuse of local addresses + + Apparently, after the server thread is stopped, the socket is still bound to the address and in TIME_WAIT state. + The connection is kept around so that any delayed packets can be matched to the connection and handled appropriately. + The OS will close the connection once a timeout period has passed. + By reusing the address, we prevent the ``socket.error: [Errno 48] Address already in use`` error. + """ + + def _create_server(self, connections_override=None): + return self.server_class( + (self.host, self.port), + QuietWSGIRequestHandler, + allow_reuse_address=True, + connections_override=connections_override, + ) + + class PlaywrightTestCase(StaticLiveServerTestCase): port = settings.E2E_PORT fixtures = ["permissions.json"] + server_thread_class = LiveServerThreadWithReuse def setUp(self): super().setUp()