test_resume_after_startup_pause_3485.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """A print paused when Bambuddy starts resumes as the same print (#3485).
  2. A power cut takes down the printers and the Bambuddy host together. Bambuddy
  3. comes back while the printers sit paused in power-loss recovery, so the first
  4. state it sees is PAUSE, and the printer's PAUSE -> RUNNING was taken for a new
  5. print: a second archive, left "printing". It is now the restart recovery that
  6. a print found RUNNING at startup already gets (#1304, #1485).
  7. """
  8. import pytest
  9. from backend.app.services.bambu_mqtt import BambuMQTTClient
  10. FILE = "chocolate-bite-buddy_plate_2.3mf"
  11. @pytest.fixture
  12. def client():
  13. client = BambuMQTTClient(ip_address="192.168.1.100", serial_number="TEST123", access_code="12345678")
  14. client.starts = []
  15. client.recovered = []
  16. client.completions = []
  17. client.on_print_start = client.starts.append
  18. client.on_print_running_observed = client.recovered.append
  19. client.on_print_complete = client.completions.append
  20. return client
  21. def _push(client, state: str, file: str | None = FILE) -> None:
  22. payload = {"gcode_state": state}
  23. if file is not None:
  24. payload.update(gcode_file=file, subtask_name=file)
  25. client._process_message({"print": payload})
  26. def test_the_resume_is_not_a_new_print(client):
  27. _push(client, "PAUSE")
  28. # The resume frame carries no file name, as on the reporter's A1 mini.
  29. _push(client, "RUNNING", file=None)
  30. assert client.starts == []
  31. assert len(client.recovered) == 1
  32. assert client.recovered[0]["filename"] == FILE
  33. def test_the_resumed_print_still_completes(client):
  34. _push(client, "PAUSE")
  35. _push(client, "RUNNING", file=None)
  36. _push(client, "FINISH")
  37. assert [c["status"] for c in client.completions] == ["completed"]
  38. def test_a_later_pause_and_resume_is_still_the_same_print(client):
  39. _push(client, "PAUSE")
  40. _push(client, "RUNNING", file=None)
  41. _push(client, "PAUSE")
  42. _push(client, "RUNNING")
  43. assert client.starts == []
  44. def test_a_print_after_the_paused_one_ends_is_new(client):
  45. _push(client, "PAUSE")
  46. _push(client, "IDLE", file="")
  47. _push(client, "RUNNING", file="next.3mf")
  48. assert len(client.starts) == 1
  49. assert client.starts[0]["filename"] == "next.3mf"
  50. def test_a_next_print_paused_before_it_runs_is_still_new(client):
  51. _push(client, "PAUSE")
  52. _push(client, "IDLE", file="")
  53. _push(client, "PREPARE", file="next.3mf")
  54. _push(client, "PAUSE", file="next.3mf")
  55. _push(client, "RUNNING", file="next.3mf")
  56. assert [s["filename"] for s in client.starts] == ["next.3mf"]
  57. def test_a_print_started_after_startup_is_new(client):
  58. _push(client, "IDLE", file="")
  59. _push(client, "RUNNING")
  60. assert len(client.starts) == 1
  61. assert client.recovered == []
  62. def test_a_pause_seen_while_running_resumes_quietly(client):
  63. _push(client, "IDLE", file="")
  64. _push(client, "RUNNING")
  65. _push(client, "PAUSE")
  66. _push(client, "RUNNING")
  67. assert len(client.starts) == 1
  68. assert client.recovered == []