From 94d494866f39c321075080c62df9bd9e10de14ea Mon Sep 17 00:00:00 2001 From: Kevin Morris Date: Sat, 23 Oct 2021 20:06:00 -0700 Subject: [PATCH] fix(fastapi): increase recursion limit during tests The default recursion limit used by Docker's archlinux:base-devel Python package becomes problematic in some cases when running tests against our FastAPI application using starlette.testclient.TestClient (aliased to fastapi.testclient.TestClient). starlette ends up with test failures because it exceeds the recursion limit, but this only happens when using the `TestClient`. When the ASGI servers are run, this is not an issue and so in that case, the recursion limit has not been touched. This change uses a `TEST_RECURSION_LIMIT` environment variable to modify the recursion limit of the FastAPI application. This variable is, by default, only supplied when running pytests in Docker, but can be force-supplied by the user. TEST_RECURSION_LIMIT=10000 has been added to `.env` and `.gitlab-ci.yml`. Signed-off-by: Kevin Morris --- .env | 1 + .gitlab-ci.yml | 1 + aurweb/asgi.py | 15 +++++++++++++++ docker-compose.yml | 3 +++ 4 files changed, 20 insertions(+) diff --git a/.env b/.env index 6a383e6d..06e862c1 100644 --- a/.env +++ b/.env @@ -4,3 +4,4 @@ MARIADB_SOCKET_DIR="/var/run/mysqld/" CGIT_CLONE_PREFIX_PHP=https://localhost:8443 CGIT_CLONE_PREFIX_FASTAPI=https://localhost:8444 GIT_DATA_DIR="./aur.git/" +TEST_RECURSION_LIMIT=10000 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a8ddf08f..17b666d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ cache: variables: AUR_CONFIG: conf/config # Default MySQL config setup in before_script. DB_HOST: localhost + TEST_RECURSION_LIMIT: 10000 before_script: - export PATH="$HOME/.poetry/bin:${PATH}" diff --git a/aurweb/asgi.py b/aurweb/asgi.py index 9b4f6c21..8ebeef29 100644 --- a/aurweb/asgi.py +++ b/aurweb/asgi.py @@ -1,5 +1,7 @@ import asyncio import http +import os +import sys import typing from urllib.parse import quote_plus @@ -25,6 +27,19 @@ app = FastAPI(exception_handlers=errors.exceptions) @app.on_event("startup") async def app_startup(): + # https://stackoverflow.com/questions/67054759/about-the-maximum-recursion-error-in-fastapi + # Test failures have been observed by internal starlette code when + # using starlette.testclient.TestClient. Looking around in regards + # to the recursion error has really not recommended a course of action + # other than increasing the recursion limit. For now, that is how + # we handle the issue: an optional TEST_RECURSION_LIMIT env var + # provided by the user. Docker uses .env's TEST_RECURSION_LIMIT + # when running test suites. + # TODO: Find a proper fix to this issue. + recursion_limit = int(os.environ.get( + "TEST_RECURSION_LIMIT", sys.getrecursionlimit())) + sys.setrecursionlimit(recursion_limit) + session_secret = aurweb.config.get("fastapi", "session_secret") if not session_secret: raise Exception("[fastapi] session_secret must not be empty") diff --git a/docker-compose.yml b/docker-compose.yml index e86d8671..e19c8fb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -216,6 +216,7 @@ services: init: true environment: - AUR_CONFIG=conf/config + - TEST_RECURSION_LIMIT=${TEST_RECURSION_LIMIT} entrypoint: /docker/test-mysql-entrypoint.sh command: /docker/scripts/run-pytests.sh clean stdin_open: true @@ -241,6 +242,7 @@ services: init: true environment: - AUR_CONFIG=conf/config.sqlite + - TEST_RECURSION_LIMIT=${TEST_RECURSION_LIMIT} entrypoint: /docker/test-sqlite-entrypoint.sh command: setup-sqlite.sh run-pytests.sh clean stdin_open: true @@ -262,6 +264,7 @@ services: init: true environment: - AUR_CONFIG=conf/config + - TEST_RECURSION_LIMIT=${TEST_RECURSION_LIMIT} entrypoint: /docker/tests-entrypoint.sh command: setup-sqlite.sh run-tests.sh stdin_open: true