yeg
2026-08-27 210663040bf65ee00b5f86545fdc31bd0356fddf
ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
@@ -1,6 +1,7 @@
package com.ruoyi.device.contract;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.time.Duration;
import java.time.ZoneId;
import java.util.Set;
@@ -13,6 +14,11 @@
import com.ruoyi.device.bts.ScriptedBtsTcpSimulator;
import com.ruoyi.device.model.DetectedChannel;
import com.ruoyi.device.model.DeviceWorkStatus;
import com.ruoyi.device.simulator.BtsSimulatorStateStore;
import com.ruoyi.device.simulator.BtsSimulatorStateStore.ChannelState;
import com.ruoyi.device.simulator.BtsSimulatorStateStore.DeviceState;
import com.ruoyi.device.simulator.BtsSimulatorStateStore.SimulatorState;
import com.ruoyi.device.simulator.InMemoryBtsSimulatorStateStore;
class SimulatorPublicContractTest
{
@@ -137,4 +143,104 @@
            assertEquals(4, adapter.discoverChannels().size());
        }
    }
    @Test
    void developmentCollectorsNeverEnterBtsCabinetDiscovery() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0);
             BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", simulator.port(),
                     Duration.ofSeconds(1), Duration.ofSeconds(1));
             DeviceAdapter adapter = new BtsDeviceAdapter("dev-sim", transport,
                     new BtsXmlCodec("dev-sim", ZoneId.of("Asia/Hong_Kong"))))
        {
            assertEquals(4, adapter.discoverChannels().size());
            simulator.addCollector("127.0.1.8", 12);
            assertEquals(4, adapter.discoverChannels().size());
            assertEquals(2, simulator.snapshot().collectors().size());
        }
    }
    @Test
    void developmentSimulatorRestoresConfigurationNumberingAndStatus() throws Exception
    {
        InMemoryBtsSimulatorStateStore store = new InMemoryBtsSimulatorStateStore();
        try (BtsDevelopmentSimulator first = new BtsDevelopmentSimulator(0, store))
        {
            first.updateDevice(1, "127.0.0.9", 2, false);
            first.addDevice("127.0.0.10", 3);
            first.updateCollector(1, "127.0.1.9", 7, false);
        }
        try (BtsDevelopmentSimulator restored = new BtsDevelopmentSimulator(0, store))
        {
            assertEquals(2, restored.snapshot().devices().size());
            assertEquals("127.0.0.9", restored.snapshot().devices().get(0).ip());
            assertEquals(false, restored.snapshot().devices().get(0).online());
            assertEquals(7, restored.snapshot().collectors().get(0).channelCount());
            assertEquals(3, restored.addDevice("127.0.0.11", 1));
        }
    }
    @Test
    void developmentSimulatorDoesNotExposeWriteThroughFailureInMemory() throws Exception
    {
        InMemoryBtsSimulatorStateStore delegate = new InMemoryBtsSimulatorStateStore();
        BtsSimulatorStateStore failing = new BtsSimulatorStateStore()
        {
            @Override public SimulatorState loadOrInitialize(SimulatorState value)
            { return delegate.loadOrInitialize(value); }
            @Override public void save(SimulatorState value) { throw new IllegalStateException("redis unavailable"); }
            @Override public java.util.List<RecentRequest> loadRecentRequests()
            { return delegate.loadRecentRequests(); }
            @Override public void saveRecentRequests(java.util.List<RecentRequest> requests)
            { delegate.saveRecentRequests(requests); }
            @Override public void reset(SimulatorState value) { delegate.reset(value); }
        };
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0, failing))
        {
            assertThrows(IllegalStateException.class, () -> simulator.addDevice("127.0.0.3", 2));
            assertEquals(1, simulator.snapshot().devices().size());
        }
    }
    @Test
    void developmentSimulatorRestoresUnfinishedTombstones() throws Exception
    {
        InMemoryBtsSimulatorStateStore store = new InMemoryBtsSimulatorStateStore();
        try (BtsDevelopmentSimulator first = new BtsDevelopmentSimulator(0, store);
             BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", first.port(),
                     Duration.ofSeconds(1), Duration.ofSeconds(1));
             DeviceAdapter adapter = new BtsDeviceAdapter("dev-sim", transport,
                     new BtsXmlCodec("dev-sim", ZoneId.of("Asia/Hong_Kong"))))
        {
            first.deleteDevice(1);
            assertEquals(4, adapter.discoverChannels().size());
        }
        try (BtsDevelopmentSimulator restored = new BtsDevelopmentSimulator(0, store);
             BtsTcpTransport transport = new BtsTcpTransport("127.0.0.1", restored.port(),
                     Duration.ofSeconds(1), Duration.ofSeconds(1));
             DeviceAdapter adapter = new BtsDeviceAdapter("dev-sim", transport,
                     new BtsXmlCodec("dev-sim", ZoneId.of("Asia/Hong_Kong"))))
        {
            assertEquals(4, adapter.discoverChannels().size());
            assertEquals(4, adapter.discoverChannels().size());
            assertEquals(0, adapter.discoverChannels().size());
        }
    }
    @Test
    void developmentSimulatorRejectsNonContiguousRestoredChannelTopology()
    {
        SimulatorState damaged = new SimulatorState(BtsSimulatorStateStore.CURRENT_VERSION,
                java.util.List.of(new DeviceState(1, "127.0.0.2", true,
                        java.util.List.of(new ChannelState(2, true, DeviceWorkStatus.STOPPED)))),
                java.util.List.of(), 2, 1, java.util.List.of());
        assertThrows(IllegalStateException.class,
                () -> new BtsDevelopmentSimulator(0, new InMemoryBtsSimulatorStateStore(damaged)));
    }
}