feat: Flask-App-Factory mit Health-Check und QueueHandler
This commit is contained in:
@@ -37,6 +37,10 @@ explicit_package_bases = true
|
|||||||
module = "pytest"
|
module = "pytest"
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = "fakeredis"
|
||||||
|
ignore_missing_imports = true
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = ["tests"]
|
testpaths = ["tests"]
|
||||||
addopts = "-v --tb=short"
|
addopts = "-v --tb=short"
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
from src.queue.handler import QueueHandler
|
||||||
|
|
||||||
|
|
||||||
|
def create_app() -> Flask:
|
||||||
|
"""Erstellt und konfiguriert die Flask-App."""
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config.from_mapping(
|
||||||
|
REDIS_HOST="localhost",
|
||||||
|
REDIS_PORT=6379,
|
||||||
|
)
|
||||||
|
app.queue_handler = QueueHandler( # type: ignore[attr-defined]
|
||||||
|
redis_host=app.config["REDIS_HOST"],
|
||||||
|
redis_port=app.config["REDIS_PORT"],
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.route("/health")
|
||||||
|
def health() -> dict[str, object]:
|
||||||
|
return {"status": "ok", "queue_size": app.queue_handler.queue_size()} # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
return app
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
"""Tests für die Flask-App-Factory mit fakeredis."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import fakeredis
|
||||||
|
from flask import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
|
||||||
|
from src.app import create_app
|
||||||
|
from src.queue.handler import QueueHandler
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_app_returns_flask_app() -> None:
|
||||||
|
"""create_app() liefert eine Flask-App-Instanz zurück."""
|
||||||
|
app = create_app()
|
||||||
|
assert isinstance(app, Flask)
|
||||||
|
|
||||||
|
|
||||||
|
def test_health_returns_status_ok() -> None:
|
||||||
|
"""GET /health liefert 200 und JSON mit status=ok."""
|
||||||
|
app = create_app()
|
||||||
|
|
||||||
|
# QueueHandler mit fakeredis ersetzen
|
||||||
|
fake_redis = fakeredis.FakeRedis(decode_responses=True)
|
||||||
|
qh = QueueHandler.__new__(QueueHandler)
|
||||||
|
qh.redis = fake_redis
|
||||||
|
qh.stream_key = "bsn:submissions"
|
||||||
|
qh.processed_set = "bsn:processed"
|
||||||
|
qh.stream_ids_hash = "bsn:stream_ids"
|
||||||
|
qh.group_name = "bsn-workers"
|
||||||
|
qh._ensure_consumer_group()
|
||||||
|
app.queue_handler = qh # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
client: FlaskClient = app.test_client()
|
||||||
|
response = client.get("/health")
|
||||||
|
assert response.status_code == 200
|
||||||
|
data = response.get_json()
|
||||||
|
assert data is not None
|
||||||
|
assert data["status"] == "ok"
|
||||||
|
|
||||||
|
|
||||||
|
def test_health_queue_size_is_integer() -> None:
|
||||||
|
"""GET /health liefert queue_size als Integer."""
|
||||||
|
app = create_app()
|
||||||
|
|
||||||
|
# QueueHandler mit fakeredis ersetzen
|
||||||
|
fake_redis = fakeredis.FakeRedis(decode_responses=True)
|
||||||
|
qh = QueueHandler.__new__(QueueHandler)
|
||||||
|
qh.redis = fake_redis
|
||||||
|
qh.stream_key = "bsn:submissions"
|
||||||
|
qh.processed_set = "bsn:processed"
|
||||||
|
qh.stream_ids_hash = "bsn:stream_ids"
|
||||||
|
qh.group_name = "bsn-workers"
|
||||||
|
qh._ensure_consumer_group()
|
||||||
|
app.queue_handler = qh # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
client = app.test_client()
|
||||||
|
response = client.get("/health")
|
||||||
|
assert response.status_code == 200
|
||||||
|
data = response.get_json()
|
||||||
|
assert data is not None
|
||||||
|
assert isinstance(data["queue_size"], int)
|
||||||
Reference in New Issue
Block a user