| | |
| | | package com.ruoyi.device.bts; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertThrows; |
| | | import static org.junit.jupiter.api.Assertions.assertTrue; |
| | | import java.time.Duration; |
| | | import java.util.Set; |
| | |
| | | { |
| | | simulator.enqueue("<bts><cmd>first_resp</cmd></bts>"); |
| | | simulator.enqueue("<bts><cmd>second_resp</cmd></bts>"); |
| | | Callable<String> first = () -> transport.exchange("<bts><cmd>first</cmd></bts>"); |
| | | Callable<String> first = () -> transport.exchange("<bts><cmd>first</cmd><note>检测</note></bts>"); |
| | | Callable<String> second = () -> transport.exchange("<bts><cmd>second</cmd></bts>"); |
| | | |
| | | Future<String> firstResult = callers.submit(first); |
| | |
| | | assertEquals(Set.of("<bts><cmd>first_resp</cmd></bts>", "<bts><cmd>second_resp</cmd></bts>"), responses); |
| | | assertEquals(2, simulator.requests().size()); |
| | | assertTrue(simulator.requests().stream().allMatch(request -> request.startsWith("<bts>"))); |
| | | assertTrue(simulator.requests().stream().anyMatch(request -> request.contains("<note>检测</note>"))); |
| | | } |
| | | finally |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void reportsDelayedResponseAsTimeout() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofMillis(50))) |
| | | { |
| | | simulator.enqueueDelayed(Duration.ofMillis(200), "<bts><cmd>late_resp</cmd></bts>"); |
| | | |
| | | BtsTransportException exception = assertThrows(BtsTransportException.class, |
| | | () -> transport.exchange("<bts><cmd>late</cmd></bts>")); |
| | | |
| | | assertEquals(BtsTransportException.Reason.TIMEOUT, exception.reason()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void reportsActiveDisconnectAndReconnectsOnNextExchange() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofSeconds(1))) |
| | | { |
| | | simulator.enqueueDisconnect(); |
| | | |
| | | BtsTransportException exception = assertThrows(BtsTransportException.class, |
| | | () -> transport.exchange("<bts><cmd>first</cmd></bts>")); |
| | | |
| | | assertEquals(BtsTransportException.Reason.DISCONNECTED, exception.reason()); |
| | | |
| | | simulator.enqueue("<bts><cmd>second_resp</cmd></bts>"); |
| | | assertEquals("<bts><cmd>second_resp</cmd></bts>", |
| | | transport.exchange("<bts><cmd>second</cmd></bts>")); |
| | | assertEquals(2, simulator.requests().size()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void rejectsResponseLargerThanConfiguredLimit() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofSeconds(1), 32)) |
| | | { |
| | | simulator.enqueue("x".repeat(33)); |
| | | |
| | | BtsTransportException exception = assertThrows(BtsTransportException.class, |
| | | () -> transport.exchange("<bts><cmd>large</cmd></bts>")); |
| | | |
| | | assertEquals(BtsTransportException.Reason.RESPONSE_TOO_LARGE, exception.reason()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void reportsRefusedConnection() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = ScriptedBtsTcpSimulator.refusingConnections(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofSeconds(1))) |
| | | { |
| | | BtsTransportException exception = assertThrows(BtsTransportException.class, |
| | | () -> transport.exchange("<bts><cmd>getdevinfo</cmd></bts>")); |
| | | |
| | | assertEquals(BtsTransportException.Reason.CONNECTION_FAILED, exception.reason()); |
| | | assertTrue(simulator.requests().isEmpty()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void rejectsResponseTimeoutAboveProtocolMaximum() |
| | | { |
| | | assertThrows(IllegalArgumentException.class, |
| | | () -> new BtsTcpTransport("127.0.0.1", 502, |
| | | Duration.ofSeconds(1), Duration.ofSeconds(31))); |
| | | } |
| | | |
| | | @Test |
| | | void rejectsResponseThatIsNotValidUtf8() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofSeconds(1))) |
| | | { |
| | | simulator.enqueueRaw(new byte[] {(byte) 0xC3, (byte) 0x28}); |
| | | |
| | | BtsTransportException exception = assertThrows(BtsTransportException.class, |
| | | () -> transport.exchange("<bts><cmd>getdevinfo</cmd></bts>")); |
| | | |
| | | assertEquals(BtsTransportException.Reason.INVALID_UTF8, exception.reason()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | | void acceptsResponseAtSizeLimitAndDelimiterPrefixInPayload() throws Exception |
| | | { |
| | | try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator(); |
| | | BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(), |
| | | Duration.ofSeconds(1), Duration.ofSeconds(1), 32)) |
| | | { |
| | | String atLimit = "x".repeat(32); |
| | | simulator.enqueue(atLimit); |
| | | simulator.enqueue("#"); |
| | | |
| | | assertEquals(atLimit, transport.exchange("first")); |
| | | assertEquals("#", transport.exchange("second")); |
| | | } |
| | | } |
| | | } |