From 0162f3730ca2e9644322a90450728b63243d40d0 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 29 八月 2026 13:36:20 +0800
Subject: [PATCH] 修正采集器历史与实时快照模型

---
 ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java |   88 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 88 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 9e8be45..ba19503 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
@@ -21,8 +21,11 @@
 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.CollectorChannelState;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorHistoryFaults;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMeasurementRecord;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMetricState;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorState;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.DeviceState;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.SimulatorState;
 import com.ruoyi.device.simulator.InMemoryBtsSimulatorStateStore;
@@ -109,6 +112,53 @@
             assertEquals(List.of("S-01", "S-02", "S-03", "S-04"),
                     restored.snapshot().collectors().get(0).channels().stream()
                             .map(channel -> channel.channelCode()).toList());
+        }
+    }
+
+    @Test
+    void collectorKeepsAppendOnlyHistoryBeyondPreviousDisplayLimit() throws Exception
+    {
+        Instant startedAt = Instant.parse("2026-08-29T03:00:00Z");
+        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
+        {
+            simulator.configureCollectorSampling(1, 100, CollectorHistoryFaults.none());
+            simulator.advanceCollectors(startedAt);
+            for (int batch = 1; batch <= 5; batch++)
+                simulator.advanceCollectors(startedAt.plusMillis(batch * 100_000L));
+
+            assertEquals(60_012, simulator.collectorHistory(1, 0, 1).total());
+            assertEquals(1, simulator.collectorHistory(1, 0, 1).records().get(0).sequenceId());
+        }
+    }
+
+    @Test
+    void collectorRealtimeDropsMeasurementsRemovedFromCurrentConfiguration() throws Exception
+    {
+        Instant startedAt = Instant.parse("2026-08-29T04:00:00Z");
+        InMemoryBtsSimulatorStateStore store = new InMemoryBtsSimulatorStateStore();
+        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0, store))
+        {
+            simulator.advanceCollectors(startedAt);
+            assertEquals(12, simulator.snapshot().collectors().get(0).latestMeasurements().size());
+
+            simulator.configureCollectorChannel(1, "S-01", List.of(
+                    new CollectorMetricState("temperature", new BigDecimal("27.0"), "℃")));
+            simulator.updateCollector(1, "127.0.1.2", 2, true);
+
+            var snapshot = simulator.snapshot().collectors().get(0);
+            assertEquals(4, snapshot.latestMeasurements().size());
+            assertTrue(snapshot.latestMeasurements().stream()
+                    .noneMatch(item -> item.channelCode().equals("S-03")
+                            || item.channelCode().equals("S-04")
+                            || item.channelCode().equals("S-01")
+                                    && item.metricCode().equals("positive_potential")));
+            assertEquals(12, simulator.collectorHistory(1, 0, 100).total());
+        }
+
+        try (BtsDevelopmentSimulator restored = new BtsDevelopmentSimulator(0, store))
+        {
+            assertEquals(4, restored.snapshot().collectors().get(0).latestMeasurements().size());
+            assertEquals(12, restored.collectorHistory(1, 0, 100).total());
         }
     }
 
@@ -333,4 +383,42 @@
         assertThrows(IllegalStateException.class,
                 () -> new BtsDevelopmentSimulator(0, new InMemoryBtsSimulatorStateStore(damaged)));
     }
+
+    @Test
+    void developmentSimulatorRejectsDamagedCollectorHistoryIdentity()
+    {
+        Instant observedAt = Instant.parse("2026-08-29T05:00:00Z");
+        List<CollectorChannelState> channels = List.of(new CollectorChannelState("S-01", List.of(
+                new CollectorMetricState("temperature", new BigDecimal("25.0"), "℃"))));
+        CollectorState collector = new CollectorState(1, "dev-sim-collector-1", "127.0.1.2",
+                "02:43:00:00:00:01", "模拟采集器", "开发模拟器", "Virtual Collector", 1, true,
+                1000, 2L, observedAt, channels, List.of(), List.of(new CollectorMeasurementRecord(
+                        "dev-sim", "wrong-collector", "S-01", 1L, observedAt,
+                        "2026-08-29 13:00:00.000", observedAt, "temperature",
+                        new BigDecimal("25.0"), "℃")), CollectorHistoryFaults.none());
+        SimulatorState damaged = new SimulatorState(BtsSimulatorStateStore.CURRENT_VERSION,
+                List.of(), List.of(collector), 1, 2, List.of());
+
+        assertThrows(IllegalStateException.class,
+                () -> new BtsDevelopmentSimulator(0, new InMemoryBtsSimulatorStateStore(damaged)));
+    }
+
+    @Test
+    void developmentSimulatorRejectsCollectorSequenceBehindPersistedHistory()
+    {
+        Instant observedAt = Instant.parse("2026-08-29T06:00:00Z");
+        List<CollectorChannelState> channels = List.of(new CollectorChannelState("S-01", List.of(
+                new CollectorMetricState("temperature", new BigDecimal("25.0"), "℃"))));
+        CollectorState collector = new CollectorState(1, "dev-sim-collector-1", "127.0.1.2",
+                "02:43:00:00:00:01", "模拟采集器", "开发模拟器", "Virtual Collector", 1, true,
+                1000, 1L, observedAt, channels, List.of(), List.of(new CollectorMeasurementRecord(
+                        "dev-sim", "dev-sim-collector-1", "S-01", 1L, observedAt,
+                        "2026-08-29 14:00:00.000", observedAt, "temperature",
+                        new BigDecimal("25.0"), "℃")), CollectorHistoryFaults.none());
+        SimulatorState damaged = new SimulatorState(BtsSimulatorStateStore.CURRENT_VERSION,
+                List.of(), List.of(collector), 1, 2, List.of());
+
+        assertThrows(IllegalStateException.class,
+                () -> new BtsDevelopmentSimulator(0, new InMemoryBtsSimulatorStateStore(damaged)));
+    }
 }

--
Gitblit v1.7.1