yeg
2026-08-26 db2eb9412ddc4ff687eb4c9b862053f49f9aec7b
ruoyi-device/src/test/java/com/ruoyi/device/bts/ScriptedBtsTcpSimulator.java
@@ -5,7 +5,9 @@
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -19,24 +21,55 @@
    private static final byte[] FRAME_END = "#\r\n".getBytes(StandardCharsets.UTF_8);
    private final ServerSocket serverSocket;
    private final int port;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final BlockingQueue<String> responses = new LinkedBlockingQueue<>();
    private final BlockingQueue<ScriptedAction> actions = new LinkedBlockingQueue<>();
    private final List<String> requests = new CopyOnWriteArrayList<>();
    ScriptedBtsTcpSimulator() throws IOException
    {
        this(true);
    }
    private ScriptedBtsTcpSimulator(boolean acceptConnections) throws IOException
    {
        serverSocket = new ServerSocket(0);
        port = serverSocket.getLocalPort();
        if (acceptConnections)
        executor.submit(this::serve);
        else
            serverSocket.close();
    }
    static ScriptedBtsTcpSimulator refusingConnections() throws IOException
    {
        return new ScriptedBtsTcpSimulator(false);
    }
    int port()
    {
        return serverSocket.getLocalPort();
        return port;
    }
    void enqueue(String response)
    {
        responses.add(response);
        actions.add(new ScriptedAction(Duration.ZERO, response.getBytes(StandardCharsets.UTF_8), false));
    }
    void enqueueDelayed(Duration delay, String response)
    {
        if (delay.isNegative()) throw new IllegalArgumentException("delay must not be negative");
        actions.add(new ScriptedAction(delay, response.getBytes(StandardCharsets.UTF_8), false));
    }
    void enqueueRaw(byte[] response)
    {
        actions.add(new ScriptedAction(Duration.ZERO, response.clone(), false));
    }
    void enqueueDisconnect()
    {
        actions.add(new ScriptedAction(Duration.ZERO, null, true));
    }
    List<String> requests()
@@ -46,21 +79,35 @@
    private void serve()
    {
        while (!serverSocket.isClosed())
        {
        try (Socket socket = serverSocket.accept())
            {
                serveConnection(socket);
            }
            catch (SocketException ex)
            {
                if (!serverSocket.isClosed()) throw new IllegalStateException(ex);
            }
            catch (Exception ignored)
            {
            }
        }
    }
    private void serveConnection(Socket socket) throws Exception
        {
            while (!socket.isClosed())
            {
                String request = readFrame(socket.getInputStream());
                requests.add(request);
                String response = responses.poll(5, TimeUnit.SECONDS);
                if (response == null) throw new IOException("No scripted BTS response available");
                socket.getOutputStream().write(response.getBytes(StandardCharsets.UTF_8));
            ScriptedAction action = actions.poll(5, TimeUnit.SECONDS);
            if (action == null) throw new IOException("No scripted BTS action available");
            TimeUnit.MILLISECONDS.sleep(action.delay().toMillis());
            if (action.disconnect()) return;
            socket.getOutputStream().write(action.payload());
                socket.getOutputStream().write(FRAME_END);
                socket.getOutputStream().flush();
            }
        }
        catch (Exception ignored)
        {
        }
    }
@@ -94,4 +141,8 @@
        executor.shutdownNow();
        executor.awaitTermination(2, TimeUnit.SECONDS);
    }
    private record ScriptedAction(Duration delay, byte[] payload, boolean disconnect)
    {
    }
}