Pi 번들 — arm64 빌드 머신이 필요하다고 적어 둔 것은 과한 가정이었다. --cross 모드에서 pip 이 태그로 aarch64/cp311 휠을 받으므로 네트워크만 있으면 된다. 휠 11개 전부 aarch64. "Pi 번들 미빌드"로 스킵되던 테스트가 이제 실제로 돈다. MoveNet — P3-3 의 잔여였던 죽은 원본을 유효한 tf2onnx 변환본으로 교체하고 sha256+size 로 고정했다. 고정 전에 어댑터 계약과 대조했다: 입력 [1,192,192,3] int32 NHWC, 출력 [1,1,17,3]. 레이아웃이 다른 변환본은 onnxruntime 에 그냥 로드되고 좌표만 틀리는 실패라, 파일이 바뀌었는지가 아니라 계약이 맞는지를 테스트로 박았다. 자격증명 회전 — 손으로 적던 SQL 절차를 명령 하나로 바꿨다. DB 에 접속하지 않고 붙여넣을 SQL 만 낸다(운영자의 창구가 phpMyAdmin 이므로 접속 정보 없이 어느 머신에서나 돌아야 한다). 비밀번호는 STDIN 으로만 받는다 — 명령행은 ps 와 셸 히스토리에 남는다. 테스트가 잠그는 것은 서버 키와 Pi 키의 일치, 그리고 앱이 그 해시를 검증하는지 두 가지다. 회전 실행 자체는 운영 계정 조작이라 저장소에서 수행하지 않는다. 검증: phpunit 276 passed(스킵 0, 신규 7) · pytest 스킵 2(환경) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBjuR7DW6PNNMows4KnbYU
47 lines
2.1 KiB
Python
47 lines
2.1 KiB
Python
"""Gated end-to-end smoke test for the real MoveNet ONNX model.
|
|
|
|
Skipped unless the model is bundled AND onnxruntime is installed, so the default
|
|
CI/dev suite (no model, no onnxruntime) stays green. On a build/pilot machine that
|
|
ran ``python -m edge.tools.fetch_movenet``, this exercises the full adapter path:
|
|
frame -> onnxruntime inference -> COCO-17 remap -> list[Person].
|
|
"""
|
|
import os
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
MODEL = os.path.join(os.path.dirname(__file__), "..", "..", "models", "movenet_lightning.onnx")
|
|
|
|
|
|
@pytest.mark.skipif(not os.path.exists(MODEL), reason="MoveNet model not bundled")
|
|
def test_real_movenet_runs():
|
|
pytest.importorskip("onnxruntime")
|
|
from edge.adapters.movenet_pose import MoveNetPoseAdapter
|
|
|
|
adapter = MoveNetPoseAdapter(MODEL)
|
|
persons = adapter.infer(np.full((480, 640, 3), 128, np.uint8))
|
|
|
|
# Runs end-to-end; a flat gray frame may yield 0 persons — the contract is
|
|
# only that it returns a list and, when non-empty, each Person has 17 keypoints.
|
|
assert isinstance(persons, list)
|
|
for person in persons:
|
|
assert len(person.keypoints) == 17
|
|
|
|
|
|
@pytest.mark.skipif(not os.path.exists(MODEL), reason="MoveNet model not bundled")
|
|
def test_model_signature_is_what_the_adapter_feeds_and_reads():
|
|
"""모델을 갈아끼웠을 때 조용히 틀리는 경우를 막는다.
|
|
|
|
레이아웃이 다른 변환본(NCHW·float32·[1,17,3])도 onnxruntime 에는 그냥 로드된다. 그러면
|
|
어댑터는 예외 없이 돌면서 엉뚱한 좌표를 내놓고, 낙상 판정은 "동작하는데 안 맞는" 상태가
|
|
된다. 파일이 바뀌었는지가 아니라 **계약이 맞는지**를 본다.
|
|
"""
|
|
ort = pytest.importorskip("onnxruntime")
|
|
session = ort.InferenceSession(MODEL, providers=["CPUExecutionProvider"])
|
|
|
|
inp = session.get_inputs()[0]
|
|
assert inp.shape == [1, 192, 192, 3], f"어댑터는 192x192 NHWC 를 넣는다: {inp.shape}"
|
|
assert inp.type == "tensor(int32)", f"어댑터는 int32 로 넣는다: {inp.type}"
|
|
|
|
out = session.get_outputs()[0]
|
|
assert out.shape == [1, 1, 17, 3], f"어댑터는 [1,1,17,3] (y,x,score) 를 읽는다: {out.shape}"
|