diff --git a/backend-java/src/test/java/com/nanri/aiimage/metrics/UploadMetricsTest.java b/backend-java/src/test/java/com/nanri/aiimage/metrics/UploadMetricsTest.java new file mode 100644 index 00000000..05feb5d2 --- /dev/null +++ b/backend-java/src/test/java/com/nanri/aiimage/metrics/UploadMetricsTest.java @@ -0,0 +1,82 @@ +package com.nanri.aiimage.metrics; + +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * task-186:上传耗时/大小/成功率指标契约(spec 11 §1,模块 file 上传接线面)。 + * aiimage.upload.duration Timer + aiimage.upload.size summary + aiimage.upload.result(.success/failure)。 + */ +class UploadMetricsTest { + + private final SimpleMeterRegistry registry = new SimpleMeterRegistry(); + private final TaskObservabilityMetrics metrics = new TaskObservabilityMetrics("server-110", registry); + + @Test + void uploadDurationRecorded() { + metrics.upload("collectdata", 10_000L, 350L, true); + assertEquals(1, registry.get("aiimage.upload.duration").tag("moduleType", "collectdata").timer().count()); + assertEquals(350.0, registry.get("aiimage.upload.duration").tag("moduleType", "collectdata").timer() + .totalTime(TimeUnit.MILLISECONDS), 0.001); + } + + @Test + void uploadSizeRecorded() { + metrics.upload("collectdata", 1024L, 100L, true); + assertEquals(1024.0, + registry.get("aiimage.upload.size").tag("moduleType", "collectdata").summary().totalAmount(), 0.001); + } + + @Test + void uploadSuccessResultCounted() { + metrics.upload("collectdata", 1L, 1L, true); + assertEquals(1.0, registry.get("aiimage.upload.result.success").tag("moduleType", "collectdata").counter().count()); + } + + @Test + void uploadFailureResultCounted() { + metrics.upload("collectdata", 1L, 1L, false); + assertEquals(1.0, registry.get("aiimage.upload.result.failure").tag("moduleType", "collectdata").counter().count()); + assertEquals(0.0, registry.find("aiimage.upload.result.success").tag("moduleType", "collectdata").counter() == null + ? 0.0 + : registry.find("aiimage.upload.result.success").tag("moduleType", "collectdata").counter().count()); + } + + @Test + void uploadSplitByModule() { + metrics.upload("similarasin", 10L, 10L, true); + metrics.upload("publish", 20L, 20L, true); + assertEquals(1, registry.get("aiimage.upload.duration").tag("moduleType", "similarasin").timer().count()); + assertEquals(1, registry.get("aiimage.upload.duration").tag("moduleType", "publish").timer().count()); + } + + @Test + void largeUploadRecorded() { + metrics.upload("shopdatacrawl", 500_000_000L, 30_000L, true); + assertEquals(500_000_000.0, + registry.get("aiimage.upload.size").tag("moduleType", "shopdatacrawl").summary().totalAmount(), 0.001); + } + + @Test + void uploadNamesFrozen() { + metrics.upload("similarasin", 1L, 1L, true); + assertTrue(registry.getMeters().stream() + .anyMatch(m -> m.getId().getName().equals("aiimage.upload.duration"))); + assertTrue(registry.getMeters().stream() + .anyMatch(m -> m.getId().getName().equals("aiimage.upload.size"))); + assertTrue(registry.getMeters().stream() + .anyMatch(m -> m.getId().getName().equals("aiimage.upload.result.success"))); + } + + @Test + void uploadNoMonitoringStackFallbackNoError() { + TaskObservabilityMetrics without = new TaskObservabilityMetrics("server-121", null); + without.upload("similarasin", 1L, 1L, true); + assertEquals("server-121", without.instanceId()); + } +}