| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import importlib
- import io
- import json
- import os
- import pytest
- from fastapi.testclient import TestClient
- @pytest.fixture()
- def client(tmp_path, monkeypatch):
- app_mod = importlib.import_module("app")
- app_mod.STORE_DIR = str(tmp_path)
- os.makedirs(app_mod.STORE_DIR, exist_ok=True)
- class DummyRecoApp:
- def __init__(self, name, digit, shift):
- self.name = name
- self.digit = digit
- self.shift = shift
- def start_reconstruction(self, path_raw_data, path_np_data_json, path_order_json):
- import matplotlib.pyplot as plt
- plt.figure()
- plt.plot([0, 1], [0, 1])
- plt.title(f"{self.name}-{self.digit}")
- plt.savefig("data/test.png")
- plt.close()
- monkeypatch.setattr(app_mod, "ReconstructionApp", DummyRecoApp, raising=True)
- return TestClient(app_mod.app)
- def _upload(client: TestClient, name: str, content: bytes, mime: str = "application/octet-stream"):
- files = {"file": (name, io.BytesIO(content), mime)}
- r = client.post("/upload", files=files)
- assert r.status_code == 200, r.text
- obj = r.json()
- assert "file_id" in obj
- return obj["file_id"]
- def test_upload_json(client: TestClient):
- params = {
- "Np": 8, "Nf": 8, "sl_nb": 1,
- "contrasts": 1, "RF_spoil": 0,
- "ETL": 0, "N_TE": 0, "phi_wing": 0, "N_wings": 0,
- "D_scans": 1
- }
- fid = _upload(client, "params.json", json.dumps(params).encode("utf-8"), "application/json")
- assert isinstance(fid, str) and len(fid) > 0
- def test_upload_h5(client: TestClient):
- fake = b"\x89HDF\r\n\x1a\n" + b"\x00" * 64
- fid = _upload(client, "raw.h5", fake, "application/octet-stream")
- assert isinstance(fid, str) and len(fid) > 0
- def test_full_reconstruction_flow(client: TestClient, tmp_path):
- raw_bytes = b"\x89HDF\r\n\x1a\n" + b"\x00" * 64
- raw_id = _upload(client, "raw.h5", raw_bytes)
- params = {
- "Np": 8, "Nf": 8, "sl_nb": 1,
- "contrasts": 1, "RF_spoil": 0,
- "ETL": 0, "N_TE": 0, "phi_wing": 0, "N_wings": 0,
- "D_scans": 1
- }
- json_id = _upload(client, "params.json", json.dumps(params).encode("utf-8"), "application/json")
- payload = {
- "file_raw_id": raw_id,
- "file_json_id": json_id,
- "file_order_id": None,
- "sequence_name": "linear_decart",
- "digit": "2d",
- "phase_shift": True
- }
- r = client.post("/reconstruct", json=payload)
- assert r.status_code == 200, r.text
- job = r.json()
- job_id = job["job_id"]
- for _ in range(50):
- s = client.get(f"/jobs/{job_id}")
- assert s.status_code == 200
- st = s.json()
- if st["status"] in ("done", "error"):
- break
- assert st["status"] == "done", f"job failed: {st.get('error_traceback')}"
- lf = client.get(f"/jobs/{job_id}/files")
- assert lf.status_code == 200
- files = lf.json()["files"]
- assert any(name.endswith(".png") for name in files), f"no png files in {files}"
- dz = client.get(f"/jobs/{job_id}/archive.zip")
- assert dz.status_code == 200
- assert dz.headers.get("content-type") == "application/zip"
- def test_reconstruct_bad_ids(client: TestClient):
- payload = {
- "file_raw_id": "nope",
- "file_json_id": "nope",
- "file_order_id": None,
- "sequence_name": "linear_decart",
- "digit": "2d",
- "phase_shift": False
- }
- r = client.post("/reconstruct", json=payload)
- assert r.status_code == 400
|