From 0ec4fb3534fa428d31802e595c09bc74be8557f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Fri, 4 Sep 2026 23:48:20 +0800 Subject: [PATCH] =?UTF-8?q?task-183:=20task.duration=20=E8=80=97=E6=97=B6?= =?UTF-8?q?=E6=8C=87=E6=A0=87=E5=A5=91=E7=BA=A6=EF=BC=88Timer=EF=BC=8C?= =?UTF-8?q?=E9=9D=9E=E8=B4=9F=E3=80=81=E5=88=86=E6=A8=A1=E5=9D=97=E3=80=81?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=86=BB=E7=BB=93=EF=BC=89+=208=20=E6=9D=A1?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metrics/TaskDurationMetricsTest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 backend-java/src/test/java/com/nanri/aiimage/metrics/TaskDurationMetricsTest.java diff --git a/backend-java/src/test/java/com/nanri/aiimage/metrics/TaskDurationMetricsTest.java b/backend-java/src/test/java/com/nanri/aiimage/metrics/TaskDurationMetricsTest.java new file mode 100644 index 00000000..fed3af5b --- /dev/null +++ b/backend-java/src/test/java/com/nanri/aiimage/metrics/TaskDurationMetricsTest.java @@ -0,0 +1,77 @@ +package com.nanri.aiimage.metrics; + +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * task-183:task.duration 耗时记录契约(spec 11 §1)。 + * 开始→终态耗时以 Timer 记录(未配置注册表时降级 debug 日志);非负;分 moduleType。 + */ +class TaskDurationMetricsTest { + + private final SimpleMeterRegistry registry = new SimpleMeterRegistry(); + private final TaskObservabilityMetrics metrics = new TaskObservabilityMetrics("server-110", registry); + + private io.micrometer.core.instrument.Timer timer(String moduleType) { + return registry.get("aiimage.task.duration").tag("moduleType", moduleType).timer(); + } + + @Test + void durationRecorded() { + metrics.taskDuration("similarasin", 1_234L); + assertEquals(1, timer("similarasin").count()); + assertEquals(1_234.0, timer("similarasin").totalTime(java.util.concurrent.TimeUnit.MILLISECONDS), 0.001); + } + + @Test + void durationAccumulates() { + metrics.taskDuration("similarasin", 100L); + metrics.taskDuration("similarasin", 200L); + assertEquals(2, timer("similarasin").count()); + assertEquals(300.0, timer("similarasin").totalTime(java.util.concurrent.TimeUnit.MILLISECONDS), 0.001); + } + + @Test + void shortTaskRecorded() { + metrics.taskDuration("similarasin", 1L); + assertTrue(timer("similarasin").count() >= 1); + } + + @Test + void longTaskRecordedLarger() { + metrics.taskDuration("similarasin", 600_000L); + assertEquals(600_000.0, timer("similarasin").totalTime(java.util.concurrent.TimeUnit.MILLISECONDS), 0.001); + } + + @Test + void durationNeverNegative() { + metrics.taskDuration("similarasin", -5L); + assertEquals(0.0, timer("similarasin").totalTime(java.util.concurrent.TimeUnit.MILLISECONDS), 0.001, + "负耗时按 0 处理,不应破坏指标"); + } + + @Test + void durationSplitByModule() { + metrics.taskDuration("similarasin", 100L); + metrics.taskDuration("publish", 50L); + assertEquals(1, timer("similarasin").count()); + assertEquals(1, timer("publish").count()); + } + + @Test + void durationNameFrozen() { + metrics.taskDuration("similarasin", 10L); + assertTrue(registry.getMeters().stream() + .anyMatch(m -> m.getId().getName().equals("aiimage.task.duration"))); + } + + @Test + void durationCarriesInstanceLabel() { + metrics.taskDuration("similarasin", 10L); + assertEquals("server-110", + registry.get("aiimage.task.duration").timer().getId().getTag("instanceId")); + } +}