support/testing: add fastapi runtime test

Add a runtime test for fastapi. Use uvicorn as the asgi server
application as does the fastapi hello world example [1].

Fastapi depends on PydanticV2 now which is written in rust so we need to
run the test on armv7.

[1] https://fastapi.tiangolo.com/tutorial/first-steps/

Signed-off-by: Marcus Hoffmann <bubu@bubu1.eu>
[Arnout:
 - fix flake8 errors
support/testing/tests/package/sample_python_fastapi.py:5:1: E302 expected 2 blank lines, found 1
support/testing/tests/package/sample_python_fastapi.py:8:1: W391 blank line at end of file
 - Remove BR2_CCACHE (as requested by Marcus).
 - Add a comment explaining that this also tests uvicorn and pydantic.
 - Re-try wget in a loop instead of a fixed timeout of 30 seconds.
 - Add a DEVELOPERS entry.
]
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
This commit is contained in:
Marcus Hoffmann 2024-02-05 18:25:10 +01:00 committed by Arnout Vandecappelle
parent 9ab334817a
commit 4e5a25a112
3 changed files with 69 additions and 0 deletions

View File

@ -2064,6 +2064,10 @@ F: package/selinux-python/
F: utils/config
F: utils/diffconfig
N: Marcus Hoffmann <bubu@bubu1.eu>
F: support/testing/tests/package/test_python_fastapi.py
F: support/testing/tests/package/sample_python_fastapi.py
N: Marek Belisko <marek.belisko@open-nandra.com>
F: package/libatasmart/
F: package/polkit/

View File

@ -0,0 +1,8 @@
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}

View File

@ -0,0 +1,57 @@
import os
import time
from tests.package.test_python import TestPythonPackageBase
class TestPythonPy3Fastapi(TestPythonPackageBase):
"""Test fastapi, uvicorn and pydantic2.
fastapi needs an asgi server to run. Since we select uvicorn as
asgi server here, uvicorn is tested as well.
pydantic is an major dependency of fastapi so it is implicitly
tested here as well.
"""
__test__ = True
config = \
"""
BR2_arm=y
BR2_cortex_a9=y
BR2_ARM_ENABLE_NEON=y
BR2_ARM_ENABLE_VFP=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_FASTAPI=y
BR2_PACKAGE_PYTHON_UVICORN=y
BR2_TARGET_ROOTFS_CPIO=y
# BR2_TARGET_ROOTFS_TAR is not set
"""
sample_scripts = ["tests/package/sample_python_fastapi.py"]
timeout = 60
def test_run(self):
self.login()
self.check_sample_scripts_exist()
cmd = "uvicorn sample_python_fastapi:app > /dev/null 2>&1 &"
_, exit_code = self.emulator.run(cmd, timeout=self.timeout)
# Give enough time for the uvicorn server to start up
for attempt in range(30):
time.sleep(1)
cmd = "wget -q -O - http://127.0.0.1:8000/"
output, exit_code = self.emulator.run(cmd, timeout=self.timeout)
if exit_code == 0:
self.assertEqual(output[0], '{"message":"Hello World"}')
break
else:
self.assertTrue(False, "Timeout while waiting for fastapi server")
def login(self):
cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
self.emulator.boot(arch="armv7",
kernel="builtin",
options=["-initrd", cpio_file])
self.emulator.login()