From efb7fa57294d2e2f4e77b839b6f8b3f7f7b63859 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Tue, 29 Sep 2026 11:17:23 +0000 Subject: [PATCH] style: auto-format with black + isort + ruff + prettier [skip ci-format-check] --- tests/unit/test_1677_batch_variants.py | 2 +- tests/unit/test_generation_preview.py | 3 +++ tests/unit/test_task_enqueue.py | 22 +++++++++++++++++++ tests/unit/test_task_queue_limit.py | 13 +++++++++++ ...test_worker_generate_video_task_binding.py | 13 ++++++----- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_1677_batch_variants.py b/tests/unit/test_1677_batch_variants.py index 0910a4507..c288a7ae6 100644 --- a/tests/unit/test_1677_batch_variants.py +++ b/tests/unit/test_1677_batch_variants.py @@ -9,7 +9,7 @@ """ from datetime import datetime, timezone -from unittest.mock import MagicMock, patch, patch +from unittest.mock import MagicMock, patch import pytest from app.core.task_enqueue import GlobalQueueFull, UserPendingLimitExceeded diff --git a/tests/unit/test_generation_preview.py b/tests/unit/test_generation_preview.py index 109b11ee0..3678e894b 100644 --- a/tests/unit/test_generation_preview.py +++ b/tests/unit/test_generation_preview.py @@ -744,6 +744,7 @@ class TestCreatePreviewRoute: def test_user_pending_limit_no_longer_rejects(self): """#2098: 用户待处理任务超限不再 429 拒绝(预检查仅全局 503)。""" from fastapi import HTTPException + repo = MagicMock() repo.count_pending_by_user.return_value = 100 repo.count_pending_total.return_value = 5 @@ -851,9 +852,11 @@ class TestCreatePreviewRoute: repo.count_pending_by_user.return_value = 0 repo.count_pending_total.return_value = 0 task = _make_task() + def _set_failed(reason="", **_kw): task.status = GenerationTaskStatus.FAILED task.error_message = reason + task.mark_failed.side_effect = _set_failed repo.create.return_value = task with patch( diff --git a/tests/unit/test_task_enqueue.py b/tests/unit/test_task_enqueue.py index b03fc3500..34c9bdf7c 100755 --- a/tests/unit/test_task_enqueue.py +++ b/tests/unit/test_task_enqueue.py @@ -14,18 +14,23 @@ from app.core.task_enqueue import ( safe_enqueue_generation_task, ) + class MockRepository: def __init__(self, global_count: int = 0, user_count: int = 0): self._global = global_count self._user = user_count self.update_called = 0 + def count_pending_total(self) -> int: return self._global + def count_pending_by_user(self, user_id: str) -> int: return self._user + def update(self, task): self.update_called += 1 + def make_mock_task(task_id: str = "task-1"): task = MagicMock() task.id = task_id @@ -33,35 +38,43 @@ def make_mock_task(task_id: str = "task-1"): task.mark_failed = MagicMock() return task + class TestCheckQueueLimits: def test_below_limits_passes(self): repo = MockRepository(global_count=5, user_count=1) check_queue_limits("user-1", repo) + def test_global_at_limit_raises(self): repo = MockRepository(global_count=GLOBAL_PENDING_LIMIT, user_count=1) with pytest.raises(GlobalQueueFull) as exc_info: check_queue_limits("user-1", repo) assert exc_info.value.pending_count == GLOBAL_PENDING_LIMIT assert exc_info.value.limit == GLOBAL_PENDING_LIMIT + def test_global_over_limit_raises(self): repo = MockRepository(global_count=GLOBAL_PENDING_LIMIT + 1, user_count=1) with pytest.raises(GlobalQueueFull): check_queue_limits("user-1", repo) + def test_user_at_limit_no_longer_raises(self): repo = MockRepository(global_count=5, user_count=USER_PENDING_LIMIT) check_queue_limits("user-1", repo) + def test_user_over_limit_no_longer_raises(self): repo = MockRepository(global_count=5, user_count=USER_PENDING_LIMIT + 100) check_queue_limits("user-1", repo) + def test_empty_user_id_skips_user_check(self): repo = MockRepository(global_count=5, user_count=999) check_queue_limits("", repo) + def test_custom_global_limit_still_honored(self): repo = MockRepository(global_count=15, user_count=999) with pytest.raises(GlobalQueueFull): check_queue_limits("u1", repo, user_pending_limit=999, global_pending_limit=10) check_queue_limits("u1", repo, user_pending_limit=999, global_pending_limit=20) + class TestSafeEnqueueGenerationTask: @patch("app.core.task_enqueue.celery_app") def test_success_path(self, mock_celery): @@ -92,6 +105,7 @@ class TestSafeEnqueueGenerationTask: @patch("app.core.task_enqueue.celery_app") def test_precheck_user_over_still_enqueues(self, mock_celery, caplog): import logging + caplog.set_level(logging.WARNING) repo = MockRepository(global_count=5, user_count=USER_PENDING_LIMIT + 100) task = make_mock_task() @@ -123,11 +137,13 @@ class TestSafeEnqueueGenerationTask: @patch("app.core.task_enqueue.celery_app") def test_postcheck_global_over_rollback(self, mock_celery): call_count = [0] + def count_pending_total_side_effect(): call_count[0] += 1 if call_count[0] == 1: return GLOBAL_PENDING_LIMIT return GLOBAL_PENDING_LIMIT + 1 + repo = MockRepository(global_count=GLOBAL_PENDING_LIMIT, user_count=0) repo.count_pending_total = MagicMock(side_effect=count_pending_total_side_effect) task = make_mock_task() @@ -140,14 +156,17 @@ class TestSafeEnqueueGenerationTask: @patch("app.core.task_enqueue.celery_app") def test_postcheck_user_over_does_not_rollback(self, mock_celery, caplog): import logging + caplog.set_level(logging.WARNING) repo = MockRepository(global_count=5, user_count=USER_PENDING_LIMIT) call_count = [0] + def count_by_user_side_effect(user_id): call_count[0] += 1 if call_count[0] <= 1: return USER_PENDING_LIMIT return USER_PENDING_LIMIT + 1 + repo.count_pending_by_user = MagicMock(side_effect=count_by_user_side_effect) task = make_mock_task() result = safe_enqueue_generation_task(task, repo, user_id="user-1") @@ -174,15 +193,18 @@ class TestSafeEnqueueGenerationTask: with pytest.raises(GlobalQueueFull): safe_enqueue_generation_task(task2, repo, user_id="user-1", user_pending_limit=999, global_pending_limit=10) + class TestExceptionClasses: def test_user_pending_limit_message(self): exc = UserPendingLimitExceeded("u1", 5, 3) assert "u1" in str(exc) assert "5" in str(exc) assert "3" in str(exc) + def test_global_queue_full_message(self): exc = GlobalQueueFull(25, 20) assert "25" in str(exc) assert "20" in str(exc) + def test_user_pending_limit_constant(self): assert USER_PENDING_LIMIT == 20 diff --git a/tests/unit/test_task_queue_limit.py b/tests/unit/test_task_queue_limit.py index 2611e749a..8e9dc4eb3 100644 --- a/tests/unit/test_task_queue_limit.py +++ b/tests/unit/test_task_queue_limit.py @@ -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 diff --git a/tests/unit/test_worker_generate_video_task_binding.py b/tests/unit/test_worker_generate_video_task_binding.py index 0018c8bc6..e3f57a4ec 100644 --- a/tests/unit/test_worker_generate_video_task_binding.py +++ b/tests/unit/test_worker_generate_video_task_binding.py @@ -74,11 +74,14 @@ def test_build_task_config_override_is_plain_function(): assert not hasattr(fn, "run"), f"{fn.__name__} must be a plain function, not a Celery task" # Bug A: override 对 title_config 做 key 归一化 (font_size→size, font_color→color) - override = _build_task_config_override({ - "title_config": {"font_size": 48, "font_color": "#ff0000", "text": "hi"}, - "bgm_config": {"url": "http://x/bgm.mp3"}, - "output_width": 1080, "output_height": 1920, - }) + override = _build_task_config_override( + { + "title_config": {"font_size": 48, "font_color": "#ff0000", "text": "hi"}, + "bgm_config": {"url": "http://x/bgm.mp3"}, + "output_width": 1080, + "output_height": 1920, + } + ) assert override["title"]["size"] == 48 assert override["title"]["color"] == "#ff0000" assert override["bgm"]["url"] == "http://x/bgm.mp3"