"""Тесты хранилища задач: переживает перезапуск, не теряет статусы.""" import pytest from app.store import JobStore, JobStatus @pytest.fixture def store(tmp_path): return JobStore(tmp_path / "jobs.db") class TestJobLifecycle: def test_new_job_is_queued(self, store): job_id = store.create(filename="call.wav", duration_sec=120.0) job = store.get(job_id) assert job["status"] == JobStatus.QUEUED assert job["filename"] == "call.wav" def test_job_id_is_unique(self, store): ids = {store.create(filename=f"{i}.wav", duration_sec=1.0) for i in range(20)} assert len(ids) == 20 def test_mark_running_then_done(self, store): job_id = store.create(filename="a.wav", duration_sec=10.0) store.mark_running(job_id) assert store.get(job_id)["status"] == JobStatus.RUNNING store.mark_done(job_id, result={"turns": []}) job = store.get(job_id) assert job["status"] == JobStatus.DONE assert job["result"] == {"turns": []} def test_mark_failed_keeps_error(self, store): job_id = store.create(filename="a.wav", duration_sec=10.0) store.mark_failed(job_id, error="сломалось") job = store.get(job_id) assert job["status"] == JobStatus.FAILED assert job["error"] == "сломалось" def test_unknown_job_returns_none(self, store): assert store.get("нет-такого") is None def test_survives_reopen(self, tmp_path): """Задачи должны переживать перезапуск сервиса.""" path = tmp_path / "jobs.db" first = JobStore(path) job_id = first.create(filename="a.wav", duration_sec=5.0) first.mark_done(job_id, result={"ok": True}) second = JobStore(path) assert second.get(job_id)["result"] == {"ok": True} class TestQueue: def test_claim_returns_oldest_queued(self, store): first = store.create(filename="1.wav", duration_sec=1.0) store.create(filename="2.wav", duration_sec=1.0) assert store.claim_next() == first def test_claim_skips_running(self, store): job_id = store.create(filename="1.wav", duration_sec=1.0) store.mark_running(job_id) assert store.claim_next() is None def test_claim_on_empty_queue(self, store): assert store.claim_next() is None def test_queue_position_counts_only_waiting(self, store): a = store.create(filename="1.wav", duration_sec=1.0) b = store.create(filename="2.wav", duration_sec=1.0) store.mark_running(a) assert store.queue_position(b) == 1 class TestCleanup: def test_removes_old_finished_jobs(self, store): job_id = store.create(filename="a.wav", duration_sec=1.0) store.mark_done(job_id, result={}) removed = store.cleanup(max_age_hours=0) assert removed == 1 assert store.get(job_id) is None def test_keeps_running_jobs_regardless_of_age(self, store): job_id = store.create(filename="a.wav", duration_sec=1.0) store.mark_running(job_id) assert store.cleanup(max_age_hours=0) == 0 assert store.get(job_id) is not None