test_archive_run_finishing.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. """An archive stays marked while its last run's timelapse work goes on.
  2. The timelapse scan and the layer timelapse stitch run after the print
  3. completed and tell their run from a later one by the archive's start time. A
  4. queue dispatch of the same file adds its run to the archive only once that
  5. work is over (``_claim_reusable_archive``), or the work would stop short and
  6. the video never be attached.
  7. """
  8. import asyncio
  9. from unittest.mock import patch
  10. import pytest
  11. from backend.app import main as main_module
  12. from backend.tests.unit.test_run_estimate_plate import _complete
  13. @pytest.fixture(autouse=True)
  14. def _clean_state():
  15. main_module._archive_runs_finishing.clear()
  16. main_module._active_prints.clear()
  17. main_module._print_plate_ids.clear()
  18. yield
  19. main_module._archive_runs_finishing.clear()
  20. main_module._active_prints.clear()
  21. main_module._print_plate_ids.clear()
  22. @pytest.mark.asyncio
  23. async def test_marked_from_the_spawn_until_the_work_ends():
  24. release = asyncio.Event()
  25. async def work():
  26. await release.wait()
  27. wrapped = main_module._mark_run_finishing(7, work())
  28. assert main_module._archive_runs_finishing == {7: 1}
  29. second = main_module._mark_run_finishing(7, asyncio.sleep(0))
  30. await second
  31. assert main_module._archive_runs_finishing == {7: 1}, "the other task is still running"
  32. task = asyncio.create_task(wrapped)
  33. release.set()
  34. await task
  35. assert main_module._archive_runs_finishing == {}
  36. @pytest.mark.asyncio
  37. async def test_a_failing_task_unmarks_too():
  38. async def work():
  39. raise RuntimeError("scan failed")
  40. with pytest.raises(RuntimeError):
  41. await main_module._mark_run_finishing(7, work())
  42. assert main_module._archive_runs_finishing == {}
  43. def test_the_timelapse_scan_marks_its_archive():
  44. spawned = []
  45. with patch("backend.app.main.spawn_background_task", side_effect=lambda coro, name: spawned.append(coro)):
  46. main_module._schedule_timelapse_scan(12, 3, plate_id=None)
  47. assert main_module._archive_runs_finishing == {12: 1}
  48. for coro in spawned:
  49. coro.close()
  50. @pytest.mark.asyncio
  51. async def test_the_layer_timelapse_of_a_completed_print_marks_its_archive(
  52. test_engine, db_session, printer_factory, archive_factory
  53. ):
  54. printer = await printer_factory()
  55. archive = await archive_factory(printer.id, filename="multi.gcode.3mf", status="printing", with_run=False)
  56. main_module._active_prints[(printer.id, "multi.gcode.3mf")] = archive.id
  57. spawned: list[str] = []
  58. real_spawn = main_module.spawn_background_task
  59. def spawn(coro, name=None, **kwargs):
  60. if name == "background-layer-timelapse":
  61. spawned.append(main_module._archive_runs_finishing.get(archive.id, 0))
  62. return real_spawn(coro, name=name, **kwargs)
  63. with patch("backend.app.main.spawn_background_task", side_effect=spawn):
  64. await _complete(test_engine, printer.id)
  65. assert spawned == [1]