c1f03d64d1
- 真实基线:SimilarAsinImageEmbedder(OkHttp) connect/read=imageDownloadTimeoutSeconds(5s)、call=2×download(10s)、prefetch 1800s - resolver 提供 connect/read/call/prefetch/maxRetries 访问面,模块级优先、命名空间兜底,不改调用点 - 仅新增类与测试,零生产行为变化
101 lines
4.0 KiB
Java
101 lines
4.0 KiB
Java
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×download(10s);
|
||
* - 整批预取预算 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);
|
||
}
|
||
}
|