| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- """The late slicer update leaves a queue job the scheduler has claimed alone.
- The slicer's options can arrive up to 30 s after a virtual-printer job was
- queued. By then the scheduler may have claimed the job (``dispatching_at``
- set, status still "pending") and started its upload with the old mapping;
- rewriting the row then made it, and the spool charge read from it, disagree
- with what the printer printed.
- """
- import json
- from datetime import datetime
- from unittest.mock import MagicMock, patch
- import pytest
- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
- from backend.app.models.print_queue import PrintQueueItem
- from backend.app.services.virtual_printer.manager import VirtualPrinterInstance
- pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
- async def test_only_the_unclaimed_job_is_restamped(test_engine, db_session, printer_factory, tmp_path):
- printer = await printer_factory()
- claimed = PrintQueueItem(printer_id=printer.id, status="pending", position=1, dispatching_at=datetime.utcnow())
- waiting = PrintQueueItem(printer_id=printer.id, status="pending", position=2)
- db_session.add_all([claimed, waiting])
- await db_session.commit()
- inst = VirtualPrinterInstance(
- target_printer_id=printer.id,
- vp_id=97,
- name="LateMQTTClaimed",
- mode="queue",
- model="O1C2",
- access_code="12345678",
- serial_suffix="391800097",
- base_dir=tmp_path,
- session_factory=async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False),
- )
- inst._mqtt = MagicMock()
- inst._recent_queue_items["test.3mf"] = ([claimed.id, waiting.id], 1_000_000.0)
- with patch("backend.app.services.virtual_printer.manager.time.monotonic", return_value=1_000_001.0):
- await inst.on_print_command(
- "test.3mf", {"command": "project_file", "file": "test.3mf", "nozzle_mapping": [16, -1]}
- )
- await db_session.refresh(claimed)
- await db_session.refresh(waiting)
- assert claimed.nozzle_mapping is None
- assert json.loads(waiting.nozzle_mapping) == [16, -1]
- async def test_the_slicer_s_pick_is_still_kept_on_a_claimed_job_s_archive(
- test_engine, db_session, printer_factory, archive_factory, tmp_path
- ):
- """The archive copy only serves later reprints, so it does not race the
- upload: a claimed job's archive still gets the slicer's AMS pick."""
- printer = await printer_factory()
- archive = await archive_factory(printer.id)
- claimed = PrintQueueItem(
- printer_id=printer.id, archive_id=archive.id, status="pending", position=1, dispatching_at=datetime.utcnow()
- )
- db_session.add(claimed)
- await db_session.commit()
- inst = VirtualPrinterInstance(
- target_printer_id=printer.id,
- vp_id=96,
- name="LateMQTTArchive",
- mode="queue",
- model="O1C2",
- access_code="12345678",
- serial_suffix="391800096",
- base_dir=tmp_path,
- session_factory=async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False),
- )
- inst._mqtt = MagicMock()
- inst.save_ams_mapping = True
- inst._recent_queue_items["test.3mf"] = ([claimed.id], 1_000_000.0)
- with patch("backend.app.services.virtual_printer.manager.time.monotonic", return_value=1_000_001.0):
- await inst.on_print_command("test.3mf", {"command": "project_file", "file": "test.3mf", "ams_mapping": [2]})
- await db_session.refresh(archive)
- await db_session.refresh(claimed)
- assert (archive.extra_data or {}).get("slicer_ams_mapping", {}).get("mapping") == [2]
- assert claimed.ams_mapping is None
|