test_scheduler_check_queue_holds.py 4.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """What check_queue holds back, run on a real database with the dispatch drained.
  2. * An item whose creator may no longer use its printer (#1727) is held with a
  3. reason, not dispatched and not failed.
  4. * A printer that already has an item printing takes no second one, even while
  5. it reports IDLE (the phantom-print seed).
  6. """
  7. import pytest
  8. from sqlalchemy import insert, update
  9. from backend.app.models.group import Group, group_printers
  10. from backend.app.models.print_queue import PrintQueueItem
  11. from backend.app.models.printer import Printer
  12. from backend.app.models.settings import Settings
  13. from backend.app.models.user import User
  14. from backend.tests.unit.test_scheduler_busy_reasons_3018 import _scheduler, one_printer # noqa: F401
  15. async def _restricted_creator(session_maker, allowed_printer_id: int) -> int:
  16. async with session_maker() as db:
  17. db.add(Settings(key="auth_enabled", value="true"))
  18. group = Group(name="team", permissions=["queue:create"], restrict_printers=True)
  19. user = User(username="member", password_hash="x", is_active=True, groups=[group])
  20. db.add_all([group, user])
  21. await db.flush()
  22. await db.execute(insert(group_printers).values(group_id=group.id, printer_id=allowed_printer_id))
  23. await db.commit()
  24. return user.id
  25. async def _other_printer(session_maker) -> int:
  26. async with session_maker() as db:
  27. printer = Printer(name="Other", serial_number="OTHER", ip_address="10.0.0.2", access_code="code", model="X1C")
  28. db.add(printer)
  29. await db.commit()
  30. return printer.id
  31. class TestACreatorWhoLostThePrinter:
  32. @pytest.mark.asyncio
  33. async def test_the_item_is_held_with_a_reason(self, one_printer): # noqa: F811
  34. allowed = await _other_printer(one_printer.session_maker)
  35. creator = await _restricted_creator(one_printer.session_maker, allowed)
  36. item_id = await one_printer.add_item()
  37. async with one_printer.session_maker() as db:
  38. await db.execute(update(PrintQueueItem).where(PrintQueueItem.id == item_id).values(created_by_id=creator))
  39. await db.commit()
  40. async with _scheduler(one_printer, idle=True) as scheduler:
  41. await scheduler.check_queue()
  42. assert not scheduler._inflight
  43. async with one_printer.session_maker() as db:
  44. item = await db.get(PrintQueueItem, item_id)
  45. assert item.status == "pending"
  46. assert "no longer has access" in (item.waiting_reason or "")
  47. @pytest.mark.asyncio
  48. async def test_a_creator_who_still_has_it_is_dispatched(self, one_printer): # noqa: F811
  49. creator = await _restricted_creator(one_printer.session_maker, one_printer.printer_id)
  50. item_id = await one_printer.add_item()
  51. async with one_printer.session_maker() as db:
  52. await db.execute(update(PrintQueueItem).where(PrintQueueItem.id == item_id).values(created_by_id=creator))
  53. await db.commit()
  54. async with _scheduler(one_printer, idle=True) as scheduler:
  55. await scheduler.check_queue()
  56. async with one_printer.session_maker() as db:
  57. assert (await db.get(PrintQueueItem, item_id)).status != "pending"
  58. class TestAPrinterWithAnItemPrinting:
  59. @pytest.mark.asyncio
  60. async def test_takes_no_second_item_while_it_reports_idle(self, one_printer): # noqa: F811
  61. printing_id = await one_printer.add_item(status="printing", position=0)
  62. pending_id = await one_printer.add_item(position=1)
  63. async with _scheduler(one_printer, idle=True) as scheduler:
  64. await scheduler.check_queue()
  65. assert not scheduler._inflight
  66. async with one_printer.session_maker() as db:
  67. assert (await db.get(PrintQueueItem, printing_id)).status == "printing"
  68. assert (await db.get(PrintQueueItem, pending_id)).status == "pending"
  69. @pytest.mark.asyncio
  70. async def test_without_it_the_same_item_goes_out(self, one_printer): # noqa: F811
  71. """The control: nothing else holds this item back."""
  72. pending_id = await one_printer.add_item(position=1)
  73. async with _scheduler(one_printer, idle=True) as scheduler:
  74. await scheduler.check_queue()
  75. async with one_printer.session_maker() as db:
  76. assert (await db.get(PrintQueueItem, pending_id)).status != "pending"