package com.vladmihalcea.flexypool.strategy;
import com.vladmihalcea.flexypool.adaptor.PoolAdapter;
import com.vladmihalcea.flexypool.adaptor.PoolAdapterFactory;
import com.vladmihalcea.flexypool.config.Configuration;
import com.vladmihalcea.flexypool.connection.ConnectionRequestContext;
import com.vladmihalcea.flexypool.exception.AcquireTimeoutException;
import com.vladmihalcea.flexypool.metric.Histogram;
import com.vladmihalcea.flexypool.metric.Metrics;
import com.vladmihalcea.flexypool.metric.MetricsFactory;
import com.vladmihalcea.flexypool.common.ConfigurationProperties;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import static org.junit.Assert.*;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.*;
/**
* RetryConnectionAcquiringStrategyTest - RetryConnectionAcquiringStrategy Test
*
* @author Vlad Mihalcea
*/
public class RetryConnectionAcquiringStrategyTest {
@Mock
private DataSource dataSource;
@Mock
private PoolAdapter<DataSource> poolAdapter;
@Mock
private Connection connection;
@Mock
private Metrics metrics;
@Mock
private Histogram histogram;
private Configuration<DataSource> configuration;
private ConnectionRequestContext connectionRequestContext;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
configuration = new Configuration.Builder<DataSource>(
getClass().getName(),
dataSource,
new PoolAdapterFactory<DataSource>() {
@Override
public PoolAdapter<DataSource> newInstance(ConfigurationProperties<DataSource, Metrics, PoolAdapter<DataSource>> configurationProperties) {
return poolAdapter;
}
}
)
.setMetricsFactory(new MetricsFactory() {
@Override
public Metrics newInstance(ConfigurationProperties configurationProperties) {
return metrics;
}
})
.build();
when(metrics.histogram(RetryConnectionAcquiringStrategy.RETRY_ATTEMPTS_HISTOGRAM)).thenReturn(histogram);
connectionRequestContext = new ConnectionRequestContext.Builder().build();
when(poolAdapter.getTargetDataSource()).thenReturn(dataSource);
}
@Test
public void testInvalidRetryAttempts() {
try {
new RetryConnectionAcquiringStrategy.Factory<DataSource>(0).newInstance(configuration);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertEquals("retryAttempts must ge greater than 0!", e.getMessage());
}
}
@Test
public void testConnectionAcquiredInOneAttempt() throws SQLException {
when(poolAdapter.getConnection(same(connectionRequestContext))).thenReturn(connection);
RetryConnectionAcquiringStrategy retryConnectionAcquiringStrategy = new RetryConnectionAcquiringStrategy.Factory<DataSource>(5).newInstance(configuration);
assertEquals(0, connectionRequestContext.getRetryAttempts());
assertSame(connection, retryConnectionAcquiringStrategy.getConnection(connectionRequestContext));
assertEquals(0, connectionRequestContext.getRetryAttempts());
verify(histogram, never()).update(anyInt());
}
@Test
public void testConnectionAcquiredInTwoAttempts() throws SQLException {
when(poolAdapter.getConnection(same(connectionRequestContext)))
.thenThrow(new AcquireTimeoutException(new Exception()))
.thenReturn(connection);
RetryConnectionAcquiringStrategy retryConnectionAcquiringStrategy = new RetryConnectionAcquiringStrategy.Factory<DataSource>(5).newInstance(configuration);
assertEquals(0, connectionRequestContext.getRetryAttempts());
assertSame(connection, retryConnectionAcquiringStrategy.getConnection(connectionRequestContext));
assertEquals(1, connectionRequestContext.getRetryAttempts());
verify(histogram, times(1)).update(1);
}
@Test
public void testConnectionNotAcquiredAfterAllAttempts() throws SQLException {
Exception rootException = new Exception();
when(poolAdapter.getConnection(same(connectionRequestContext)))
.thenThrow(new AcquireTimeoutException(rootException));
RetryConnectionAcquiringStrategy retryConnectionAcquiringStrategy = new RetryConnectionAcquiringStrategy.Factory<DataSource>(2).newInstance(configuration);
assertEquals(0, connectionRequestContext.getRetryAttempts());
try {
retryConnectionAcquiringStrategy.getConnection(connectionRequestContext);
} catch (AcquireTimeoutException e) {
assertSame(rootException, e.getCause());
}
assertEquals(2, connectionRequestContext.getRetryAttempts());
verify(histogram, times(1)).update(2);
}
}