package rocks.inspectit.server.influx;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Pong;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.slf4j.Logger;
import org.testng.annotations.Test;
import rocks.inspectit.server.influx.InfluxAvailabilityChecker.InfluxAvailabilityListener;
import rocks.inspectit.shared.all.testbase.TestBase;
/**
*
* Tests the {@link InfluxAvailabilityChecker} class.
*
* @author Marius Oehler
*
*/
public class InfluxAvailabilityCheckerTest extends TestBase {
@InjectMocks
InfluxAvailabilityChecker availabilityChecker;
@Mock
Logger log;
@Mock
InfluxDB influxDb;
@Mock
InfluxAvailabilityListener listener;
@Mock
ScheduledExecutorService executorService;
/**
* Tests the {@link InfluxAvailabilityChecker#activate()} method.
*/
public static class Activate extends InfluxAvailabilityCheckerTest {
@Test
public void activate() {
availabilityChecker.activate();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void activateTwice() {
when(executorService.schedule(any(Runnable.class), any(Long.class), any(TimeUnit.class))).thenReturn(mock(ScheduledFuture.class));
availabilityChecker.activate();
availabilityChecker.activate();
verify(executorService, times(1)).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void activateAfterDeactivation() {
ScheduledFuture scheduledFuture = mock(ScheduledFuture.class);
when(scheduledFuture.isDone()).thenReturn(false, true);
when(executorService.schedule(any(Runnable.class), any(Long.class), any(TimeUnit.class))).thenReturn(scheduledFuture);
availabilityChecker.activate();
availabilityChecker.deactivate();
availabilityChecker.activate();
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(scheduledFuture, times(2)).isDone();
verify(scheduledFuture).cancel(false);
verifyNoMoreInteractions(scheduledFuture);
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
}
}
/**
* Tests the {@link InfluxAvailabilityChecker#deactivate()} method.
*/
public static class Deactivate extends InfluxAvailabilityCheckerTest {
@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
public void cancelFuture() {
ScheduledFuture scheduledFuture = mock(ScheduledFuture.class);
when(scheduledFuture.isDone()).thenReturn(false);
when(executorService.schedule(any(Runnable.class), any(Long.class), any(TimeUnit.class))).thenReturn(scheduledFuture);
availabilityChecker.activate();
availabilityChecker.deactivate();
verify(executorService, times(1)).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(scheduledFuture).isDone();
verify(scheduledFuture).cancel(false);
verifyNoMoreInteractions(scheduledFuture);
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
public void futureNull() {
availabilityChecker.deactivate();
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
verifyZeroInteractions(executorService);
}
@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
public void futureIsDone() {
ScheduledFuture scheduledFuture = mock(ScheduledFuture.class);
when(scheduledFuture.isDone()).thenReturn(true);
when(executorService.schedule(any(Runnable.class), any(Long.class), any(TimeUnit.class))).thenReturn(scheduledFuture);
availabilityChecker.activate();
availabilityChecker.deactivate();
verify(scheduledFuture).isDone();
verify(executorService, times(1)).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verifyNoMoreInteractions(scheduledFuture);
verifyZeroInteractions(influxDb);
verifyZeroInteractions(listener);
}
}
/**
* Tests the {@link InfluxAvailabilityChecker#run()} method.
*/
public static class Run extends InfluxAvailabilityCheckerTest {
@Test
public void isAvailable() {
availabilityChecker.activate();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb).ping();
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void isNotAvailable() {
availabilityChecker.activate();
when(influxDb.ping()).thenThrow(Exception.class);
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb).ping();
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
public void isAvailableAndWasAvailable() {
availabilityChecker.activate();
availabilityChecker.run();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void isAvailableAndWasNotAvailable() {
availabilityChecker.activate();
when(influxDb.ping()).thenThrow(Exception.class).thenReturn(mock(Pong.class));
availabilityChecker.run();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(15L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verify(listener).onReconnection();
verifyNoMoreInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void isNotAvailableAndWasAvailable() {
availabilityChecker.activate();
when(influxDb.ping()).thenReturn(mock(Pong.class)).thenThrow(Exception.class);
availabilityChecker.run();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verify(listener).onDisconnection();
verifyNoMoreInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void isNotAvailableAndWasNotAvailable() {
availabilityChecker.activate();
when(influxDb.ping()).thenThrow(Exception.class);
availabilityChecker.run();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(15L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void resetExecutionDelay() {
availabilityChecker.activate();
when(influxDb.ping()).thenThrow(Exception.class).thenThrow(Exception.class).thenThrow(Exception.class).thenThrow(Exception.class).thenThrow(Exception.class).thenReturn(mock(Pong.class));
availabilityChecker.run(); // 15 delay
availabilityChecker.run(); // 30 delay
availabilityChecker.run(); // 60 delay
availabilityChecker.run(); // 600 delay
availabilityChecker.run(); // 600 delay
availabilityChecker.run(); // 5 delay
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(15L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(30L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(60L), any(TimeUnit.class));
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(120L), any(TimeUnit.class));
verify(executorService).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(6)).ping();
verifyNoMoreInteractions(influxDb);
verify(listener).onReconnection();
verifyNoMoreInteractions(listener);
}
@Test
@SuppressWarnings("unchecked")
public void unexcpectedException() {
availabilityChecker.activate();
when(influxDb.ping()).thenThrow(Exception.class).thenReturn(mock(Pong.class));
doThrow(RuntimeException.class).when(listener).onReconnection();
availabilityChecker.run();
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verify(listener).onReconnection();
verifyNoMoreInteractions(listener);
}
@Test
public void influxIsNull() {
availabilityChecker.activate();
availabilityChecker.setInflux(null);
availabilityChecker.run();
verify(executorService).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService, times(1)).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
verifyZeroInteractions(influxDb);
}
@Test
public void isNotActive() {
availabilityChecker.run();
verify(influxDb).ping();
verifyNoMoreInteractions(influxDb);
verifyZeroInteractions(listener);
verifyZeroInteractions(executorService);
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void stateChangedAfterReactivation() {
when(influxDb.ping()).thenReturn(mock(Pong.class)).thenThrow(Exception.class);
ScheduledFuture scheduledFuture = mock(ScheduledFuture.class);
when(scheduledFuture.isDone()).thenReturn(false, true);
when(executorService.schedule(any(Runnable.class), any(Long.class), any(TimeUnit.class))).thenReturn(scheduledFuture);
availabilityChecker.activate();
availabilityChecker.run();
availabilityChecker.deactivate();
availabilityChecker.activate();
availabilityChecker.run();
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(0L), any(TimeUnit.class));
verify(executorService, times(2)).schedule(eq(availabilityChecker), eq(5L), any(TimeUnit.class));
verifyNoMoreInteractions(executorService);
verify(influxDb, times(2)).ping();
verifyNoMoreInteractions(influxDb);
verify(scheduledFuture, times(2)).isDone();
verify(scheduledFuture).cancel(false);
verifyNoMoreInteractions(scheduledFuture);
verifyZeroInteractions(listener);
}
}
}