mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-14 03:33:43 +08:00
85 lines
3.1 KiB
Java
85 lines
3.1 KiB
Java
package vip.mate.channel;
|
||
|
||
import org.junit.jupiter.api.DisplayName;
|
||
import org.junit.jupiter.api.Test;
|
||
|
||
import static org.junit.jupiter.api.Assertions.*;
|
||
|
||
/** RFC-024 Change 5: ExponentialBackoff 新增 jitter 字段的行为验证(含向后兼容)。 */
|
||
class ExponentialBackoffTest {
|
||
|
||
@Test
|
||
@DisplayName("默认构造 jitter=0,行为与旧版本完全一致(纯指数递增)")
|
||
void defaultConstructorHasNoJitter() {
|
||
var b = new ExponentialBackoff();
|
||
assertEquals(0.0, b.getJitter(), 0.0001);
|
||
assertEquals(2000L, b.nextDelayMs());
|
||
assertEquals(4000L, b.nextDelayMs());
|
||
assertEquals(8000L, b.nextDelayMs());
|
||
assertEquals(16000L, b.nextDelayMs());
|
||
assertEquals(30000L, b.nextDelayMs()); // 触顶 maxDelay
|
||
assertEquals(30000L, b.nextDelayMs());
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("4-arg 旧构造等价 jitter=0(向后兼容)")
|
||
void fourArgLegacyConstructorZeroJitter() {
|
||
var b = new ExponentialBackoff(2000, 30000, 2.0, -1);
|
||
assertEquals(0.0, b.getJitter(), 0.0001);
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("jitter=0.2 时延迟在 ±20% 范围内波动")
|
||
void jitterRandomWithinConfiguredRange() {
|
||
var b = new ExponentialBackoff(1000, 60000, 2.0, -1, 0.2);
|
||
// 第一次 nextDelayMs:base=1000,jitter ±20%,期望 [800, 1200]
|
||
for (int trial = 0; trial < 50; trial++) {
|
||
b.reset();
|
||
long d = b.nextDelayMs();
|
||
assertTrue(d >= 800 && d <= 1200, "expected 800..1200, got " + d + " (trial " + trial + ")");
|
||
}
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("jitter 不会让延迟溢出到超过 maxDelayMs")
|
||
void jitterClampedToMaxDelay() {
|
||
var b = new ExponentialBackoff(10000, 15000, 2.0, -1, 0.5);
|
||
for (int i = 0; i < 20; i++) {
|
||
long d = b.nextDelayMs();
|
||
assertTrue(d <= 15000, "delay should never exceed max 15000, got " + d);
|
||
}
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("jitter 非负(偶尔随机会让 base 变成负数,需夹到 0)")
|
||
void jitterNeverNegative() {
|
||
// 小 initial + 大 jitter,理论上可能产生负数,应夹到 0
|
||
var b = new ExponentialBackoff(10, 100, 2.0, -1, 0.8);
|
||
for (int i = 0; i < 50; i++) {
|
||
b.reset();
|
||
assertTrue(b.nextDelayMs() >= 0);
|
||
}
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("reset() 清零后 nextDelayMs 从 initial 再开始")
|
||
void resetRestartsFromInitial() {
|
||
var b = new ExponentialBackoff(1000, 10000, 2.0, -1, 0.0);
|
||
b.nextDelayMs(); b.nextDelayMs(); b.nextDelayMs();
|
||
assertTrue(b.getAttempts() > 0);
|
||
b.reset();
|
||
assertEquals(0, b.getAttempts());
|
||
assertEquals(1000L, b.nextDelayMs());
|
||
}
|
||
|
||
@Test
|
||
@DisplayName("jitter 参数被夹到 [0, 1)(防止恶意配置)")
|
||
void jitterClampedToValidRange() {
|
||
var bNeg = new ExponentialBackoff(1000, 10000, 2.0, -1, -0.5);
|
||
assertEquals(0.0, bNeg.getJitter(), 0.0001);
|
||
|
||
var bTooBig = new ExponentialBackoff(1000, 10000, 2.0, -1, 1.5);
|
||
assertTrue(bTooBig.getJitter() < 1.0);
|
||
}
|
||
}
|