test_sn_request.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import os
  2. import sys
  3. import unittest
  4. from pathlib import Path
  5. from unittest.mock import patch
  6. os.environ.setdefault('QT_QPA_PLATFORM', 'offscreen')
  7. sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
  8. from PyQt6.QtWidgets import QApplication
  9. from app import Link, Monitor
  10. from generated import vkfly
  11. app = QApplication.instance() or QApplication([])
  12. class FakeLink:
  13. def __init__(self):
  14. self.requests = []
  15. def request_sn(self, target_system):
  16. self.requests.append(target_system)
  17. def stop(self):
  18. pass
  19. class SnRequestTest(unittest.TestCase):
  20. def setUp(self):
  21. self.monitor = Monitor()
  22. self.link = FakeLink()
  23. self.monitor.link = self.link
  24. self.writer = vkfly.MAVLink(None, srcSystem=42, srcComponent=1)
  25. def tearDown(self):
  26. self.monitor.close()
  27. def decode(self, message, writer):
  28. reader = vkfly.MAVLink(None)
  29. decoded = None
  30. for byte in message.pack(writer):
  31. result = reader.parse_char(bytes([byte]))
  32. if result is not None:
  33. decoded = result
  34. self.assertIsNotNone(decoded)
  35. return decoded
  36. def test_auto_request_once_and_manual_retry(self):
  37. heartbeat = self.decode(self.writer.heartbeat_encode(2, 3, 0, 0, 4, 3), self.writer)
  38. self.monitor.receive(heartbeat)
  39. self.monitor.receive(heartbeat)
  40. self.assertEqual(self.link.requests, [42])
  41. self.assertTrue(self.monitor.sn_button.isEnabled())
  42. self.monitor.sn_button.click()
  43. self.assertEqual(self.link.requests, [42, 42])
  44. self.assertEqual(self.monitor.labels['sn'].text(), '已请求,等待飞控回复')
  45. def test_ignores_non_autopilot_heartbeat(self):
  46. other = vkfly.MAVLink(None, srcSystem=99, srcComponent=1)
  47. self.monitor.receive(self.decode(other.heartbeat_encode(6, vkfly.MAV_AUTOPILOT_INVALID, 0, 0, 0, 3), other))
  48. self.assertEqual(self.link.requests, [])
  49. self.assertFalse(self.monitor.sn_button.isEnabled())
  50. def test_displays_flight_controller_sn_not_other_component(self):
  51. self.monitor.receive(self.decode(self.writer.heartbeat_encode(2, 3, 0, 0, 4, 3), self.writer))
  52. zeros = [0] * 16
  53. sn = list(b'VK123') + [0] * 11
  54. msg = self.writer.vk_comp_version_encode(1, zeros, zeros, sn, zeros, zeros, zeros)
  55. reader = vkfly.MAVLink(None)
  56. decoded = None
  57. for byte in msg.pack(self.writer):
  58. result = reader.parse_char(bytes([byte]))
  59. if result is not None:
  60. decoded = result
  61. self.monitor.receive(decoded)
  62. self.assertEqual(self.monitor.labels['sn'].text(), 'VK123')
  63. other = self.writer.vk_comp_version_encode(3, zeros, zeros, zeros, zeros, zeros, zeros)
  64. self.monitor.receive(other)
  65. self.assertEqual(self.monitor.labels['sn'].text(), 'VK123')
  66. def test_serial_writes_only_sn_request(self):
  67. link = Link('fake', 115200)
  68. link.request_sn(42)
  69. writes = []
  70. class FakeSerial:
  71. in_waiting = 0
  72. def __init__(self, *args, **kwargs):
  73. pass
  74. def __enter__(self):
  75. return self
  76. def __exit__(self, *args):
  77. pass
  78. def write(self, data):
  79. writes.append(bytes(data))
  80. return len(data)
  81. def read(self, size):
  82. link.running = False
  83. return b''
  84. with patch('app.serial.Serial', FakeSerial):
  85. link.run()
  86. self.assertEqual(len(writes), 1)
  87. reader = vkfly.MAVLink(None)
  88. msg = None
  89. for byte in writes[0]:
  90. result = reader.parse_char(bytes([byte]))
  91. if result is not None:
  92. msg = result
  93. self.assertEqual(msg.get_type(), 'COMMAND_LONG')
  94. self.assertEqual((msg.target_system, msg.target_component), (42, 1))
  95. self.assertEqual(msg.command, vkfly.MAV_CMD_REQUEST_MESSAGE)
  96. self.assertEqual((msg.param1, msg.param2), (vkfly.MAVLINK_MSG_ID_VK_COMP_VERSION, 1))
  97. self.assertEqual((msg.param3, msg.param4, msg.param5, msg.param6, msg.param7), (0, 0, 0, 0, 0))
  98. if __name__ == '__main__':
  99. unittest.main()