| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- """A job cancelled while it is being sent stays cancelled when the send then fails."""
- from __future__ import annotations
- from unittest.mock import AsyncMock, patch
- import pytest
- from sqlalchemy import update
- from backend.app.models.print_queue import PrintQueueItem
- from backend.tests.unit.test_scheduler_busy_reasons_3018 import _scheduler, one_printer # noqa: F401
- pytestmark = pytest.mark.asyncio
- async def test_a_cancel_during_the_upload_is_not_turned_into_a_failure(one_printer): # noqa: F811
- item_id = await one_printer.add_item()
- async def upload_then_cancelled(*args, **kwargs):
- # The user cancels while the file is on its way; then the upload fails.
- async with one_printer.session_maker() as other:
- await other.execute(update(PrintQueueItem).where(PrintQueueItem.id == item_id).values(status="cancelled"))
- await other.commit()
- return False
- failed = AsyncMock()
- toast = AsyncMock()
- async with _scheduler(one_printer, idle=True) as scheduler:
- with (
- patch("backend.app.services.print_scheduler.upload_file_async", upload_then_cancelled),
- patch("backend.app.services.notification_service.notification_service.on_queue_job_failed", failed),
- patch("backend.app.services.print_scheduler.ws_manager.send_queue_item_failed", toast),
- ):
- await scheduler.check_queue()
- for task, _pid in list(scheduler._inflight.values()):
- await task
- async with one_printer.session_maker() as db:
- item = await db.get(PrintQueueItem, item_id)
- assert item.status == "cancelled"
- failed.assert_not_awaited()
- # The dispatch toast is closed, not left spinning.
- assert toast.await_args.kwargs["reason"] == "cancelled_mid_dispatch"
- async def test_a_failed_upload_still_fails_the_job(one_printer): # noqa: F811
- item_id = await one_printer.add_item()
- async with _scheduler(one_printer, idle=True) as scheduler:
- with patch("backend.app.services.print_scheduler.upload_file_async", AsyncMock(return_value=False)):
- await scheduler.check_queue()
- for task, _pid in list(scheduler._inflight.values()):
- await task
- async with one_printer.session_maker() as db:
- item = await db.get(PrintQueueItem, item_id)
- assert item.status == "failed"
- async def test_a_stop_while_the_printer_turns_busy_is_not_undone(db_session, printer_factory):
- from backend.app.services.print_scheduler import PrintScheduler
- printer = await printer_factory()
- stopped = PrintQueueItem(printer_id=printer.id, status="cancelled", position=0)
- printing = PrintQueueItem(printer_id=printer.id, status="printing", position=1)
- db_session.add_all([stopped, printing])
- await db_session.commit()
- stopped_id, printing_id = stopped.id, printing.id
- for item_id in (stopped_id, printing_id):
- await PrintScheduler._defer_until_printer_idle(db_session, await db_session.get(PrintQueueItem, item_id))
- db_session.expire_all()
- assert (await db_session.get(PrintQueueItem, stopped_id)).status == "cancelled"
- assert (await db_session.get(PrintQueueItem, printing_id)).status == "pending"
|