From 210663040bf65ee00b5f86545fdc31bd0356fddf Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期四, 27 八月 2026 16:31:53 +0800
Subject: [PATCH] feat(device): persist simulator discovery in redis
---
ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java b/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
index 85887f6..de1a699 100644
--- a/ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java
+++ b/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)));
+ }
}
--
Gitblit v1.7.1