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"