Files
crawler-plugin/backend-java/src/test/java/com/nanri/aiimage/config/ImageDownloadHttpConfigResolverTest.java
T
huangzd1997 c1f03d64d1 task-171: 图片下载客户端配置接入(ImageDownloadHttpConfigResolver,download/prefetch 模块级现有配置优先、命名空间兜底)+ 8 条测试
- 真实基线:SimilarAsinImageEmbedder(OkHttp) connect/read=imageDownloadTimeoutSeconds(5s)、call=2×download(10s)、prefetch 1800s
- resolver 提供 connect/read/call/prefetch/maxRetries 访问面,模块级优先、命名空间兜底,不改调用点
- 仅新增类与测试,零生产行为变化
2026-09-04 23:10:36 +08:00

101 lines
4.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.nanri.aiimage.config;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* task-171:图片下载客户端配置接入契约(plan 10,诚实模式)。
*
* 现网真实基线(已核实,对应 task-166 契约表"图片下载"行):
* - SimilarAsinImageEmbedder 用自建 OkHttpClient(非共享 JDK 池):connect/read/write =
* aiimage.similar-asin.image-download-timeout-seconds(默认 5s),call = 2×download10s);
* - 整批预取预算 aiimage.similar-asin.image-prefetch-timeout-seconds(默认 1800s);
* - 无显式次数重试(依赖 OkHttp retryOnConnectionFailure + 上游批次重提),图片缓存幂等。
*
* resolver 语义:模块级现有配置优先(保证接入切点行为不变),命名空间 aiimage.http-client.*
* 兜底;不改动 SimilarAsinImageEmbedder 调用点,仅提供稳定访问面。
*/
class ImageDownloadHttpConfigResolverTest {
private HttpClientProperties http;
private SimilarAsinProperties similarAsin;
private ImageDownloadHttpConfigResolver resolver;
@BeforeEach
void setUp() {
http = new HttpClientProperties();
similarAsin = new SimilarAsinProperties();
resolver = new ImageDownloadHttpConfigResolver(http, similarAsin);
}
@Test
void defaultsMatchCurrentEmbedder() {
// 模块默认 imageDownloadTimeoutSeconds=5 → OkHttp connect/read 5s、call 10s
assertEquals(5_000L, resolver.readTimeoutMillis());
assertEquals(5_000L, resolver.connectTimeoutMillis());
assertEquals(10_000L, resolver.callTimeoutMillis());
}
@Test
void prefetchBudgetFromModule() {
// 模块默认 imagePrefetchTimeoutSeconds=1800 → 1800s
assertEquals(1_800_000L, resolver.prefetchTimeoutMillis());
}
@Test
void moduleWinsOverNamespace() {
// 模块级现有配置优先:命名空间 read 调大不影响图片下载 read(行为不变)
http.setReadTimeoutMillis(120_000);
assertEquals(5_000L, resolver.readTimeoutMillis());
}
@Test
void downloadOverrideTakesEffect() {
similarAsin.setImageDownloadTimeoutSeconds(8);
assertEquals(8_000L, resolver.readTimeoutMillis());
assertEquals(8_000L, resolver.connectTimeoutMillis());
assertEquals(16_000L, resolver.callTimeoutMillis(), "call = 2×download");
}
@Test
void fallsBackToNamespaceWhenModuleUnset() {
// 模块未配置(<=0) → 命名空间(默认 connect 10s/read 60s/call 90s
similarAsin.setImageDownloadTimeoutSeconds(0);
similarAsin.setImagePrefetchTimeoutSeconds(0);
assertEquals(10_000L, resolver.connectTimeoutMillis());
assertEquals(60_000L, resolver.readTimeoutMillis());
assertEquals(90_000L, resolver.callTimeoutMillis());
assertEquals(60_000L, resolver.prefetchTimeoutMillis());
}
@Test
void retryFromNamespaceClamped() {
// 无显式次数重试是现状;次数来自命名空间,供未来接入切点
assertEquals(3, resolver.maxRetries());
http.setMaxRetries(99);
assertEquals(10, resolver.maxRetries(), "命名空间重试钳制到 10");
assertEquals(500L, resolver.baseRetryDelayMillis());
}
@Test
void invalidNamespaceTimeoutsClamped() {
similarAsin.setImageDownloadTimeoutSeconds(0);
similarAsin.setImagePrefetchTimeoutSeconds(0);
http.setConnectTimeoutMillis(-1);
assertEquals(1_000L, resolver.connectTimeoutMillis());
http.setReadTimeoutMillis(999_999_999L);
assertEquals(3_600_000L, resolver.readTimeoutMillis());
}
@Test
void resolverWiredAsStableAccessSurface() {
assertTrue(resolver.connectTimeoutMillis() > 0);
assertTrue(resolver.readTimeoutMillis() > 0);
assertTrue(resolver.callTimeoutMillis() > 0);
assertTrue(resolver.maxRetries() >= 0);
}
}