style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 47s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m28s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m54s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 7m6s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 8m43s
AI Code Review / AI Code Review (pull_request) Successful in 10m46s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m49s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 15m58s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 24m52s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 4m25s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 5m1s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 1h3m21s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped

This commit is contained in:
CI Bot
2026-09-29 11:17:23 +00:00
parent 5e1520230f
commit efb7fa5729
5 changed files with 47 additions and 6 deletions
+13
View File
@@ -26,13 +26,17 @@ class MockRepository:
self._global_pending = global_pending
self._send_task_called = False
self.updated_tasks = []
def count_pending_by_user(self, user_id: str) -> int:
return self._user_pending
def count_pending_total(self) -> int:
return self._global_pending
def update(self, task):
self.updated_tasks.append(task)
return task
def set_pending(self, *, user_pending: int | None = None, global_pending: int | None = None):
if user_pending is not None:
self._user_pending = user_pending
@@ -45,6 +49,7 @@ class MockTask:
self.id = task_id
self.status = status
self.error_message = ""
def mark_failed(self, reason: str):
self.status = "failed"
self.error_message = reason
@@ -120,6 +125,7 @@ class TestSafeEnqueueWithLimits:
def test_user_limit_exceeded_still_enqueues(self, mock_celery, caplog):
"""#2098: 用户远超软上限仍入队,任务不被标记 failed。"""
import logging
caplog.set_level(logging.WARNING)
repo = MockRepository(user_pending=100, global_pending=5)
task = MockTask("task-1")
@@ -179,8 +185,10 @@ class TestPostEnqueueFinalCheck:
def test_post_enqueue_global_overflow_rollback(self, mock_celery):
repo = MockRepository(user_pending=1, global_pending=20)
task = MockTask("task-1")
def side_effect(*args, **kwargs):
repo.set_pending(global_pending=21)
mock_celery.side_effect = side_effect
with pytest.raises(GlobalQueueFull) as exc_info:
safe_enqueue_generation_task(task, repo, user_id="user-1")
@@ -193,11 +201,14 @@ class TestPostEnqueueFinalCheck:
def test_post_enqueue_user_overflow_no_rollback(self, mock_celery, caplog):
"""#2098: 入队后用户超软上限仅 warning,不回滚。"""
import logging
caplog.set_level(logging.WARNING)
repo = MockRepository(user_pending=USER_PENDING_LIMIT, global_pending=5)
task = MockTask("task-1")
def side_effect(*args, **kwargs):
repo.set_pending(user_pending=USER_PENDING_LIMIT + 1)
mock_celery.side_effect = side_effect
result = safe_enqueue_generation_task(task, repo, user_id="user-1")
assert result is True
@@ -218,8 +229,10 @@ class TestPostEnqueueFinalCheck:
def test_post_enqueue_no_user_id_skips_user_check(self, mock_celery):
repo = MockRepository(user_pending=10, global_pending=5)
task = MockTask("task-1")
def side_effect(*args, **kwargs):
repo.set_pending(user_pending=15, global_pending=5)
mock_celery.side_effect = side_effect
result = safe_enqueue_generation_task(task, repo, user_id="")
assert result is True