package com.zy.ai.service.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.zy.ai.domain.autotune.AutoTuneRuleSnapshotItem;
|
import com.zy.asrs.entity.BasDevp;
|
import com.zy.asrs.entity.BasStation;
|
import com.zy.asrs.entity.WrkMast;
|
import com.zy.asrs.service.BasDevpService;
|
import com.zy.asrs.service.BasStationService;
|
import com.zy.asrs.service.WrkMastService;
|
import com.zy.core.model.StationObjModel;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.mockito.ArgumentCaptor;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
class AutoTuneSnapshotServiceImplTest {
|
|
private AutoTuneSnapshotServiceImpl service;
|
|
@BeforeEach
|
void setUp() {
|
service = new AutoTuneSnapshotServiceImpl();
|
}
|
|
@Test
|
void buildStationOutTaskLimitMapPreservesNullZeroAndNegativeLimits() {
|
Map<String, Integer> result = service.buildStationOutTaskLimitMap(Arrays.asList(
|
station(101, null),
|
station(102, 0),
|
station(103, -1),
|
station(104, 5)
|
));
|
|
assertNull(result.get("101"));
|
assertEquals(0, result.get("102"));
|
assertEquals(-1, result.get("103"));
|
assertEquals(5, result.get("104"));
|
}
|
|
@Test
|
void buildStationOutBufferCapacityMapPreservesConfiguredCapacity() {
|
Map<String, Integer> result = service.buildStationOutBufferCapacityMap(Arrays.asList(
|
station(101, 1, null),
|
station(102, 1, 0),
|
station(103, 1, 3)
|
));
|
|
assertNull(result.get("101"));
|
assertEquals(0, result.get("102"));
|
assertEquals(3, result.get("103"));
|
}
|
|
@Test
|
void buildRuleSnapshotExposesStepRangeCooldownAndDynamicMaxSource() {
|
List<AutoTuneRuleSnapshotItem> result = service.buildRuleSnapshot();
|
|
AutoTuneRuleSnapshotItem stationOutTaskRule = findRule(result, "station", "outTaskLimit");
|
assertEquals(0, stationOutTaskRule.getMinValue());
|
assertNull(stationOutTaskRule.getMaxValue());
|
assertEquals(3, stationOutTaskRule.getMaxStep());
|
assertEquals(10, stationOutTaskRule.getCooldownMinutes());
|
assertEquals(Boolean.TRUE, stationOutTaskRule.getDynamicMaxValue());
|
assertEquals("currentParameterSnapshot.stationOutBufferCapacities[targetId]",
|
stationOutTaskRule.getDynamicMaxSource());
|
assertEquals("单次调整幅度不能超过 maxStep;增大时不得超过对应站点 outBufferCapacity。",
|
stationOutTaskRule.getNote());
|
|
AutoTuneRuleSnapshotItem crnMaxOutRule = findRule(result, "crn", "maxOutTask");
|
assertEquals(3, crnMaxOutRule.getMaxStep());
|
assertNull(crnMaxOutRule.getDynamicMaxSource());
|
assertEquals("单次调整幅度不能超过 maxStep。", crnMaxOutRule.getNote());
|
|
AutoTuneRuleSnapshotItem crnMaxInRule = findRule(result, "crn", "maxInTask");
|
assertEquals(3, crnMaxInRule.getMaxStep());
|
|
assertRuleMaxStep(result, "sys_config", "crnOutBatchRunningLimit", 3);
|
assertRuleMaxStep(result, "dual_crn", "maxOutTask", 3);
|
assertRuleMaxStep(result, "dual_crn", "maxInTask", 3);
|
}
|
|
@Test
|
void loadActiveTasksIncludesNullWrkStatusInGroupedCondition() {
|
WrkMastService wrkMastService = mock(WrkMastService.class);
|
when(wrkMastService.list(any(Wrapper.class))).thenReturn(Collections.emptyList());
|
ReflectionTestUtils.setField(service, "wrkMastService", wrkMastService);
|
|
ReflectionTestUtils.invokeMethod(service, "loadActiveTasks");
|
|
ArgumentCaptor<Wrapper<WrkMast>> wrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
|
verify(wrkMastService).list(wrapperCaptor.capture());
|
String sqlSegment = wrapperCaptor.getValue().getSqlSegment();
|
String normalizedSqlSegment = sqlSegment.replaceAll("\\s+", " ");
|
assertTrue(normalizedSqlSegment.contains("(wrk_sts NOT IN"));
|
assertTrue(normalizedSqlSegment.contains("OR wrk_sts IS NULL"));
|
}
|
|
@Test
|
void loadOutStationListOnlyQueriesBasDevpOutStations() {
|
BasStationService basStationService = mock(BasStationService.class);
|
BasDevpService basDevpService = mock(BasDevpService.class);
|
ReflectionTestUtils.setField(service, "basStationService", basStationService);
|
ReflectionTestUtils.setField(service, "basDevpService", basDevpService);
|
when(basDevpService.list(any(Wrapper.class))).thenReturn(Arrays.asList(
|
basDevp(1, 101, 102),
|
basDevp(2, 102)
|
));
|
when(basStationService.list(any(Wrapper.class))).thenReturn(Arrays.asList(
|
station(101, 2),
|
station(102, 3)
|
));
|
|
java.util.List<BasStation> result = ReflectionTestUtils.invokeMethod(service, "loadOutStationList");
|
|
assertEquals(2, result.size());
|
assertEquals(101, result.get(0).getStationId());
|
assertEquals(102, result.get(1).getStationId());
|
|
ArgumentCaptor<Wrapper<BasDevp>> basDevpWrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
|
verify(basDevpService).list(basDevpWrapperCaptor.capture());
|
assertTrue(basDevpWrapperCaptor.getValue().getSqlSegment().contains("status ="));
|
|
ArgumentCaptor<Wrapper<BasStation>> stationWrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
|
verify(basStationService).list(stationWrapperCaptor.capture());
|
assertTrue(stationWrapperCaptor.getValue().getSqlSegment().contains("station_id IN"));
|
}
|
|
@Test
|
void loadOutStationListDoesNotQueryStationsWhenBasDevpOutStationsAreEmpty() {
|
BasStationService basStationService = mock(BasStationService.class);
|
BasDevpService basDevpService = mock(BasDevpService.class);
|
ReflectionTestUtils.setField(service, "basStationService", basStationService);
|
ReflectionTestUtils.setField(service, "basDevpService", basDevpService);
|
when(basDevpService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(basDevp(1)));
|
|
java.util.List<BasStation> result = ReflectionTestUtils.invokeMethod(service, "loadOutStationList");
|
|
assertTrue(result.isEmpty());
|
verify(basStationService, never()).list(any(Wrapper.class));
|
}
|
|
private BasStation station(Integer stationId, Integer outTaskLimit) {
|
return station(stationId, outTaskLimit, null);
|
}
|
|
private BasStation station(Integer stationId, Integer outTaskLimit, Integer outBufferCapacity) {
|
BasStation station = new BasStation();
|
station.setStationId(stationId);
|
station.setOutTaskLimit(outTaskLimit);
|
station.setOutBufferCapacity(outBufferCapacity);
|
return station;
|
}
|
|
private BasDevp basDevp(Integer devpNo, Integer... stationIds) {
|
BasDevp basDevp = new BasDevp();
|
basDevp.setDevpNo(devpNo);
|
basDevp.setStatus(1);
|
if (stationIds == null || stationIds.length == 0) {
|
return basDevp;
|
}
|
basDevp.setOutStationList(JSON.toJSONString(Arrays.stream(stationIds)
|
.map(this::stationObjModel)
|
.toList()));
|
return basDevp;
|
}
|
|
private StationObjModel stationObjModel(Integer stationId) {
|
StationObjModel stationObjModel = new StationObjModel();
|
stationObjModel.setStationId(stationId);
|
return stationObjModel;
|
}
|
|
private AutoTuneRuleSnapshotItem findRule(List<AutoTuneRuleSnapshotItem> rules,
|
String targetType,
|
String targetKey) {
|
for (AutoTuneRuleSnapshotItem rule : rules) {
|
if (targetType.equals(rule.getTargetType()) && targetKey.equals(rule.getTargetKey())) {
|
return rule;
|
}
|
}
|
throw new AssertionError("rule not found: " + targetType + "/" + targetKey);
|
}
|
|
private void assertRuleMaxStep(List<AutoTuneRuleSnapshotItem> rules,
|
String targetType,
|
String targetKey,
|
int expectedMaxStep) {
|
AutoTuneRuleSnapshotItem rule = findRule(rules, targetType, targetKey);
|
assertEquals(expectedMaxStep, rule.getMaxStep());
|
}
|
}
|