yeg
2026-08-30 56cddf53e7e71afad29885d7fcf773a222b95f6c
ruoyi-admin/src/test/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorControllerTest.java
@@ -5,7 +5,10 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.time.Instant;
import java.util.List;
@@ -13,6 +16,7 @@
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.server.ResponseStatusException;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.device.bts.BtsDevelopmentSimulator;
import com.ruoyi.device.discovery.DeviceDiscoveryCandidateStore.CabinetCandidate;
@@ -21,6 +25,7 @@
import com.ruoyi.device.model.ChannelIdentity;
import com.ruoyi.device.model.DeviceWorkStatus;
import com.ruoyi.web.config.BtsDevelopmentSimulatorWebConfig;
import com.ruoyi.config.DevelopmentCollectorStatusSynchronizer;
class BtsDevelopmentSimulatorControllerTest
{
@@ -68,6 +73,25 @@
    }
    @Test
    void controllerCreatesNewareDeviceFromExplicitModelProfile() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            BtsDevelopmentSimulatorController controller = controller(simulator);
            var created = controller.createDevice(new BtsDevelopmentSimulatorController.CreateDeviceCommand(
                    "127.0.0.8", 0, "CT-4008T-5V6A-S1-F"));
            var device = created.devices().stream().filter(item -> item.ip().equals("127.0.0.8"))
                    .findFirst().orElseThrow();
            assertEquals(8, device.channels().size());
            assertEquals("新威", device.profile().manufacturer());
            assertEquals("CT-4008T-5V6A-S1-F", device.profile().model());
            assertEquals(100, device.profile().sampleIntervalMs());
        }
    }
    @Test
    void controllerConfiguresCollectorsSeparatelyFromCabinets() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
@@ -95,6 +119,90 @@
    }
    @Test
    void controllerExposesCollectorRealtimeAndPagedHistory() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            BtsDevelopmentSimulatorController controller = controller(simulator);
            controller.configureCollectorSampling(1,
                    new BtsDevelopmentSimulatorController.CollectorSamplingCommand(
                            100, List.of(), null, null, false));
            controller.configureCollectorChannel(1, "S-01",
                    new BtsDevelopmentSimulatorController.CollectorChannelCommand(List.of(
                            new BtsDevelopmentSimulatorController.CollectorMetricCommand(
                                    "temperature", new BigDecimal("27.2"), "℃"),
                            new BtsDevelopmentSimulatorController.CollectorMetricCommand(
                                    "custom_voltage", new BigDecimal("1.234"), "V"))));
            simulator.advanceCollectors(Instant.parse("2026-08-29T01:00:00Z"));
            var realtime = controller.collectorRealtime(1);
            var firstPage = controller.collectorHistory(1, 0, 2);
            assertTrue(realtime.online());
            assertTrue(realtime.measurements().stream().anyMatch(item -> item.metricCode().equals("custom_voltage")));
            assertEquals(2, firstPage.records().size());
            assertTrue(firstPage.hasMore());
            assertEquals(2, firstPage.nextOffset());
        }
    }
    @Test
    void controllerPowersAllSimulatorDevicesWithoutResettingHistory() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            BtsDevelopmentSimulatorController controller = controller(simulator);
            simulator.advanceCollectors(Instant.now());
            long historyCount = controller.state().collectors().get(0).historyRecordCount();
            var poweredOff = controller.setPower(
                    new BtsDevelopmentSimulatorController.SimulatorPowerCommand(false));
            assertTrue(poweredOff.devices().stream().noneMatch(device -> device.online()
                    || device.channels().stream().anyMatch(channel -> channel.online())));
            assertTrue(poweredOff.collectors().stream().noneMatch(collector -> collector.online()));
            assertEquals(historyCount, poweredOff.collectors().get(0).historyRecordCount());
            var poweredOn = controller.setPower(
                    new BtsDevelopmentSimulatorController.SimulatorPowerCommand(true));
            assertTrue(poweredOn.devices().stream().allMatch(device -> device.online()
                    && device.channels().stream().allMatch(channel -> channel.online()
                            && channel.workStatus() == DeviceWorkStatus.STOPPED)));
            assertTrue(poweredOn.collectors().stream().allMatch(collector -> collector.online()));
        }
    }
    @Test
    void powerChangeImmediatelyReconcilesCollectorStatus() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            DevelopmentCollectorStatusSynchronizer synchronizer = mock(DevelopmentCollectorStatusSynchronizer.class);
            BtsDevelopmentSimulatorController controller = new BtsDevelopmentSimulatorController(simulator,
                    new InMemoryDeviceDiscoveryCandidateStore(), synchronizer);
            controller.setPower(new BtsDevelopmentSimulatorController.SimulatorPowerCommand(true));
            verify(synchronizer).synchronizeOnlineStatus();
        }
    }
    @Test
    void simulatorPowerCommandRequiresExplicitState() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            BtsDevelopmentSimulatorController controller = controller(simulator);
            ResponseStatusException exception = assertThrows(ResponseStatusException.class,
                    () -> controller.setPower(new BtsDevelopmentSimulatorController.SimulatorPowerCommand(null)));
            assertEquals(400, exception.getStatusCode().value());
            assertTrue(controller.state().collectors().get(0).online());
        }
    }
    @Test
    void virtualIpMustBeUniqueAcrossCabinetsAndCollectors() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))