yeg
2026-09-07 eee00fd63f558cfa0caf737c868de8fc0c652fcd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.battery.device.simulator;
 
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.battery.device.api.model.ChannelIdentity;
import com.battery.device.api.model.DeviceConnectionStatus;
import com.battery.device.api.model.DeviceWorkStatus;
 
class SimulatorObservationAdapterContractTest
{
    @Test void configuredChannelFactsSurviveSoftwareFailureAndRestart() throws Exception
    {
        var store = new InMemoryBtsSimulatorStateStore();
        long firstSequence;
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0, store))
        {
            simulator.updateChannel(1, 1, true, DeviceWorkStatus.PROTECTED);
            simulator.updateCollectorChannelStatus(1, "S-01", DeviceWorkStatus.UNOBSERVABLE);
            var collector = simulator.latestCollector("dev-sim-collector-1");
            assertTrue(collector.measurements().stream().noneMatch(item -> item.channelCode().equals("S-01")));
            firstSequence = collector.measurements().get(0).sequenceId();
            simulator.setSoftwareAccessible(false);
            simulator.updateDevice(1, "127.0.0.8", 4, false);
            assertFalse(simulator.snapshot().softwareAccessible());
        }
        try (BtsDevelopmentSimulator restored = new BtsDevelopmentSimulator(0, store))
        {
            assertFalse(restored.snapshot().softwareAccessible());
            assertEquals("127.0.0.8", restored.snapshot().devices().get(0).ip());
            assertEquals(DeviceWorkStatus.PROTECTED, restored.snapshot().devices().get(0).channels().get(0).workStatus());
            assertTrue(restored.snapshot().collectors().get(0).latestMeasurements().isEmpty());
            restored.setSoftwareAccessible(true);
            assertTrue(restored.latestCollector("dev-sim-collector-1").measurements().get(0).sequenceId() > firstSequence);
            assertEquals(DeviceWorkStatus.UNOBSERVABLE, restored.snapshot().collectors().get(0).channels().get(0).workStatus());
        }
    }
 
    @Test void offlineCollectorDoesNotReturnLastSuccessAndStateReadsDoNotSample() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            assertTrue(simulator.snapshot().collectors().get(0).latestMeasurements().isEmpty());
            var first = simulator.collectorRealtime(1);
            var recent = simulator.snapshot().recentRequests();
            assertEquals(recent, simulator.snapshot().recentRequests());
            simulator.updateCollector(1, "127.0.1.2", 4, false);
            assertFalse(simulator.collectorRealtime(1).online());
            assertTrue(simulator.collectorRealtime(1).measurements().isEmpty());
            simulator.updateCollector(1, "127.0.1.2", 4, true);
            assertTrue(simulator.collectorRealtime(1).measurements().get(0).sequenceId() > first.measurements().get(0).sequenceId());
            var channel = simulator.discoverChannels().get(0).identity();
            simulator.updateChannel(1, 1, true, DeviceWorkStatus.UNOBSERVABLE);
            assertNull(simulator.latestCabinet(channel));
            assertEquals(DeviceWorkStatus.UNOBSERVABLE, simulator.observe(java.util.Set.of(channel)).get(channel).workStatus());
        }
    }
 
    @Test void softwareFailurePreservesIdentityAndDoesNotReplayMeasurements() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            var channel = simulator.discoverChannels().get(0).identity();
            simulator.updateChannel(1, 1, true, DeviceWorkStatus.WORKING);
            var first = simulator.latestCabinet(channel);
            assertNotNull(first);
            assertFalse(simulator.latestCollector("dev-sim-collector-1").measurements().isEmpty());
            simulator.setSoftwareAccessible(false);
            assertEquals(channel, simulator.discoverChannels().get(0).identity());
            assertTrue(simulator.snapshot().devices().get(0).online());
            assertEquals(DeviceWorkStatus.UNOBSERVABLE,
                    simulator.observe(java.util.Set.of(channel)).get(channel).workStatus());
            assertNull(simulator.latestCabinet(channel));
            assertTrue(simulator.latestCollector("dev-sim-collector-1").measurements().isEmpty());
            simulator.setSoftwareAccessible(true);
            var next = simulator.latestCabinet(channel);
            assertTrue(next.sequenceId() > first.sequenceId());
            assertFalse(next.deviceTime().isBefore(first.deviceTime()));
            assertTrue(simulator.stepRecords(channel).isEmpty());
            assertTrue(simulator.cycleRecords(channel).isEmpty());
            assertEquals(60000L, simulator.persistenceIntervalMillis(channel));
        }
    }
 
    @Test void persistenceRejectsForeignIdentitiesAndOfflineCachedFacts() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            ChannelIdentity channel = simulator.discoverChannels().get(0).identity();
            simulator.updateChannel(channel.devid(), channel.chlid(), true, DeviceWorkStatus.WORKING);
            assertNotNull(simulator.latestCabinet(channel));
            for (ChannelIdentity foreign : java.util.List.of(
                    new ChannelIdentity("another-adapter", channel.devtype(), channel.devid(), channel.subdevid(), channel.chlid()),
                    new ChannelIdentity(channel.adapterCode(), 999, channel.devid(), channel.subdevid(), channel.chlid()),
                    new ChannelIdentity(channel.adapterCode(), channel.devtype(), channel.devid(), 999, channel.chlid())))
            {
                assertNull(simulator.latestCabinet(foreign));
                assertNull(simulator.testPlan(foreign));
                assertTrue(simulator.stepRecords(foreign).isEmpty());
                assertTrue(simulator.cycleRecords(foreign).isEmpty());
            }
            simulator.updateChannel(channel.devid(), channel.chlid(), false, DeviceWorkStatus.WORKING);
            assertNull(simulator.latestCabinet(channel));
            assertTrue(simulator.stepRecords(channel).isEmpty());
            assertTrue(simulator.cycleRecords(channel).isEmpty());
        }
    }
 
    @Test
    void simulatorCanBeUsedDirectlyThroughTheVendorNeutralContract() throws Exception
    {
        try (BtsDevelopmentSimulator simulator = new BtsDevelopmentSimulator(0))
        {
            ChannelIdentity channel = simulator.discoverChannels().get(0).identity();
            simulator.updateChannel(channel.devid(), channel.chlid(), true, DeviceWorkStatus.WORKING);
 
            var observation = simulator.observe(java.util.Set.of(channel)).get(channel);
 
            assertEquals("dev-sim", simulator.adapterCode());
            assertEquals(DeviceConnectionStatus.ONLINE, observation.connectionStatus());
            assertEquals(DeviceWorkStatus.WORKING, observation.workStatus());
        }
    }
}