package io.vertx.ext.jdbc; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.metrics.MetricsOptions; import io.vertx.core.metrics.impl.DummyVertxMetrics; import io.vertx.core.spi.VertxMetricsFactory; import io.vertx.core.spi.metrics.PoolMetrics; import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.ext.sql.SQLClient; import io.vertx.test.core.VertxTestBase; import io.vertx.test.fakemetrics.FakePoolMetrics; import org.junit.Test; import javax.sql.DataSource; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; /** * @author <a href="mailto:julien@julienviet.com">Julien Viet</a> */ public class JDBCPoolMetricsTest extends VertxTestBase { private SQLClient client; private FakePoolMetrics metrics; public void after() throws Exception { if (client != null) { client.close(); } super.after(); } private SQLClient getClient() { if (client == null) { Map<String, PoolMetrics> metricsMap = FakePoolMetrics.getPoolMetrics(); Set<String> keys = new HashSet<>(metricsMap.keySet()); client = JDBCClient.createNonShared(vertx, JDBCClientTestBase.config(). put("max_pool_size", 10)); Set<String> after = new HashSet<>(metricsMap.keySet()); after.removeAll(keys); metrics = (FakePoolMetrics) metricsMap.get(after.iterator().next()); } return client; } @Override protected VertxOptions getOptions() { MetricsOptions options = new MetricsOptions().setEnabled(true); options.setFactory(new VertxMetricsFactory() { @Override public VertxMetrics metrics(Vertx vertx, VertxOptions options) { return new DummyVertxMetrics() { @Override public boolean isEnabled() { return true; } @Override public <P> PoolMetrics<?> createMetrics(P pool, String poolType, String poolName, int maxPoolSize) { if (pool instanceof DataSource) { assertEquals("datasource", poolType); return new FakePoolMetrics(poolName, maxPoolSize); } else { return super.createMetrics(pool, poolType, poolName, maxPoolSize); } } }; } }); return new VertxOptions().setMetricsOptions(options); } @Test public void testLifecycle() { Map<String, PoolMetrics> metricsMap = FakePoolMetrics.getPoolMetrics(); assertEquals(Collections.emptySet(), metricsMap.keySet()); client = getClient(); assertEquals(1, metricsMap.size()); assertEquals(10, metrics.getPoolSize()); client.close(); client = null; assertEquals(0, metricsMap.size()); } @Test public void testUseConnection() { client = getClient(); client.getConnection(onSuccess(conn -> { assertEquals(0, metrics.numberOfWaitingTasks()); assertEquals(1, metrics.numberOfRunningTasks()); conn.close(onSuccess(v -> { assertEquals(0, metrics.numberOfWaitingTasks()); assertEquals(0, metrics.numberOfRunningTasks()); testComplete(); })); })); await(); } @Test public void testQueue() throws Exception { client = getClient(); CompletableFuture<Void> close = new CompletableFuture<>(); AtomicInteger closedCount = new AtomicInteger(); CountDownLatch closedLatch = new CountDownLatch(11); for (int i = 0;i < 11;i++) { client.getConnection(onSuccess(conn -> { close.thenAccept(v -> { conn.close(ar -> { closedCount.decrementAndGet(); closedLatch.countDown(); }); }); })); } assertWaitUntil(() -> metrics.numberOfRunningTasks() == 10 && metrics.numberOfWaitingTasks() == 1); close.complete(null); awaitLatch(closedLatch); assertEquals(0, metrics.numberOfWaitingTasks()); assertEquals(0, metrics.numberOfRunningTasks()); } }