|
1 | 1 | import unittest |
2 | 2 | from unittest import IsolatedAsyncioTestCase |
3 | | -from unittest.mock import MagicMock, patch |
| 3 | +from unittest.mock import AsyncMock, MagicMock, patch |
4 | 4 |
|
5 | | -from custom_components.solis_modbus.client_manager import ModbusClientManager |
| 5 | +from custom_components.solis_modbus.client_manager import MIN_INTER_FRAME_MS, ModbusClientManager |
6 | 6 |
|
7 | 7 |
|
8 | 8 | class TestModbusClientManager(unittest.TestCase): |
@@ -91,6 +91,27 @@ async def test_inter_frame_wait_updates_shared_timestamp(self, mock_client_cls): |
91 | 91 | await self.manager.inter_frame_wait("1.2.3.4:502", is_write=False) |
92 | 92 | self.assertGreater(self.manager.get_last_modbus_request("1.2.3.4:502"), 0.0) |
93 | 93 |
|
| 94 | + @patch("custom_components.solis_modbus.client_manager.AsyncModbusTcpClient") |
| 95 | + @patch("custom_components.solis_modbus.client_manager.time.perf_counter") |
| 96 | + @patch("custom_components.solis_modbus.client_manager.asyncio.sleep", new_callable=AsyncMock) |
| 97 | + async def test_inter_frame_wait_enforces_min_interval_for_reads_and_writes(self, mock_sleep, mock_perf_counter, mock_client_cls): |
| 98 | + mock_client_cls.return_value = MagicMock() |
| 99 | + # Two operations back-to-back on the same connection: each should independently |
| 100 | + # compute a wait based on MIN_INTER_FRAME_MS, regardless of is_write. |
| 101 | + # Call sequence: [read: current_time, read: recorded last] [write: current_time, write: recorded last] |
| 102 | + mock_perf_counter.side_effect = [0.0, 0.31, 0.32, 0.62] |
| 103 | + self.manager.get_tcp_client("1.2.3.4", 502) |
| 104 | + |
| 105 | + await self.manager.inter_frame_wait("1.2.3.4:502", is_write=False) |
| 106 | + await self.manager.inter_frame_wait("1.2.3.4:502", is_write=True) |
| 107 | + |
| 108 | + expected_delay_s = MIN_INTER_FRAME_MS / 1000 |
| 109 | + self.assertEqual(2, mock_sleep.call_count) |
| 110 | + # Read: 0.0 elapsed since last (0.0) -> full MIN_INTER_FRAME_MS wait. |
| 111 | + self.assertAlmostEqual(expected_delay_s, mock_sleep.call_args_list[0].args[0]) |
| 112 | + # Write: 10ms elapsed since last (0.31) -> remaining wait is MIN_INTER_FRAME_MS - 10ms. |
| 113 | + self.assertAlmostEqual(expected_delay_s - 0.01, mock_sleep.call_args_list[1].args[0]) |
| 114 | + |
94 | 115 |
|
95 | 116 | if __name__ == "__main__": |
96 | 117 | unittest.main() |
0 commit comments