yeg
2026-08-26 db2eb9412ddc4ff687eb4c9b862053f49f9aec7b
ruoyi-device/src/test/java/com/ruoyi/device/bts/BtsTcpTransportTest.java
@@ -1,6 +1,7 @@
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;
@@ -23,7 +24,7 @@
            {
                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);
@@ -33,6 +34,7 @@
                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
            {
@@ -40,4 +42,112 @@
            }
        }
    }
    @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"));
        }
    }
}