172 lines
4.8 KiB
Python
172 lines
4.8 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestJobsAPI:
|
|
"""
|
|
Интеграционные тесты для API endpoints.
|
|
"""
|
|
|
|
async def test_trigger_job_creates_new_job(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
queue_name: str,
|
|
task_name: str,
|
|
):
|
|
"""
|
|
Тест создания новой задачи через API.
|
|
"""
|
|
payload = {
|
|
"queue": queue_name,
|
|
"task": task_name,
|
|
"args": {"test_key": "test_value"},
|
|
"lock_key": "lock_api_1",
|
|
"partition_key": "part1",
|
|
"priority": 100,
|
|
"max_attempts": 5,
|
|
"lease_ttl_sec": 60,
|
|
}
|
|
|
|
response = await client.post("/api/v1/jobs/trigger", json=payload)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "job_id" in data
|
|
assert data["status"] == "queued"
|
|
|
|
async def test_trigger_job_with_idempotency_key(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
queue_name: str,
|
|
task_name: str,
|
|
):
|
|
"""
|
|
Тест идемпотентности через idempotency_key.
|
|
"""
|
|
payload = {
|
|
"queue": queue_name,
|
|
"task": task_name,
|
|
"args": {},
|
|
"idempotency_key": "unique_key_123",
|
|
"lock_key": "lock_idem",
|
|
"priority": 100,
|
|
"max_attempts": 5,
|
|
"lease_ttl_sec": 60,
|
|
}
|
|
|
|
response1 = await client.post("/api/v1/jobs/trigger", json=payload)
|
|
response2 = await client.post("/api/v1/jobs/trigger", json=payload)
|
|
|
|
assert response1.status_code == 200
|
|
assert response2.status_code == 200
|
|
|
|
data1 = response1.json()
|
|
data2 = response2.json()
|
|
|
|
assert data1["job_id"] == data2["job_id"]
|
|
assert data1["status"] == data2["status"] == "queued"
|
|
|
|
async def test_get_status_returns_job_status(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
queue_name: str,
|
|
task_name: str,
|
|
):
|
|
"""
|
|
Тест получения статуса задачи через API.
|
|
"""
|
|
payload = {
|
|
"queue": queue_name,
|
|
"task": task_name,
|
|
"args": {},
|
|
"lock_key": "lock_status",
|
|
"priority": 100,
|
|
"max_attempts": 5,
|
|
"lease_ttl_sec": 60,
|
|
}
|
|
|
|
create_response = await client.post("/api/v1/jobs/trigger", json=payload)
|
|
job_id = create_response.json()["job_id"]
|
|
|
|
status_response = await client.get(f"/api/v1/jobs/{job_id}/status")
|
|
|
|
assert status_response.status_code == 200
|
|
data = status_response.json()
|
|
assert data["job_id"] == job_id
|
|
assert data["status"] == "queued"
|
|
assert data["attempt"] == 0
|
|
|
|
async def test_get_status_returns_404_for_nonexistent_job(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
):
|
|
"""
|
|
Тест получения статуса несуществующей задачи.
|
|
"""
|
|
fake_job_id = "00000000-0000-0000-0000-000000000000"
|
|
|
|
response = await client.get(f"/api/v1/jobs/{fake_job_id}/status")
|
|
|
|
assert response.status_code == 404
|
|
|
|
async def test_cancel_job_sets_cancel_flag(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
queue_name: str,
|
|
task_name: str,
|
|
):
|
|
"""
|
|
Тест отмены задачи через API.
|
|
"""
|
|
payload = {
|
|
"queue": queue_name,
|
|
"task": task_name,
|
|
"args": {},
|
|
"lock_key": "lock_cancel",
|
|
"priority": 100,
|
|
"max_attempts": 5,
|
|
"lease_ttl_sec": 60,
|
|
}
|
|
|
|
create_response = await client.post("/api/v1/jobs/trigger", json=payload)
|
|
job_id = create_response.json()["job_id"]
|
|
|
|
cancel_response = await client.post(f"/api/v1/jobs/{job_id}/cancel")
|
|
|
|
assert cancel_response.status_code == 200
|
|
data = cancel_response.json()
|
|
assert data["job_id"] == job_id
|
|
|
|
async def test_cancel_nonexistent_job_returns_404(
|
|
self,
|
|
client: AsyncClient,
|
|
clean_queue_tables,
|
|
):
|
|
"""
|
|
Тест отмены несуществующей задачи.
|
|
"""
|
|
fake_job_id = "00000000-0000-0000-0000-000000000000"
|
|
|
|
response = await client.post(f"/api/v1/jobs/{fake_job_id}/cancel")
|
|
|
|
assert response.status_code == 404
|
|
|
|
async def test_health_endpoint_returns_200(
|
|
self,
|
|
client: AsyncClient,
|
|
):
|
|
"""
|
|
Тест health check endpoint.
|
|
"""
|
|
response = await client.get("/health")
|
|
|
|
assert response.status_code == 200
|