mirror of
https://github.com/azaion/detections.git
synced 2026-06-21 08:11:07 +00:00
Fixed isolate Jetson manual e2e and stabilize SSE warmup
This commit is contained in:
+46
-4
@@ -133,10 +133,11 @@ def image_detect(http_client, auth_headers):
|
||||
headers=headers,
|
||||
timeout=timeout,
|
||||
)
|
||||
done.wait(timeout=timeout)
|
||||
completed = done.wait(timeout=timeout)
|
||||
elapsed_ms = (time.perf_counter() - t0) * 1000.0
|
||||
|
||||
assert r.status_code == 202, f"Expected 202, got {r.status_code}: {r.text}"
|
||||
assert completed, f"Timed out waiting for terminal SSE event on channel {cid}"
|
||||
assert not errors, f"SSE errors: {errors}"
|
||||
|
||||
th.join(timeout=1)
|
||||
@@ -214,6 +215,27 @@ def _read_media(name: str) -> bytes:
|
||||
return p.read_bytes()
|
||||
|
||||
|
||||
def _health(http_client):
|
||||
r = http_client.get("/health")
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
|
||||
def _health_ai_active(data: dict) -> bool:
|
||||
return data.get("aiAvailability") not in ("None", "Downloading", "Error")
|
||||
|
||||
|
||||
def _wait_for_ai_active(http_client, timeout: float = 30) -> dict | None:
|
||||
deadline = time.time() + timeout
|
||||
last = None
|
||||
while time.time() < deadline:
|
||||
last = _health(http_client)
|
||||
if _health_ai_active(last):
|
||||
return last
|
||||
time.sleep(1)
|
||||
return last
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def media_dir():
|
||||
return str(_media_dir())
|
||||
@@ -280,11 +302,20 @@ def warm_engine(http_client, image_small, auth_headers):
|
||||
consecutive_errors = 0
|
||||
|
||||
while time.time() < deadline:
|
||||
try:
|
||||
current_health = _health(http_client)
|
||||
if _health_ai_active(current_health):
|
||||
return
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
cid = str(uuid.uuid4())
|
||||
headers = {**auth_headers, "X-Channel-Id": cid}
|
||||
done = threading.Event()
|
||||
terminal_status = None
|
||||
|
||||
def _listen(cid=cid):
|
||||
nonlocal terminal_status
|
||||
try:
|
||||
with http_client.get(
|
||||
f"/detect/events/{cid}",
|
||||
@@ -297,7 +328,8 @@ def warm_engine(http_client, image_small, auth_headers):
|
||||
if not ev.data or not str(ev.data).strip():
|
||||
continue
|
||||
data = json.loads(ev.data)
|
||||
if data.get("mediaStatus") == "AIProcessed":
|
||||
terminal_status = data.get("mediaStatus")
|
||||
if terminal_status in ("AIProcessed", "Error"):
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
@@ -316,9 +348,19 @@ def warm_engine(http_client, image_small, auth_headers):
|
||||
)
|
||||
last_status = r.status_code
|
||||
if r.status_code == 202:
|
||||
done.wait(timeout=30)
|
||||
completed = done.wait(timeout=30)
|
||||
th.join(timeout=1)
|
||||
return
|
||||
if completed and terminal_status == "AIProcessed":
|
||||
if _health_ai_active(_wait_for_ai_active(http_client, timeout=30) or {}):
|
||||
return
|
||||
if completed and terminal_status == "Error":
|
||||
consecutive_errors += 1
|
||||
else:
|
||||
active_health = _wait_for_ai_active(http_client, timeout=10)
|
||||
if _health_ai_active(active_health or {}):
|
||||
return
|
||||
time.sleep(2)
|
||||
continue
|
||||
if r.status_code >= 500:
|
||||
consecutive_errors += 1
|
||||
if consecutive_errors >= 5:
|
||||
|
||||
@@ -27,6 +27,7 @@ services:
|
||||
ANNOTATIONS_URL: http://mock-annotations:8081
|
||||
JWT_SECRET: test-secret-e2e-only
|
||||
CLASSES_JSON_PATH: /app/classes.json
|
||||
LOG_DIR: /app/Logs
|
||||
volumes:
|
||||
- ./fixtures:/media
|
||||
- detections-logs:/app/Logs
|
||||
@@ -50,6 +51,7 @@ services:
|
||||
ANNOTATIONS_URL: http://mock-annotations:8081
|
||||
JWT_SECRET: test-secret-e2e-only
|
||||
CLASSES_JSON_PATH: /app/classes.json
|
||||
LOG_DIR: /app/Logs
|
||||
volumes:
|
||||
- ./fixtures:/media
|
||||
- detections-logs:/app/Logs
|
||||
@@ -73,6 +75,7 @@ services:
|
||||
ANNOTATIONS_URL: http://mock-annotations:8081
|
||||
JWT_SECRET: test-secret-e2e-only
|
||||
CLASSES_JSON_PATH: /app/classes.json
|
||||
LOG_DIR: /app/Logs
|
||||
volumes:
|
||||
- ./fixtures:/media:ro
|
||||
- detections-logs:/app/Logs
|
||||
|
||||
@@ -29,11 +29,11 @@ def test_ft_p08_immediate_async_response(
|
||||
assert r.status_code == 202
|
||||
|
||||
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.timeout(30)
|
||||
def test_ft_p09_sse_event_delivery(
|
||||
warm_engine, http_client, jwt_token
|
||||
):
|
||||
media_id = f"sse-{uuid.uuid4().hex}"
|
||||
media_id = f"event-{uuid.uuid4().hex}"
|
||||
channel_id = str(uuid.uuid4())
|
||||
body = _ai_config_video()
|
||||
auth_header = {"Authorization": f"Bearer {jwt_token}"}
|
||||
|
||||
@@ -409,6 +409,7 @@ async def detect_events(channel_id: str, request: Request, after_ts: Optional[in
|
||||
|
||||
async def event_generator():
|
||||
try:
|
||||
yield ": connected\n\n"
|
||||
if after_ts is not None:
|
||||
for ts_ms, data in list(_channel_buffers.get(channel_id, [])):
|
||||
if ts_ms > after_ts:
|
||||
|
||||
Reference in New Issue
Block a user