fix(pipeline): 增强人脸匹配流水线的健壮性

- 在FilterByTimeRangeStage中增加空值检查和配置验证
- 在LoadMatchedSamplesStage中增加sampleListIds空值检查
- 添加完整的集成测试覆盖Pipeline工厂和Context构建
- 为FilterByDevicePhotoLimitStage添加全面的单元测试
- 为FilterByTimeRangeStage添加边界条件和异常处理测试
- 为LoadMatchedSamplesStage添加异常路径测试
This commit is contained in:
2025-12-03 18:17:34 +08:00
parent 96e75a458f
commit b3fa10e8fd
6 changed files with 800 additions and 1 deletions

View File

@@ -69,9 +69,23 @@ public class FilterByTimeRangeStage extends AbstractFaceMatchingStage<FaceMatchi
protected StageResult<FaceMatchingContext> doExecute(FaceMatchingContext context) {
List<FaceSampleEntity> faceSamples = context.getFaceSamples();
List<Long> sampleListIds = context.getSampleListIds();
Integer tourMinutes = context.getScenicConfig().getInteger("tour_time");
Long faceId = context.getFaceId();
// 防御性检查:faceSamples为空
if (faceSamples == null || faceSamples.isEmpty()) {
log.debug("faceSamples为空,跳过时间范围筛选,faceId={}", faceId);
return StageResult.skipped("faceSamples为空");
}
// 防御性检查:tour_time配置
Integer tourMinutes = context.getScenicConfig() != null
? context.getScenicConfig().getInteger("tour_time")
: null;
if (tourMinutes == null || tourMinutes <= 0) {
log.debug("景区未配置tour_time或配置为0,跳过时间范围筛选,faceId={}", faceId);
return StageResult.skipped("未配置tour_time");
}
try {
// 1. 构建样本ID到实体的映射
Map<Long, FaceSampleEntity> sampleMap = faceSamples.stream()

View File

@@ -64,6 +64,12 @@ public class LoadMatchedSamplesStage extends AbstractFaceMatchingStage<FaceMatch
List<Long> sampleListIds = context.getSampleListIds();
Long faceId = context.getFaceId();
// 防御性检查:如果sampleListIds为空,直接跳过
if (sampleListIds == null || sampleListIds.isEmpty()) {
log.debug("sampleListIds为空,跳过加载匹配样本,faceId={}", faceId);
return StageResult.skipped("sampleListIds为空");
}
try {
// 批量加载样本实体
List<FaceSampleEntity> faceSamples = faceSampleMapper.listByIds(sampleListIds);