From 7ab0e426264707fb85ee38d0a9a73caf41899635 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 29 八月 2026 13:11:40 +0800
Subject: [PATCH] 实现采集器独立实时与历史采样模拟
---
ruoyi-device/src/test/java/com/ruoyi/device/contract/SimulatorPublicContractTest.java | 90 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 90 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 de1a699..9e8be45 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,9 +1,14 @@
package com.ruoyi.device.contract;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.math.BigDecimal;
import java.time.Duration;
+import java.time.Instant;
import java.time.ZoneId;
+import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;
import com.ruoyi.device.api.DeviceAdapter;
@@ -16,6 +21,8 @@
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.CollectorHistoryFaults;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMetricState;
import com.ruoyi.device.simulator.BtsSimulatorStateStore.DeviceState;
import com.ruoyi.device.simulator.BtsSimulatorStateStore.SimulatorState;
import com.ruoyi.device.simulator.InMemoryBtsSimulatorStateStore;
@@ -23,6 +30,89 @@
class SimulatorPublicContractTest
{
@Test
+ void collectorGeneratesIndependentRealtimeAndHistoricalMeasurements() throws Exception
+ {
+ Instant startedAt = Instant.parse("2026-08-29T01:00:00Z");
+ try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
+ {
+ simulator.configureCollectorSampling(1, 200, CollectorHistoryFaults.none());
+ simulator.configureCollectorChannel(1, "S-01", List.of(
+ new CollectorMetricState("temperature", new BigDecimal("26.5"), "℃"),
+ new CollectorMetricState("positive_potential", new BigDecimal("3.801"), "V"),
+ new CollectorMetricState("negative_potential", new BigDecimal("-0.120"), "V"),
+ new CollectorMetricState("pressure", new BigDecimal("101.2"), "kPa")));
+
+ simulator.advanceCollectors(startedAt);
+ simulator.advanceCollectors(startedAt.plusMillis(400));
+
+ var realtime = simulator.snapshot().collectors().get(0).latestMeasurements();
+ var history = simulator.collectorHistory(1, 0, 1000);
+ assertEquals(13, realtime.size());
+ assertTrue(realtime.stream().allMatch(item -> item.sequenceId() == 3));
+ assertTrue(realtime.stream().anyMatch(item -> item.channelCode().equals("S-01")
+ && item.metricCode().equals("pressure") && item.unit().equals("kPa")));
+ assertEquals(39, history.total());
+ assertEquals("dev-sim", history.records().get(0).adapterCode());
+ assertEquals("dev-sim-collector-1", history.records().get(0).collectorCode());
+ assertEquals(startedAt, history.records().get(0).deviceTime());
+ assertTrue(history.records().get(0).deviceTimeRaw().startsWith("2026-08-29 09:00:00"));
+ assertEquals(startedAt, history.records().get(0).serverReceivedAt());
+ }
+ }
+
+ @Test
+ void collectorHistorySupportsPagingAndRepeatableFaultScenarios() throws Exception
+ {
+ Instant startedAt = Instant.parse("2026-08-29T02:00:00Z");
+ try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
+ {
+ simulator.configureCollectorSampling(1, 100,
+ new CollectorHistoryFaults(List.of(2L), 1L, 3L, true));
+ simulator.advanceCollectors(startedAt);
+ simulator.advanceCollectors(startedAt.plusMillis(200));
+
+ var first = simulator.collectorHistory(1, 0, 17);
+ var second = simulator.collectorHistory(1, first.nextOffset(), 1000);
+ List<com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMeasurementRecord> records =
+ new java.util.ArrayList<>(first.records());
+ records.addAll(second.records());
+
+ assertEquals(48, first.total());
+ assertTrue(first.hasMore());
+ assertFalse(second.hasMore());
+ assertTrue(records.stream().noneMatch(item -> item.sequenceId() == 2));
+ assertEquals(24, records.stream().filter(item -> item.sequenceId() == 1).count());
+ assertEquals(2, records.stream().filter(item -> item.sequenceId() == 3
+ && item.channelCode().equals("S-01") && item.metricCode().equals("temperature")).count());
+ assertTrue(records.get(0).sequenceId() >= records.get(records.size() - 1).sequenceId());
+ }
+ }
+
+ @Test
+ void collectorStopsWhileOfflineAndResumesFromPersistedSequence() throws Exception
+ {
+ InMemoryBtsSimulatorStateStore store = new InMemoryBtsSimulatorStateStore();
+ Instant now = Instant.now();
+ try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0, store))
+ {
+ simulator.advanceCollectors(now);
+ simulator.updateCollector(1, "127.0.1.2", 4, false);
+ simulator.advanceCollectors(now.plusSeconds(10));
+ assertEquals(1, simulator.snapshot().collectors().get(0).latestMeasurements().get(0).sequenceId());
+ }
+
+ try (BtsDevelopmentSimulator restored = new BtsDevelopmentSimulator(0, store))
+ {
+ restored.updateCollector(1, "127.0.1.2", 4, true);
+ restored.advanceCollectors(Instant.now().plusSeconds(2));
+ assertTrue(restored.snapshot().collectors().get(0).latestMeasurements().get(0).sequenceId() >= 2);
+ 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 simulatorIsReusableOutsideTheBtsPackage() throws Exception
{
try (ScriptedBtsTcpSimulator simulator = new ScriptedBtsTcpSimulator();
--
Gitblit v1.7.1