test_bambu_mqtt_cfg_parse.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. """Tests for ``parse_ams_filament_backup_from_cfg`` (#1766 prefer_lowest gate).
  2. The function extracts bit 18 of Bambu's top-level ``print.cfg`` hex string,
  3. which OrcaSlicer's DeviceManager.cpp:4961 maps to AMS Filament Backup. These
  4. tests pin the bit position + cover the absent / malformed cases A1-family
  5. printers and pre-init pushes produce.
  6. """
  7. import pytest
  8. from backend.app.services.bambu_mqtt import parse_ams_filament_backup_from_cfg
  9. class TestParseAmsFilamentBackupFromCfg:
  10. def test_h2d_on_capture(self):
  11. # Captured 2026-06-20 from H2D fw 01.03.00.00 with backup ON.
  12. # Hex "C0340FC219" has bit 18 set (nibble 5 = F = 0b1111).
  13. assert parse_ams_filament_backup_from_cfg("C0340FC219") is True
  14. def test_h2d_off_capture(self):
  15. # Same printer, backup toggled OFF — only bit 18 flips:
  16. # "C0340BC219" — nibble 5 = B = 0b1011.
  17. assert parse_ams_filament_backup_from_cfg("C0340BC219") is False
  18. def test_x1c_short_hex_string_on(self):
  19. # X1C cfg in the investigation snapshots is short ("FCA09").
  20. # Bit 18 of 0xFCA09 = 0b1111110010100001001, bit18 set.
  21. assert parse_ams_filament_backup_from_cfg("FCA09") is True
  22. def test_lowercase_hex(self):
  23. # Robustness: int(s, 16) accepts both cases; check we don't regress.
  24. assert parse_ams_filament_backup_from_cfg("c0340fc219") is True
  25. def test_only_bit_18_isolated(self):
  26. # Sanity: a value with ONLY bit 18 set must parse as True.
  27. assert parse_ams_filament_backup_from_cfg(hex(1 << 18)[2:]) is True
  28. def test_bit_18_clear_but_others_set(self):
  29. # Set every bit EXCEPT 18 — must parse as False.
  30. mask = (~(1 << 18)) & 0xFFFFFFFF
  31. assert parse_ams_filament_backup_from_cfg(hex(mask)[2:]) is False
  32. @pytest.mark.parametrize(
  33. "value",
  34. [
  35. None, # field omitted (A1 family old protocol)
  36. "", # empty string
  37. 123, # firmware-emitted int instead of hex string (defensive)
  38. "not_hex", # malformed
  39. "0xZZ", # invalid hex
  40. ["FCA09"], # wrong shape
  41. {"cfg": "FCA09"}, # nested by mistake
  42. ],
  43. )
  44. def test_invalid_returns_none(self, value):
  45. # None preserves today's behaviour for callers gating on backup state —
  46. # NOT False. Treating absent as OFF would regress A1-family scheduling.
  47. assert parse_ams_filament_backup_from_cfg(value) is None