fix: clarify shadow refresh recovery contract

This commit is contained in:
zgw
2026-09-03 11:39:31 +08:00
parent c6a8b4f3b2
commit 5ed39162cc
3 changed files with 161 additions and 1 deletions

View File

@@ -4,6 +4,8 @@ import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.Clock;
import static org.assertj.core.api.Assertions.assertThat;
@@ -75,9 +77,31 @@ class ShadowSnapshotCoordinatorTest {
ShadowSnapshotCoordinator.Admission wrongWarehouse = coordinator.enter(NOW);
assertThat(wrongWarehouse.accepted()).isFalse();
assertThat(wrongWarehouse.skipReason()).isEqualTo(ShadowSkipReason.WAREHOUSE);
assertThat(coordinator.phase()).isEqualTo(ShadowSnapshotCoordinator.Phase.BUSY);
coordinator.exit(wrongWarehouse);
}
@Test
void staleOrMismatchedEntryRecoversThroughRefresh() {
ShadowSnapshotCoordinator coordinator = coordinatorAt("01");
publish(coordinator, snapshot(7, "02", NOW));
ShadowSnapshotCoordinator.Admission skipped = coordinator.enter(NOW);
coordinator.exit(skipped);
assertThat(coordinator.phase()).isEqualTo(ShadowSnapshotCoordinator.Phase.BUSY);
assertThat(coordinator.tryBeginRefresh(NOW)).isPresent();
}
@Test
void exitUsesInjectedClockForQuietSince() {
Instant exitTime = NOW.plusSeconds(17);
ShadowSnapshotCoordinator coordinator = new ShadowSnapshotCoordinator(
"01", Duration.ofSeconds(60), Clock.fixed(exitTime, ZoneOffset.UTC));
ShadowSnapshotCoordinator.Admission admission = coordinator.enter(NOW);
coordinator.exit(admission);
assertThat(coordinator.quietSince()).isEqualTo(exitTime);
}
@Test
void treatsNumericWarehouseIdsAsEquivalent() {
ShadowSnapshotCoordinator coordinator = coordinatorAt("01");