项目里程碑初步优化
This commit is contained in:
@@ -2,10 +2,8 @@ import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
import uuid
|
||||
|
||||
import asyncpg
|
||||
|
||||
@@ -40,68 +38,6 @@ def request_json(path: str, *, method: str = "GET", token: str | None = None, pa
|
||||
return exc.code, body_json
|
||||
|
||||
|
||||
def request_bytes(path: str, *, method: str = "GET", token: str | None = None) -> tuple[int, bytes]:
|
||||
url = f"{BASE}{path}"
|
||||
headers = {}
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
req = urllib.request.Request(url, method=method, headers=headers)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
return resp.getcode(), resp.read()
|
||||
except urllib.error.HTTPError as exc:
|
||||
return exc.code, exc.read()
|
||||
|
||||
|
||||
def request_multipart(
|
||||
path: str,
|
||||
*,
|
||||
token: str,
|
||||
file_field: str,
|
||||
file_name: str,
|
||||
file_content: bytes,
|
||||
expected_version: int,
|
||||
) -> tuple[int, dict]:
|
||||
boundary = f"----ctms-boundary-{uuid.uuid4().hex}"
|
||||
chunks: list[bytes] = []
|
||||
chunks.append(
|
||||
(
|
||||
f"--{boundary}\r\n"
|
||||
f'Content-Disposition: form-data; name="expected_version"\r\n\r\n'
|
||||
f"{expected_version}\r\n"
|
||||
).encode("utf-8")
|
||||
)
|
||||
chunks.append(
|
||||
(
|
||||
f"--{boundary}\r\n"
|
||||
f'Content-Disposition: form-data; name="{file_field}"; filename="{file_name}"\r\n'
|
||||
f"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n\r\n"
|
||||
).encode("utf-8")
|
||||
)
|
||||
chunks.append(file_content)
|
||||
chunks.append(b"\r\n")
|
||||
chunks.append(f"--{boundary}--\r\n".encode("utf-8"))
|
||||
body = b"".join(chunks)
|
||||
|
||||
url = f"{BASE}{path}"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": f"multipart/form-data; boundary={boundary}",
|
||||
}
|
||||
req = urllib.request.Request(url, method="POST", headers=headers, data=body)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
text = resp.read().decode() or "{}"
|
||||
return resp.getcode(), json.loads(text)
|
||||
except urllib.error.HTTPError as exc:
|
||||
text = exc.read().decode() or "{}"
|
||||
try:
|
||||
body_json = json.loads(text)
|
||||
except Exception:
|
||||
body_json = {"raw": text}
|
||||
return exc.code, body_json
|
||||
|
||||
|
||||
def assert_or_exit(condition: bool, message: str) -> None:
|
||||
if not condition:
|
||||
print(f"[FAIL] {message}")
|
||||
@@ -440,24 +376,6 @@ def main() -> int:
|
||||
)
|
||||
print("[9/12] rollback_ok")
|
||||
|
||||
status, exported_bytes = request_bytes(f"/api/v1/studies/{study_id}/setup-config/export-excel", token=token)
|
||||
assert_or_exit(status == 200 and len(exported_bytes) > 0, f"导出Excel失败 status={status} bytes={len(exported_bytes)}")
|
||||
with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as tmp:
|
||||
tmp.write(exported_bytes)
|
||||
tmp_path = tmp.name
|
||||
print(f"[10/12] export_excel_ok file={tmp_path}")
|
||||
|
||||
status, imported = request_multipart(
|
||||
f"/api/v1/studies/{study_id}/setup-config/import-excel",
|
||||
token=token,
|
||||
file_field="file",
|
||||
file_name="setup-config-smoke.xlsx",
|
||||
file_content=exported_bytes,
|
||||
expected_version=rolled["version"],
|
||||
)
|
||||
assert_or_exit(status == 200 and isinstance(imported.get("version"), int), f"导入失败 status={status} body={imported}")
|
||||
print(f"[11/12] import_excel_ok version={imported['version']}")
|
||||
|
||||
status, _ = request_json(f"/api/v1/studies/{study_id}/lock", token=token, method="PATCH", payload={})
|
||||
assert_or_exit(status == 200, f"锁定失败 status={status}")
|
||||
try:
|
||||
@@ -465,10 +383,10 @@ def main() -> int:
|
||||
f"/api/v1/studies/{study_id}/setup-config",
|
||||
token=token,
|
||||
method="PUT",
|
||||
payload={"expected_version": imported["version"], "data": imported["data"]},
|
||||
payload={"expected_version": rolled["version"], "data": rolled["data"]},
|
||||
)
|
||||
assert_or_exit(status == 403, f"锁定后写入应403,实际 status={status} body={locked_result}")
|
||||
print("[12/12] lock_403_check_ok")
|
||||
print("[10/10] lock_403_check_ok")
|
||||
finally:
|
||||
unlock_status, unlock_body = request_json(f"/api/v1/studies/{study_id}/unlock", token=token, method="PATCH", payload={})
|
||||
assert_or_exit(unlock_status == 200, f"解锁失败 status={unlock_status} body={unlock_body}")
|
||||
|
||||
Reference in New Issue
Block a user