1
0

test_transmit.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import logging
  2. import unittest.mock
  3. import pytest
  4. import cc1101.options
  5. # pylint: disable=protected-access
  6. def test_transmit_empty_payload(transceiver):
  7. with unittest.mock.patch.object(
  8. transceiver,
  9. "get_packet_length_mode",
  10. return_value=cc1101.options.PacketLengthMode.VARIABLE,
  11. ), unittest.mock.patch.object(
  12. transceiver, "get_packet_length_bytes", return_value=21
  13. ):
  14. with pytest.raises(ValueError, match=r"\bempty\b"):
  15. transceiver.transmit([])
  16. @pytest.mark.parametrize(
  17. ("max_packet_length", "payload"),
  18. ((3, "\x04\x01\x02\x03"), (4, [7, 21, 42, 0, 0, 1, 2, 3])),
  19. )
  20. def test_transmit_exceeding_max_length(transceiver, max_packet_length, payload):
  21. with unittest.mock.patch.object(
  22. transceiver,
  23. "get_packet_length_mode",
  24. return_value=cc1101.options.PacketLengthMode.VARIABLE,
  25. ), unittest.mock.patch.object(
  26. transceiver, "get_packet_length_bytes", return_value=max_packet_length
  27. ):
  28. with pytest.raises(
  29. ValueError, match=r"\bpayload exceeds maximum payload length\b"
  30. ):
  31. transceiver.transmit(payload)
  32. @pytest.mark.parametrize(
  33. ("packet_length", "payload"),
  34. ((3, "\x04\x01\x02\x03"), (4, [7, 21, 42, 0, 0, 1, 2, 3])),
  35. )
  36. def test_transmit_unexpected_payload_len(transceiver, packet_length, payload):
  37. with unittest.mock.patch.object(
  38. transceiver,
  39. "get_packet_length_mode",
  40. return_value=cc1101.options.PacketLengthMode.FIXED,
  41. ), unittest.mock.patch.object(
  42. transceiver, "get_packet_length_bytes", return_value=packet_length
  43. ):
  44. with pytest.raises(ValueError, match=r"\bpayload length\b"):
  45. transceiver.transmit(payload)
  46. def test_transmit_not_idle(transceiver: cc1101.CC1101) -> None:
  47. with unittest.mock.patch.object(
  48. transceiver,
  49. "get_packet_length_mode",
  50. return_value=cc1101.options.PacketLengthMode.VARIABLE,
  51. ), unittest.mock.patch.object(
  52. transceiver, "get_packet_length_bytes", return_value=42 // 2
  53. ), unittest.mock.patch.object(
  54. transceiver,
  55. "get_main_radio_control_state_machine_state",
  56. return_value=cc1101.MainRadioControlStateMachineState.RX,
  57. ), pytest.raises(
  58. RuntimeError,
  59. match=r"^device must be idle before transmission \(current marcstate: RX\)$",
  60. ):
  61. transceiver.transmit(b"\x01\x02\x03")
  62. transceiver._spi.xfer.assert_not_called()
  63. @pytest.mark.parametrize("payload", (b"\0", b"\xaa\xbb\xcc", bytes(range(42))))
  64. def test_transmit_fixed(caplog, transceiver, payload):
  65. transceiver._spi.xfer.side_effect = lambda v: [15] * len(v)
  66. with unittest.mock.patch.object(
  67. transceiver,
  68. "get_packet_length_mode",
  69. return_value=cc1101.options.PacketLengthMode.FIXED,
  70. ), unittest.mock.patch.object(
  71. transceiver, "get_packet_length_bytes", return_value=len(payload)
  72. ), unittest.mock.patch.object(
  73. transceiver,
  74. "get_main_radio_control_state_machine_state",
  75. return_value=cc1101.MainRadioControlStateMachineState.IDLE,
  76. ), caplog.at_level(
  77. logging.INFO
  78. ):
  79. transceiver.transmit(payload)
  80. assert transceiver._spi.xfer.call_args_list == [
  81. unittest.mock.call([0x3B]), # flush
  82. unittest.mock.call([0x3F | 0x40] + list(payload)),
  83. unittest.mock.call([0x35]), # start transmission
  84. ]
  85. assert caplog.record_tuples == [
  86. (
  87. "cc1101",
  88. 20,
  89. "transmitting 0x{} ({!r})".format( # pylint: disable=consider-using-f-string
  90. "".join(f"{b:02x}" for b in payload), payload
  91. ),
  92. )
  93. ]
  94. @pytest.mark.parametrize(
  95. "payload", (b"\x01\0", b"\x03\xaa\xbb\xcc", b"\x10" + bytes(range(16)))
  96. )
  97. def test_transmit_variable(transceiver, payload):
  98. transceiver._spi.xfer.side_effect = lambda v: [15] * len(v)
  99. with unittest.mock.patch.object(
  100. transceiver,
  101. "get_packet_length_mode",
  102. return_value=cc1101.options.PacketLengthMode.VARIABLE,
  103. ), unittest.mock.patch.object(
  104. transceiver, "get_packet_length_bytes", return_value=255
  105. ), unittest.mock.patch.object(
  106. transceiver,
  107. "get_main_radio_control_state_machine_state",
  108. return_value=cc1101.MainRadioControlStateMachineState.IDLE,
  109. ):
  110. transceiver.transmit(payload)
  111. assert transceiver._spi.xfer.call_args_list == [
  112. unittest.mock.call([0x3B]), # flush
  113. unittest.mock.call([0x3F | 0x40] + [len(payload)] + list(payload)),
  114. unittest.mock.call([0x35]), # start transmission
  115. ]