| | |
| | | |
| | | class DeviceDiscoveryPersistenceServiceTest |
| | | { |
| | | /** |
| | | * 来源不可达时,既有候选保留来源身份但旧快照被撤下、在线转为离线,登记设备同步离线; |
| | | * 来源恢复后下一次成功发现重新带回实时事实。 |
| | | */ |
| | | @Test |
| | | void failedDiscoveryInvalidatesSuccessfulSnapshotUntilSoftwareReturns() throws Exception |
| | | void failedDiscoveryInvalidatesSuccessfulSnapshotUntilSourceReturns() |
| | | { |
| | | try (var simulator = new com.battery.device.simulator.BtsDevelopmentSimulator(0); |
| | | var registry = new DeviceAdapterRegistry(List.of(new com.battery.device.bts.BtsDeviceAdapterFactory()))) |
| | | { |
| | | registry.synchronize(new com.battery.device.api.registry.AdapterInstanceConfig("dev-sim", "BTS", |
| | | "127.0.0.1", simulator.port(), 5000, "Asia/Hong_Kong", true, |
| | | com.battery.device.api.model.AdapterCapabilities.observeOnly())); |
| | | var store = new InMemoryDeviceDiscoveryCandidateStore(); |
| | | var mapper = Mockito.mock(TDetectionCabinetMapper.class); |
| | | var persistence = new DeviceDiscoveryPersistenceService(store, mapper); |
| | | var scheduler = new com.battery.business.runtime.DevelopmentSimulatorDiscoveryScheduler(registry, persistence); |
| | | simulator.updateChannel(1, 1, true, com.battery.device.api.model.DeviceWorkStatus.WORKING); |
| | | scheduler.discover(); |
| | | var before = store.snapshot(java.time.Instant.now()).cabinets().get(0); |
| | | org.junit.jupiter.api.Assertions.assertNotNull(before.channels().get(0).latestSnapshot()); |
| | | simulator.setSoftwareAccessible(false); |
| | | scheduler.discover(); |
| | | var failed = store.snapshot(java.time.Instant.now()).cabinets().get(0); |
| | | assertEquals(before.deviceCode(), failed.deviceCode()); |
| | | org.junit.jupiter.api.Assertions.assertFalse(failed.online()); |
| | | org.junit.jupiter.api.Assertions.assertNull(failed.channels().get(0).latestSnapshot()); |
| | | verify(mapper).markRegisteredCabinetsOffline("dev-sim"); |
| | | simulator.setSoftwareAccessible(true); |
| | | scheduler.discover(); |
| | | org.junit.jupiter.api.Assertions.assertTrue(store.snapshot(java.time.Instant.now()).cabinets().get(0).online()); |
| | | } |
| | | InMemoryDeviceDiscoveryCandidateStore store = new InMemoryDeviceDiscoveryCandidateStore(); |
| | | TDetectionCabinetMapper cabinetMapper = Mockito.mock(TDetectionCabinetMapper.class); |
| | | DeviceAdapterRegistry registry = Mockito.mock(DeviceAdapterRegistry.class); |
| | | DeviceAdapter adapter = Mockito.mock(DeviceAdapter.class); |
| | | ChannelIdentity identity = new ChannelIdentity("neware76", 21, 36, 1, 2); |
| | | java.time.Instant observedAt = java.time.Instant.parse("2026-09-28T01:54:56Z"); |
| | | com.battery.device.api.model.RealtimeSnapshot snapshot = new com.battery.device.api.model.RealtimeSnapshot( |
| | | identity, com.battery.device.api.model.DeviceWorkStatus.WORKING, 3, 7, "1", null, |
| | | new java.math.BigDecimal("1.2"), new java.math.BigDecimal("3.3"), |
| | | new java.math.BigDecimal("0.5"), new java.math.BigDecimal("1.1"), 60L, 30L, null, observedAt, java.util.Map.of()); |
| | | when(adapter.discoverChannels()).thenReturn(List.of(new DetectedChannel(identity, "26.1.2.3", true))); |
| | | when(adapter.inquire(any())).thenReturn(java.util.Map.of(identity, snapshot)); |
| | | when(registry.execute(eq("neware76"), any())).thenAnswer(invocation -> { |
| | | @SuppressWarnings("unchecked") |
| | | Function<DeviceAdapter, Object> operation = (Function<DeviceAdapter, Object>) invocation.getArgument(1); |
| | | return operation.apply(adapter); |
| | | }); |
| | | DeviceDiscoveryPersistenceService service = new DeviceDiscoveryPersistenceService(store, cabinetMapper); |
| | | service.discoverForReception(registry, new DeviceDiscoveryPersistenceService.DiscoverySource( |
| | | "neware76", 8L, "新威 7.6 那台", 60000, true)); |
| | | |
| | | var before = store.snapshot(java.time.Instant.now()).cabinets().get(0); |
| | | org.junit.jupiter.api.Assertions.assertNotNull(before.channels().get(0).latestSnapshot()); |
| | | org.junit.jupiter.api.Assertions.assertTrue(before.online()); |
| | | |
| | | service.markUnavailable("neware76"); |
| | | |
| | | var failed = store.snapshot(java.time.Instant.now()).cabinets().get(0); |
| | | assertEquals(before.deviceCode(), failed.deviceCode()); |
| | | org.junit.jupiter.api.Assertions.assertFalse(failed.online()); |
| | | org.junit.jupiter.api.Assertions.assertNull(failed.channels().get(0).latestSnapshot()); |
| | | verify(cabinetMapper).markRegisteredCabinetsOffline("neware76"); |
| | | } |
| | | |
| | | @Test |