mirror of
https://github.com/azaion/detections.git
synced 2026-04-22 19:56:32 +00:00
[AZ-137] [AZ-138] Decompose test tasks and scaffold E2E test infrastructure
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
RUN pip install --no-cache-dir flask gunicorn
|
||||
COPY app.py .
|
||||
EXPOSE 8081
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8081", "-w", "1", "--timeout", "120", "app:app"]
|
||||
@@ -0,0 +1,58 @@
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
_mode = "normal"
|
||||
_annotations: list = []
|
||||
|
||||
|
||||
def _fail():
|
||||
return _mode == "error"
|
||||
|
||||
|
||||
@app.route("/annotations", methods=["POST"])
|
||||
def annotations():
|
||||
if _fail():
|
||||
return "", 503
|
||||
_annotations.append(request.get_json(silent=True))
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/auth/refresh", methods=["POST"])
|
||||
def auth_refresh():
|
||||
if _fail():
|
||||
return "", 503
|
||||
return {"token": "refreshed-test-token"}
|
||||
|
||||
|
||||
@app.route("/mock/config", methods=["POST"])
|
||||
def mock_config():
|
||||
global _mode
|
||||
body = request.get_json(silent=True) or {}
|
||||
mode = body.get("mode", "normal")
|
||||
if mode not in ("normal", "error"):
|
||||
return "", 400
|
||||
_mode = mode
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/mock/reset", methods=["POST"])
|
||||
def mock_reset():
|
||||
global _mode, _annotations
|
||||
_mode = "normal"
|
||||
_annotations.clear()
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/mock/status", methods=["GET"])
|
||||
def mock_status():
|
||||
return {
|
||||
"mode": _mode,
|
||||
"annotation_count": len(_annotations),
|
||||
"annotations": list(_annotations),
|
||||
}
|
||||
|
||||
|
||||
@app.route("/mock/annotations", methods=["GET"])
|
||||
def mock_annotations_list():
|
||||
return {"annotations": list(_annotations)}
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
RUN pip install --no-cache-dir flask gunicorn
|
||||
COPY app.py .
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "-w", "1", "--timeout", "120", "app:app"]
|
||||
@@ -0,0 +1,110 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
_mode = "normal"
|
||||
_first_fail_remaining = False
|
||||
_uploads: dict[tuple[str, str], bytes] = {}
|
||||
_load_count = 0
|
||||
_upload_count = 0
|
||||
|
||||
|
||||
def _models_root() -> Path:
|
||||
return Path(os.environ.get("MODELS_ROOT", "/models"))
|
||||
|
||||
|
||||
def _resolve_disk_path(filename: str, folder: str | None) -> Path | None:
|
||||
root = _models_root()
|
||||
if folder:
|
||||
p = root / folder / filename
|
||||
else:
|
||||
p = root / filename
|
||||
if p.is_file():
|
||||
return p
|
||||
if folder is None:
|
||||
alt = root / "models" / filename
|
||||
if alt.is_file():
|
||||
return alt
|
||||
return None
|
||||
|
||||
|
||||
def _should_fail_load() -> bool:
|
||||
global _first_fail_remaining
|
||||
if _mode == "error":
|
||||
return True
|
||||
if _mode == "first_fail":
|
||||
if _first_fail_remaining:
|
||||
_first_fail_remaining = False
|
||||
return True
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
@app.route("/load/<path:filename>", methods=["GET", "POST"])
|
||||
def load(filename):
|
||||
global _load_count
|
||||
folder = None
|
||||
if request.method == "POST" and request.is_json:
|
||||
body = request.get_json(silent=True) or {}
|
||||
folder = body.get("folder")
|
||||
if _should_fail_load():
|
||||
return "", 503
|
||||
path = _resolve_disk_path(filename, folder)
|
||||
if path is None:
|
||||
key = (folder or "", filename)
|
||||
data = _uploads.get(key)
|
||||
if data is None and folder:
|
||||
data = _uploads.get(("", filename))
|
||||
if data is None:
|
||||
return "", 404
|
||||
_load_count += 1
|
||||
return data, 200
|
||||
_load_count += 1
|
||||
return path.read_bytes(), 200
|
||||
|
||||
|
||||
@app.route("/upload/<path:filename>", methods=["POST"])
|
||||
def upload(filename):
|
||||
global _upload_count
|
||||
folder = request.form.get("folder") or ""
|
||||
f = request.files.get("data")
|
||||
if not f:
|
||||
return "", 400
|
||||
_uploads[(folder, filename)] = f.read()
|
||||
_upload_count += 1
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/mock/config", methods=["POST"])
|
||||
def mock_config():
|
||||
global _mode, _first_fail_remaining
|
||||
body = request.get_json(silent=True) or {}
|
||||
mode = body.get("mode", "normal")
|
||||
if mode not in ("normal", "error", "first_fail"):
|
||||
return "", 400
|
||||
_mode = mode
|
||||
_first_fail_remaining = mode == "first_fail"
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/mock/reset", methods=["POST"])
|
||||
def mock_reset():
|
||||
global _mode, _first_fail_remaining, _uploads, _load_count, _upload_count
|
||||
_mode = "normal"
|
||||
_first_fail_remaining = False
|
||||
_uploads.clear()
|
||||
_load_count = 0
|
||||
_upload_count = 0
|
||||
return "", 200
|
||||
|
||||
|
||||
@app.route("/mock/status", methods=["GET"])
|
||||
def mock_status():
|
||||
return {
|
||||
"mode": _mode,
|
||||
"upload_count": _upload_count,
|
||||
"load_count": _load_count,
|
||||
}
|
||||
Reference in New Issue
Block a user