maybe use channels server for testing?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer
2025-01-16 00:47:17 +01:00
parent a11f1258e1
commit 9fda4e91ad
2 changed files with 60 additions and 3 deletions

52
tests/e2e/_process.py Normal file
View File

@ -0,0 +1,52 @@
"""authentik e2e testing utilities"""
import traceback
from daphne.testing import DaphneProcess, _reinstall_reactor
from django import setup as django_setup
from django.conf import settings
class TestDatabaseProcess(DaphneProcess):
"""Channels does not correctly switch to the test database by default.
https://github.com/django/channels/issues/2048"""
def run(self):
# OK, now we are in a forked child process, and want to use the reactor.
# However, FreeBSD systems like MacOS do not fork the underlying Kqueue,
# which asyncio (hence asyncioreactor) is built on.
# Therefore, we should uninstall the broken reactor and install a new one.
_reinstall_reactor()
if not settings.configured: # Fix For raise AppRegistryNotReady("Apps aren't loaded yet.")
django_setup() # Ensure Django is fully set up before using settings
from daphne.endpoints import build_endpoint_description_strings
from daphne.server import Server
from twisted.internet import reactor
application = self.get_application()
if not settings.DATABASES[list(settings.DATABASES.keys())[0]]["NAME"].startswith("test_"):
for _, db_settings in settings.DATABASES.items():
db_settings["NAME"] = f"test_{db_settings['NAME']}"
settings.TEST = True
try:
# Create the server class
endpoints = build_endpoint_description_strings(host=self.host, port=0)
self.server = Server(
application=application, endpoints=endpoints, signal_handlers=False, **self.kwargs
)
# Set up a poller to look for the port
reactor.callLater(0.1, self.resolve_port)
# Run with setup/teardown
if self.setup is not None:
self.setup()
try:
self.server.run()
finally:
if self.teardown is not None:
self.teardown()
except BaseException as e:
# Put the error on our queue so the parent gets it
self.errors.put((e, traceback.format_exc()))

View File

@ -12,8 +12,8 @@ from typing import Any
from unittest.case import TestCase from unittest.case import TestCase
from urllib.parse import urlencode from urllib.parse import urlencode
from channels.testing import ChannelsLiveServerTestCase
from django.apps import apps from django.apps import apps
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.db import connection from django.db import connection
from django.db.migrations.loader import MigrationLoader from django.db.migrations.loader import MigrationLoader
from django.test.testcases import TransactionTestCase from django.test.testcases import TransactionTestCase
@ -35,6 +35,7 @@ from authentik.core.api.users import UserSerializer
from authentik.core.models import User from authentik.core.models import User
from authentik.core.tests.utils import create_test_admin_user from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id from authentik.lib.generators import generate_id
from tests.e2e._process import TestDatabaseProcess
RETRIES = int(environ.get("RETRIES", "3")) RETRIES = int(environ.get("RETRIES", "3"))
IS_CI = "CI" in environ IS_CI = "CI" in environ
@ -152,13 +153,17 @@ class DockerTestCase(TestCase):
self.__network.remove() self.__network.remove()
class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase): class SeleniumTestCase(DockerTestCase, ChannelsLiveServerTestCase):
"""StaticLiveServerTestCase which automatically creates a Webdriver instance""" """ChannelsLiveServerTestCase which automatically creates a Webdriver instance"""
ProtocolServerProcess = TestDatabaseProcess
host = get_local_ip() host = get_local_ip()
wait_timeout: int wait_timeout: int
user: User user: User
serve_static = True
def setUp(self): def setUp(self):
if IS_CI: if IS_CI:
print("::group::authentik Logs", file=stderr) print("::group::authentik Logs", file=stderr)