MaintenanceEventControllerRegistrationTest.java
package redis.clients.jedis;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Duration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for the {@link MaintenanceController} surface of {@link MaintenanceEventController}:
* what {@link MaintenanceEventController#register} installs on a connection, what
* {@link MaintenanceEventController#unregister} tears down. No sockets: the connections are bare.
*/
public class MaintenanceEventControllerRegistrationTest {
private static final int SO_TIMEOUT_MS = 2000;
private static final int RELAXED_TIMEOUT_MS = 10_000;
private MaintenanceEventController controller;
private Connection conn;
@BeforeEach
public void setUp() {
controller = MaintenanceEventController
.from(MaintenanceNotificationsConfig.builder().relaxedTimeout(RELAXED_TIMEOUT_MS).build());
conn = new Connection();
conn.setSoTimeout(SO_TIMEOUT_MS);
}
@AfterEach
public void tearDown() {
controller.close();
ConnectionTestHelper.resetClockNanos();
}
@Test
public void registerInstallsThePoolWideAndPerConnectionOverlaysAndTheListener() {
controller.register(conn);
assertTrue(conn.getMaintenanceEventListeners().contains(controller));
ChainedTimeoutSource chain = conn.getTimeoutSource();
assertInstanceOf(ManagedTimeoutSource.class, chain.seekBy(controller),
"the pool-wide MOVING rebind overlay is keyed by the installing controller");
assertInstanceOf(ExpiringTimeoutSource.class, chain.seekBy(ExpiringTimeoutSource.class),
"the per-connection MIGRATING/FAILING_OVER window overlay");
assertFalse(ConnectionTestHelper.isRelaxedTimeoutActive(conn), "nothing open yet");
}
@Test
public void perConnectionOverlayCarriesTheConfiguredRelaxedTimeouts() {
controller.register(conn);
ConnectionTestHelper.relaxTimeouts(conn, Duration.ofMinutes(1)); // open the window
assertTrue(ConnectionTestHelper.isRelaxedTimeoutActive(conn));
assertEquals(RELAXED_TIMEOUT_MS, ConnectionTestHelper.getRelaxedSoTimeout(conn));
assertEquals(RELAXED_TIMEOUT_MS, conn.getTimeoutSource().get().timeout);
}
@Test
public void unregisterRemovesBothOverlaysAndTheListener() {
controller.register(conn);
controller.unregister(conn);
assertFalse(conn.getMaintenanceEventListeners().contains(controller));
ChainedTimeoutSource chain = conn.getTimeoutSource();
assertNull(chain.seekBy(controller));
assertNull(chain.seekBy(ExpiringTimeoutSource.class));
assertEquals(SO_TIMEOUT_MS, chain.get().timeout);
}
@Test
public void unregisterPreservesOverlaysInstalledByOthers() {
controller.register(conn);
Object foreignOwner = new Object();
ManagedTimeoutSource foreign = new ManagedTimeoutSource(() -> null, foreignOwner);
conn.getTimeoutSource().addOverride(foreign);
controller.unregister(conn);
assertSame(foreign, conn.getTimeoutSource().seekBy(foreignOwner));
}
}