| | |
| | | import static org.junit.jupiter.api.Assertions.assertThrows; |
| | | import static org.mockito.ArgumentMatchers.any; |
| | | import static org.mockito.ArgumentMatchers.eq; |
| | | import static org.mockito.Mockito.never; |
| | | import static org.mockito.Mockito.times; |
| | | import static org.mockito.Mockito.verify; |
| | | import static org.mockito.Mockito.when; |
| | | import java.math.BigDecimal; |
| | | import java.time.Instant; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.function.Function; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.device.api.DeviceAdapter; |
| | | import com.ruoyi.device.bts.BtsTransportException; |
| | | import com.ruoyi.device.api.DeviceAdapterException; |
| | | import com.ruoyi.device.model.ChannelIdentity; |
| | | import com.ruoyi.device.model.DetectedChannel; |
| | | import com.ruoyi.device.model.DeviceWorkStatus; |
| | | import com.ruoyi.device.model.RealtimeSnapshot; |
| | | import com.ruoyi.device.registry.DeviceAdapterRegistry; |
| | | import com.ruoyi.system.domain.TDetectionCabinet; |
| | | import com.ruoyi.system.domain.TDetectionChannel; |
| | |
| | | void repeatedDiscoveryUpsertsStableChannelIdentityWithoutDeletingMissingChannels() |
| | | { |
| | | when(adapterMapper.selectDeviceAdapterById(7L)).thenReturn(adapter); |
| | | when(registry.require("lab-bts")).thenReturn(deviceAdapter); |
| | | when(deviceAdapter.discoverChannels()).thenReturn(List.of( |
| | | new DetectedChannel(new ChannelIdentity("lab-bts", 22, 1, 2, 3), "192.168.1.35", true), |
| | | new DetectedChannel(new ChannelIdentity("lab-bts", 22, 1, 2, 4), "192.168.1.35", false))); |
| | | stubRegistryExecution(); |
| | | when(adapterMapper.selectCabinetIdByIdentity(7L, 22, 1)).thenReturn(10L); |
| | | |
| | | assertEquals(2, service.discover(7L).channelCount()); |
| | | assertEquals(2, service.discover(7L).channelCount()); |
| | | |
| | | verify(adapterMapper, times(4)).upsertDetectedChannel(any(TDetectionChannel.class)); |
| | | verify(adapterMapper, never()).deleteMissingChannels(any(), any()); |
| | | verify(adapterMapper, times(2)).updateDiscoverySuccess(eq(7L), any()); |
| | | verify(adapterMapper, times(2)).updateDetectedCabinet(any(TDetectionCabinet.class)); |
| | | } |
| | | |
| | | @Test |
| | | void discoveryPersistsRealtimeWorkStatusForAvailableChannels() |
| | | { |
| | | ChannelIdentity identity = new ChannelIdentity("lab-bts", 22, 1, 2, 3); |
| | | when(adapterMapper.selectDeviceAdapterById(7L)).thenReturn(adapter); |
| | | when(deviceAdapter.discoverChannels()).thenReturn(List.of( |
| | | new DetectedChannel(identity, "192.168.1.35", true))); |
| | | when(deviceAdapter.inquire(Set.of(identity))).thenReturn(Map.of(identity, |
| | | new RealtimeSnapshot(identity, DeviceWorkStatus.WORKING, 1, 2, "cc", null, |
| | | BigDecimal.ONE, BigDecimal.TEN, null, null, 3L, 2L, null, |
| | | Instant.parse("2026-08-26T01:02:03Z"), Map.of()))); |
| | | when(adapterMapper.selectCabinetIdByIdentity(7L, 22, 1)).thenReturn(10L); |
| | | stubRegistryExecution(); |
| | | |
| | | service.discover(7L); |
| | | |
| | | var channel = org.mockito.ArgumentCaptor.forClass(TDetectionChannel.class); |
| | | verify(adapterMapper).upsertDetectedChannel(channel.capture()); |
| | | assertEquals("WORKING", channel.getValue().getWorkStatus()); |
| | | } |
| | | |
| | | @Test |
| | | void connectionFailureHasStableCodeAndLaterDiscoveryClearsError() |
| | | { |
| | | when(adapterMapper.selectDeviceAdapterById(7L)).thenReturn(adapter); |
| | | when(registry.require("lab-bts")).thenReturn(deviceAdapter); |
| | | when(deviceAdapter.discoverChannels()) |
| | | .thenThrow(new BtsTransportException(BtsTransportException.Reason.CONNECTION_FAILED, |
| | | "connection refused", null)) |
| | | .thenThrow(new DeviceAdapterException("CONNECTION_FAILED", "connection refused", null)) |
| | | .thenReturn(List.of()); |
| | | stubRegistryExecution(); |
| | | |
| | | ServiceException failure = assertThrows(ServiceException.class, () -> service.discover(7L)); |
| | | assertEquals(DeviceAdapterErrorCodes.DISCOVERY_FAILED, failure.getCode()); |
| | |
| | | assertEquals(0, service.discover(7L).channelCount()); |
| | | verify(adapterMapper).updateDiscoverySuccess(eq(7L), any()); |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private void stubRegistryExecution() |
| | | { |
| | | when(registry.execute(eq("lab-bts"), any())).thenAnswer(invocation -> |
| | | ((Function<DeviceAdapter, Object>) invocation.getArgument(1)).apply(deviceAdapter)); |
| | | } |
| | | } |