| | |
| | | var mapper = mock(TTestMapper.class); when(mapper.selectCollectorCode(7L)).thenReturn("collector-7"); |
| | | var adapter = mock(TestDataObservationAdapter.class); |
| | | var service = new TTestLiveServiceImpl(tests, |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, mapper); |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, mapper, null); |
| | | test.setReceptionBoundaryAtUtc(java.util.Date.from(now)); |
| | | for (Instant deviceTime : List.of(now.minusSeconds(1), now)) { |
| | | var measurement = new TestDataObservationAdapter.CollectorMeasurement("S-01", 1L, deviceTime, deviceTime.toString(), |
| | |
| | | @Test |
| | | void currentTemperatureAlarmIsIndependentOfHistoricalTodoHandling() throws Exception |
| | | { |
| | | try (var simulator = new com.battery.device.simulator.BtsDevelopmentSimulator(0)) { |
| | | TTest test = test("RECEIVING"); |
| | | var battery = test.getBatteries().get(0); battery.setCollectorId(7L); |
| | | var primary = new com.battery.business.domain.TTestCollectorChannel(); |
| | |
| | | test.setThresholds(List.of(rule)); |
| | | var tests = mock(ITTestService.class); when(tests.selectTestById(10L)).thenReturn(test); |
| | | var mapper = mock(TTestMapper.class); when(mapper.selectCollectorCode(7L)).thenReturn("dev-sim-collector-1"); |
| | | var adapter = mock(TestDataObservationAdapter.class); |
| | | Instant now = Instant.now(); |
| | | // 采集器来源交出主、辅助两路测量:只有绑定了的 S-01 主温度进预警。 |
| | | when(adapter.latestCollector(org.mockito.ArgumentMatchers.nullable(String.class), |
| | | org.mockito.ArgumentMatchers.eq("dev-sim-collector-1"))).thenReturn(collectorRealtime(now, "38")); |
| | | var service = new TTestLiveServiceImpl(tests, |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), simulator, mapper); |
| | | simulator.configureCollectorChannel(1, "S-01", List.of( |
| | | new com.battery.device.simulator.BtsSimulatorStateStore.CollectorMetricState("temperature", new BigDecimal("38"), "℃"))); |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, mapper, null); |
| | | var alarms = service.current(10L).exceptions().stream().filter(item -> "THRESHOLD".equals(item.get("exceptionType"))).toList(); |
| | | assertEquals(1, alarms.size()); |
| | | assertEquals(new BigDecimal("38"), alarms.get(0).get("value")); |
| | |
| | | history.setExceptionType("THRESHOLD"); history.setMetricCode("temperature"); |
| | | history.setAbnormalValue(new BigDecimal("38")); |
| | | when(mapper.selectWarningExceptions(10L, "OPEN")).thenReturn(List.of(history)); |
| | | simulator.configureCollectorChannel(1, "S-01", List.of( |
| | | new com.battery.device.simulator.BtsSimulatorStateStore.CollectorMetricState("temperature", new BigDecimal("25"), "℃"))); |
| | | when(adapter.latestCollector(org.mockito.ArgumentMatchers.nullable(String.class), |
| | | org.mockito.ArgumentMatchers.eq("dev-sim-collector-1"))).thenReturn(collectorRealtime(now, "25")); |
| | | assertTrue(service.current(10L).exceptions().stream().noneMatch(item -> "THRESHOLD".equals(item.get("exceptionType")))); |
| | | assertEquals("OPEN", history.getExceptionStatus()); |
| | | } |
| | | |
| | | private static TestDataObservationAdapter.CollectorRealtime collectorRealtime(Instant now, String temperature) |
| | | { |
| | | return new TestDataObservationAdapter.CollectorRealtime("dev-sim-collector-1", true, 1000, |
| | | List.of(new TestDataObservationAdapter.CollectorMeasurement("S-01", 1L, now, now.toString(), now, |
| | | "TEMPERATURE", new BigDecimal(temperature), "℃")), null); |
| | | } |
| | | |
| | | @Test |
| | | void consoleReadsConfiguredSimulatorPlanAtCurrentChannelPosition() throws Exception |
| | | void consoleReadsConfiguredPlanAtCurrentChannelPosition() throws Exception |
| | | { |
| | | try (var simulator = new com.battery.device.simulator.BtsDevelopmentSimulator(0)) { |
| | | var test = test("RECEIVING"); |
| | | var binding = test.getBatteries().get(0).getBinding(); |
| | | binding.setDevtype(22); binding.setSubdevid(1); |
| | | simulator.configureChannel(1, 1, new com.battery.device.simulator.BtsSimulatorStateStore.ChannelConfiguration( |
| | | BigDecimal.ONE, new BigDecimal("4.125"), BigDecimal.ONE, BigDecimal.ONE, 2, 2, 3, 120, 30, |
| | | List.of(new com.battery.device.simulator.BtsSimulatorStateStore.SimulatorPlanStep("充电", "cc", 60, 4.2), |
| | | new com.battery.device.simulator.BtsSimulatorStateStore.SimulatorPlanStep("放电", "dc", 90, 3.0)))); |
| | | simulator.updateChannel(1, 1, true, DeviceWorkStatus.WORKING); |
| | | var tests = mock(ITTestService.class); |
| | | when(tests.selectTestById(10L)).thenReturn(test); |
| | | var adapter = mock(TestDataObservationAdapter.class); |
| | | // 来源交出它自己的方案:当前循环 2、当前工步 2、计划 3 个循环,工步行按循环位置排列。 |
| | | when(adapter.testPlan(any(ChannelIdentity.class))).thenReturn(new TestDataObservationAdapter.TestPlan(2, 2, 3, |
| | | List.of(new TestDataObservationAdapter.PlanRow("STEP", 1, 1, "充电", 60, 4.2, "已完成", null, null), |
| | | new TestDataObservationAdapter.PlanRow("STEP", 2, 2, "放电", 90, 3.0, "进行中", null, null)))); |
| | | var service = new TTestLiveServiceImpl(tests, |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), simulator); |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, null, null); |
| | | var plan = service.current(10L).testPlan(); |
| | | assertEquals(2, plan.currentCycleNo()); |
| | | assertEquals(2, plan.currentStepNo()); |
| | |
| | | assertEquals("放电", plan.rows().get(1).stepName()); |
| | | assertEquals(90d, plan.rows().get(1).durationSeconds()); |
| | | assertEquals("进行中", plan.rows().get(1).executionStatus()); |
| | | simulator.updateChannel(1, 1, false, DeviceWorkStatus.WORKING); |
| | | when(adapter.testPlan(any(ChannelIdentity.class))).thenReturn(null); |
| | | org.junit.jupiter.api.Assertions.assertNull(service.current(10L).testPlan()); |
| | | } |
| | | } |
| | | |
| | | @Test |
| | |
| | | assertTrue(alarms.stream().anyMatch(item -> "CABINET_CHANNEL".equals(item.get("sourceType")))); |
| | | } |
| | | |
| | | /** |
| | | * 非接收状态只读来源可达性:状态取自所链接来源实例的连接结果,且**不请求**任何测量, |
| | | * 否则暂停期间仍会产生新观测。 |
| | | */ |
| | | @Test |
| | | void nonReceivingConsoleReadsCollectorStatusWithoutRequestingMeasurements() throws Exception |
| | | { |
| | | try (var simulator = new com.battery.device.simulator.BtsDevelopmentSimulator(0)) |
| | | { |
| | | TTest test = test("RECEIVING"); |
| | | test.getBatteries().get(0).setCollectorId(7L); |
| | |
| | | when(tests.selectTestById(10L)).thenReturn(test); |
| | | var mapper = mock(TTestMapper.class); |
| | | when(mapper.selectCollectorCode(7L)).thenReturn("dev-sim-collector-1"); |
| | | var candidates = new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(); |
| | | Instant now = Instant.now(); |
| | | candidates.replaceCollectors("dev-sim", List.of(new DeviceDiscoveryCandidateStore.CollectorCandidate( |
| | | "dev-sim", "dev-sim-collector-1", "127.0.1.2", null, "模拟采集器", null, null, |
| | | 4, true, now, now.plusSeconds(30)))); |
| | | var service = new TTestLiveServiceImpl(tests, candidates, simulator, mapper); |
| | | service.current(10L); |
| | | var received = simulator.snapshot().recentRequests(); |
| | | assertTrue(received.stream().anyMatch(item -> item.command().equals("collector-realtime"))); |
| | | var adapter = mock(TestDataObservationAdapter.class); |
| | | var adapters = mock(com.battery.business.mapper.TDeviceAdapterMapper.class); |
| | | var source = new com.battery.business.domain.TDeviceAdapter(); |
| | | source.setConnectionStatus("ONLINE"); |
| | | when(adapters.selectDeviceAdapterByCode("dev-sim")).thenReturn(source); |
| | | var service = new TTestLiveServiceImpl(tests, |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, mapper, adapters); |
| | | test.setReceptionStatus("RECEIVING"); |
| | | var receiving = service.current(10L).sources().stream() |
| | | .filter(item -> item.sourceType().equals("COLLECTOR")).findFirst().orElseThrow(); |
| | | assertEquals("ONLINE", receiving.deviceStatus()); |
| | | verify(adapter).latestCollector(org.mockito.ArgumentMatchers.eq("dev-sim"), |
| | | org.mockito.ArgumentMatchers.eq("dev-sim-collector-1")); |
| | | org.mockito.Mockito.clearInvocations(adapter); |
| | | for (String status : List.of("PAUSED", "ENDED", "NOT_STARTED")) |
| | | { |
| | | test.setReceptionStatus(status); |
| | | var source = service.current(10L).sources().stream() |
| | | var paused = service.current(10L).sources().stream() |
| | | .filter(item -> item.sourceType().equals("COLLECTOR")).findFirst().orElseThrow(); |
| | | assertEquals("ONLINE", source.deviceStatus()); |
| | | assertTrue(source.latestSnapshot().isEmpty()); |
| | | assertEquals(received, simulator.snapshot().recentRequests()); |
| | | assertEquals("ONLINE", paused.deviceStatus()); |
| | | assertTrue(paused.latestSnapshot().isEmpty()); |
| | | } |
| | | verify(adapter, never()).latestCollector(org.mockito.ArgumentMatchers.anyString(), |
| | | org.mockito.ArgumentMatchers.anyString()); |
| | | } |
| | | |
| | | /** 来源不提供辅助测量(新威实测无辅助数据)时如实标注,并且不因此生成离线异常。 */ |
| | | @Test |
| | | void collectorWithoutAuxiliaryMeasurementsStaysOnlineAndIsMarkedUnavailable() throws Exception |
| | | { |
| | | TTest test = test("RECEIVING"); |
| | | test.getBatteries().get(0).setCollectorId(7L); |
| | | var tests = mock(ITTestService.class); |
| | | when(tests.selectTestById(10L)).thenReturn(test); |
| | | var mapper = mock(TTestMapper.class); |
| | | when(mapper.selectCollectorCode(7L)).thenReturn("neware76-collector"); |
| | | var adapter = mock(TestDataObservationAdapter.class); |
| | | when(adapter.latestCollector(org.mockito.ArgumentMatchers.anyString(), |
| | | org.mockito.ArgumentMatchers.anyString())).thenReturn(null); |
| | | var adapters = mock(com.battery.business.mapper.TDeviceAdapterMapper.class); |
| | | var source = new com.battery.business.domain.TDeviceAdapter(); |
| | | source.setConnectionStatus("ONLINE"); |
| | | when(adapters.selectDeviceAdapterByCode("dev-sim")).thenReturn(source); |
| | | var service = new TTestLiveServiceImpl(tests, |
| | | new com.battery.device.api.discovery.InMemoryDeviceDiscoveryCandidateStore(), adapter, mapper, adapters); |
| | | |
| | | var collector = service.current(10L).sources().stream() |
| | | .filter(item -> item.sourceType().equals("COLLECTOR")).findFirst().orElseThrow(); |
| | | |
| | | assertEquals("ONLINE", collector.deviceStatus()); |
| | | assertEquals(Boolean.FALSE, collector.latestSnapshot().get("auxiliaryDataAvailable")); |
| | | assertFalse(collector.latestSnapshot().containsKey("measurements")); |
| | | assertTrue(service.current(10L).exceptions().stream() |
| | | .noneMatch(item -> "COLLECTOR".equals(item.get("sourceType")))); |
| | | } |
| | | |
| | | @Test |
| | |
| | | "dev-sim", 1L, "dev-sim", 1, 1, "127.0.0.2", "mac", "cabinet", "vendor", "model", |
| | | List.of(channel), now, now.plusSeconds(60)); |
| | | when(candidates.snapshot(any(Instant.class))).thenReturn( |
| | | new DeviceDiscoveryCandidateStore.CandidateSnapshot(List.of(cabinet), List.of())); |
| | | new DeviceDiscoveryCandidateStore.CandidateSnapshot(List.of(cabinet))); |
| | | var plan = new TestDataObservationAdapter.TestPlan(1, 1, 1, List.of()); |
| | | when(simulator.testPlan(any(ChannelIdentity.class))).thenReturn(plan); |
| | | if (mapper != null && test.getBatteries().get(0).getCollectorId() != null) { |
| | |
| | | private CurrentLiveService(ITTestService tests, DeviceDiscoveryCandidateStore candidates, |
| | | TestDataObservationAdapter simulator, TTestMapper mapper) |
| | | { |
| | | super(tests, candidates, simulator, mapper); |
| | | super(tests, candidates, simulator, mapper, null); |
| | | } |
| | | } |
| | | |