116 lines
3.9 KiB
Python
Executable File
116 lines
3.9 KiB
Python
Executable File
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
import json
|
|
|
|
|
|
def test_reference_bundle_running_task_remains_running_after_elapsed_time(tmp_path, monkeypatch):
|
|
from apps.web.vue3 import main
|
|
|
|
monkeypatch.setattr(main, "WORKSPACE_ROOT", tmp_path / "workspace")
|
|
task = {
|
|
"id": "task_ref_timeout",
|
|
"task_id": "task_ref_timeout",
|
|
"stage": "reference_bundle_download",
|
|
"job_id": "job_ref_timeout",
|
|
"status": "running",
|
|
"message": "正在后台下载参考物种注释包",
|
|
"created_at": (datetime.now() - timedelta(seconds=500)).isoformat(),
|
|
"start_time": (datetime.now() - timedelta(seconds=500)).isoformat(),
|
|
"timeout_sec": 300,
|
|
"payload": {"job_id": "job_ref_timeout", "timeout_sec": 300},
|
|
}
|
|
|
|
main._apply_reference_bundle_stale_watchdog(task)
|
|
|
|
assert task["status"] == "running"
|
|
assert task["pending_seconds"] >= 500
|
|
assert task["progress"]["phase"] == "running"
|
|
assert task["progress"]["indeterminate"] is True
|
|
assert "action_required" not in task
|
|
assert "retryable" not in task
|
|
assert "result" not in task
|
|
status_path = (
|
|
tmp_path
|
|
/ "workspace"
|
|
/ "job_ref_timeout"
|
|
/ "final"
|
|
/ "reference_bundle_tasks"
|
|
/ "task_ref_timeout.json"
|
|
)
|
|
assert status_path.exists()
|
|
persisted = json.loads(status_path.read_text(encoding="utf-8"))
|
|
assert persisted["status"] == "running"
|
|
assert persisted["progress"]["phase"] == "running"
|
|
|
|
|
|
def test_reference_bundle_task_can_be_recovered_from_persisted_status(tmp_path, monkeypatch):
|
|
from apps.web.vue3 import main
|
|
|
|
monkeypatch.setattr(main, "WORKSPACE_ROOT", tmp_path / "workspace")
|
|
status_dir = tmp_path / "workspace" / "job_ref_recover" / "final" / "reference_bundle_tasks"
|
|
status_dir.mkdir(parents=True)
|
|
status_path = status_dir / "task_ref_recover.json"
|
|
status_path.write_text(
|
|
json.dumps(
|
|
{
|
|
"id": "task_ref_recover",
|
|
"task_id": "task_ref_recover",
|
|
"stage": "reference_bundle_download",
|
|
"job_id": "job_ref_recover",
|
|
"status": "failed",
|
|
"message": "download failed",
|
|
},
|
|
ensure_ascii=False,
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
recovered = main._load_reference_bundle_task("task_ref_recover")
|
|
|
|
assert recovered is not None
|
|
assert recovered["job_id"] == "job_ref_recover"
|
|
assert recovered["status"] == "failed"
|
|
|
|
|
|
def test_reference_bundle_task_uses_english_user_messages(tmp_path, monkeypatch):
|
|
from apps.web import pipeline_backend
|
|
from apps.web.vue3 import main
|
|
|
|
monkeypatch.setattr(main, "WORKSPACE_ROOT", tmp_path / "workspace")
|
|
monkeypatch.setattr(main, "INPUT_ROOT", tmp_path / "input")
|
|
job_id = "job_ref_english"
|
|
task_id = "task_ref_english"
|
|
(tmp_path / "workspace" / job_id).mkdir(parents=True)
|
|
(tmp_path / "input" / job_id).mkdir(parents=True)
|
|
main.tasks[task_id] = {
|
|
"id": task_id,
|
|
"task_id": task_id,
|
|
"stage": "reference_bundle_download",
|
|
"job_id": job_id,
|
|
"status": "pending",
|
|
}
|
|
monkeypatch.setattr(
|
|
pipeline_backend,
|
|
"download_reference_annotation_bundle",
|
|
lambda **_kwargs: {
|
|
"status": "success",
|
|
"requested_file_types": ["pep", "cds"],
|
|
"files": {"pep": "ref.pep.fasta", "cds": "ref.cds.fasta"},
|
|
},
|
|
)
|
|
|
|
main.run_reference_bundle_download_task(
|
|
task_id,
|
|
{
|
|
"job_id": job_id,
|
|
"species_code": "string_taxon_3562",
|
|
"requested_stages": ["ppi"],
|
|
"timeout_sec": 30,
|
|
},
|
|
)
|
|
|
|
task = main.tasks.pop(task_id)
|
|
assert task["message"] == "PPI and Ka/Ks reference species data are ready"
|
|
assert task["progress"]["message"] == "PPI and Ka/Ks reference species data are ready"
|