test_spoolman_tracking_shared_archive.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Spoolman tracking for an archive printing on several printers at once.
  2. A batch dispatches one archive as several queue items. The print-start
  3. capture looked the queue item up by archive alone and insisted on one row, so
  4. with two copies printing it raised and the print was never charged.
  5. """
  6. from types import SimpleNamespace
  7. from unittest.mock import AsyncMock, MagicMock, patch
  8. import pytest
  9. from backend.app.models.active_print_spoolman import ActivePrintSpoolman # registers its table
  10. from backend.app.models.print_queue import PrintQueueItem
  11. from backend.app.services.spoolman_tracking import store_print_data
  12. @pytest.mark.asyncio
  13. @pytest.mark.integration
  14. async def test_each_printer_reads_its_own_queue_item(db_session, printer_factory, archive_factory):
  15. from sqlalchemy import select
  16. printer_a = await printer_factory()
  17. printer_b = await printer_factory()
  18. archive = await archive_factory(printer_a.id, status="printing", with_run=False)
  19. db_session.add(PrintQueueItem(printer_id=printer_a.id, archive_id=archive.id, plate_id=2, status="printing"))
  20. db_session.add(PrintQueueItem(printer_id=printer_b.id, archive_id=archive.id, plate_id=3, status="printing"))
  21. await db_session.commit()
  22. plates: list = []
  23. printer_manager = MagicMock()
  24. printer_manager.get_status.return_value = SimpleNamespace(
  25. raw_data={"ams": [{"id": 0, "tray": [{"id": 0, "tray_type": "PLA"}]}]}
  26. )
  27. mock_settings = MagicMock()
  28. mock_path = MagicMock()
  29. mock_path.exists.return_value = True
  30. mock_settings.base_dir.__truediv__.return_value = mock_path
  31. def _usage(path, plate_id=None):
  32. plates.append(plate_id)
  33. return [{"slot_id": 1, "used_g": 5.0, "type": "PLA", "color": "#FF0000"}]
  34. with (
  35. patch("backend.app.services.spoolman_tracking.app_settings", mock_settings),
  36. patch("backend.app.api.routes.settings.get_setting", AsyncMock(return_value="true")),
  37. patch("backend.app.utils.threemf_tools.extract_filament_usage_from_3mf", side_effect=_usage),
  38. patch("backend.app.utils.threemf_tools.extract_layer_filament_usage_from_3mf", return_value=None),
  39. patch("backend.app.utils.threemf_tools.extract_filament_properties_from_3mf", return_value={}),
  40. ):
  41. await store_print_data(
  42. printer_id=printer_a.id,
  43. archive_id=archive.id,
  44. file_path="archives/test.3mf",
  45. db=db_session,
  46. printer_manager=printer_manager,
  47. ams_mapping=[0],
  48. )
  49. assert plates == [2]
  50. rows = (await db_session.execute(select(ActivePrintSpoolman))).scalars().all()
  51. assert [r.printer_id for r in rows] == [printer_a.id]