Skip to content

Commit 9d51794

Browse files
committed
Improve pgbouncer test (#1651)
* Reuse pgBouncer image across builds This will speed up the test when running the test suite locally Signed-off-by: Thomas Segismont <tsegismont@gmail.com> * Increase PgBouncerTest timeout to 5 minutes The test fails intermittently like this on CI: 2026-02-09T10:53:31.9241881Z [ERROR] io.vertx.pgclient.PgBouncerTest.testPreparedBatch -- Time elapsed: 132.0 s <<< ERROR! 2026-02-09T10:53:31.9243012Z java.util.concurrent.TimeoutException 2026-02-09T10:53:31.9243800Z at io.vertx.ext.unit.impl.TestContextImpl.lambda$run$1(TestContextImpl.java:79) 2026-02-09T10:53:31.9244627Z at java.base/java.lang.Thread.run(Thread.java:1474) So let's give it a chance to complete in case the build of the container image and the startup take too long. Signed-off-by: Thomas Segismont <tsegismont@gmail.com> * Manage connections properly in PgBouncerTest Setup connections before each test in setUp method. Close them after each test in tearDown method. Also, use Vert.x Future#await methods for readability. Signed-off-by: Thomas Segismont <tsegismont@gmail.com> --------- Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent eea43ed commit 9d51794

1 file changed

Lines changed: 36 additions & 38 deletions

File tree

vertx-pg-client/src/test/java/io/vertx/pgclient/PgBouncerTest.java

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
1+
/*
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
112
package io.vertx.pgclient;
213

314

415
import io.vertx.core.CompositeFuture;
516
import io.vertx.core.Future;
617
import io.vertx.core.Vertx;
18+
import io.vertx.ext.unit.junit.Timeout;
719
import io.vertx.ext.unit.junit.VertxUnitRunner;
820
import io.vertx.sqlclient.Cursor;
921
import io.vertx.sqlclient.Tuple;
10-
import org.apache.commons.compress.utils.IOUtils;
1122
import org.junit.After;
1223
import org.junit.Before;
24+
import org.junit.Rule;
1325
import org.junit.Test;
1426
import org.junit.runner.RunWith;
1527
import org.testcontainers.Testcontainers;
1628
import org.testcontainers.containers.FixedHostPortGenericContainer;
1729
import org.testcontainers.containers.GenericContainer;
1830
import org.testcontainers.images.builder.ImageFromDockerfile;
19-
import org.testcontainers.images.builder.Transferable;
2031

21-
import java.io.IOException;
22-
import java.io.InputStream;
2332
import java.util.ArrayList;
2433
import java.util.Arrays;
2534
import java.util.List;
@@ -32,13 +41,17 @@
3241
@RunWith(VertxUnitRunner.class)
3342
public class PgBouncerTest {
3443

44+
@Rule
45+
public Timeout timeout = new Timeout(5, TimeUnit.MINUTES);
46+
3547
private FixedHostPortGenericContainer<?> pgContainer;
3648
private GenericContainer<?> pgBouncerContainer;
3749
private Vertx vertx;
3850
private PgConnectOptions options;
51+
private List<PgConnection> connections = new ArrayList<>();
3952

4053
@Before
41-
public void setUp() {
54+
public void setUp() throws Exception {
4255
pgContainer = new FixedHostPortGenericContainer<>("postgres:10.10")
4356
.withFixedExposedPort(5432, 5432);
4457
pgContainer.withEnv("POSTGRES_PASSWORD", "postgres");
@@ -52,8 +65,8 @@ public void setUp() {
5265
Testcontainers.exposeHostPorts(pgPort);
5366

5467
pgBouncerContainer = new GenericContainer<>(
55-
new ImageFromDockerfile()
56-
.withFileFromTransferable("Dockerfile", resourceTransferable("pgBouncer/Dockerfile")))
68+
new ImageFromDockerfile("vertx-pgclient-pg-bouncer", false)
69+
.withFileFromClasspath("Dockerfile", "pgBouncer/Dockerfile"))
5770
.withClasspathResourceMapping("pgBouncer/pgbouncer.ini", "/etc/pgbouncer/pgbouncer.ini", READ_ONLY)
5871
.withClasspathResourceMapping("pgBouncer/userlist.txt", "/etc/pgbouncer/userlist.txt", READ_ONLY)
5972
.withExposedPorts(6432);
@@ -71,68 +84,53 @@ public void setUp() {
7184
.setPipeliningLimit(1);
7285

7386
vertx = Vertx.vertx();
74-
}
7587

76-
private static Transferable resourceTransferable(String resourceName) {
77-
try (InputStream stream = PgBouncerTest.class.getClassLoader().getResourceAsStream(resourceName)) {
78-
assert stream != null;
79-
return Transferable.of(IOUtils.toByteArray(stream));
80-
} catch (IOException e) {
81-
throw new RuntimeException(e);
88+
// Initialize connections for tests
89+
int numConn = 2;
90+
for (int i = 0; i < numConn; i++) {
91+
connections.add(Future.await(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)), 20, TimeUnit.SECONDS));
8292
}
8393
}
8494

8595
@After
8696
public void tearDown() throws Exception {
97+
for (PgConnection conn : connections) {
98+
Future.await(conn.close(), 20, TimeUnit.SECONDS);
99+
}
87100
Testcontainers.exposeHostPorts();
88101
pgBouncerContainer.stop();
89102
pgContainer.stop();
90-
vertx.close().toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
103+
Future.await(vertx.close(), 20, TimeUnit.SECONDS);
91104
}
92105

93106
@Test
94107
public void testPreparedQuery() throws Exception {
95-
List<PgConnection> connections = new ArrayList<>();
96-
int numConn = 2;
97-
for (int i = 0;i < numConn;i++) {
98-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
99-
}
100108
CompositeFuture cf = CompositeFuture.join(connections.stream()
101109
.map(conn -> conn.preparedQuery("select 1").execute().map(rows -> rows.iterator().next().getInteger(0)))
102110
.collect(Collectors.toList()));
103-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
104-
for (int i = 0;i < numConn;i++) {
111+
Future.await(cf, 20, TimeUnit.SECONDS);
112+
for (int i = 0; i < connections.size(); i++) {
105113
assertEquals(1, (cf.<Object>resultAt(i)));
106114
}
107115
}
108116

109117
@Test
110118
public void testPreparedBatch() throws Exception {
111-
List<PgConnection> connections = new ArrayList<>();
112-
int numConn = 2;
113-
for (int i = 0;i < numConn;i++) {
114-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
115-
}
116119
CompositeFuture cf = CompositeFuture.join(connections.stream()
117120
.map(conn -> conn.preparedQuery("select 1")
118121
.executeBatch(Arrays.asList(Tuple.tuple(), Tuple.tuple()))
119122
.map(rows -> rows.iterator().next().getInteger(0)))
120123
.collect(Collectors.toList()));
121-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
122-
for (int i = 0;i < numConn;i++) {
124+
Future.await(cf, 20, TimeUnit.SECONDS);
125+
for (int i = 0; i < connections.size(); i++) {
123126
assertEquals(1, (cf.<Object>resultAt(i)));
124127
}
125128
}
126129

127130
@Test
128131
public void testCursor() throws Exception {
129-
List<PgConnection> connections = new ArrayList<>();
130-
int numConn = 2;
131-
for (int i = 0;i < numConn;i++) {
132-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
133-
}
134132
List<Future> list = new ArrayList<>();
135-
for (int i = 0;i < numConn;i++) {
133+
for (int i = 0; i < connections.size(); i++) {
136134
int val = i;
137135
PgConnection conn = connections.get(i);
138136
list.add(conn
@@ -146,11 +144,11 @@ public void testCursor() throws Exception {
146144
.map(res -> res.iterator().next().getInteger(0))
147145
.eventually(v -> cursor.close())
148146
.eventually(v -> ps.close());
149-
}).eventually(v -> tx.commit())));
147+
}).eventually(v -> tx.commit())));
150148
}
151149
CompositeFuture cf = CompositeFuture.join(list);
152-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
153-
for (int i = 0;i < numConn;i++) {
150+
Future.await(cf, 20, TimeUnit.SECONDS);
151+
for (int i = 0; i < connections.size(); i++) {
154152
assertEquals(i, (cf.<Object>resultAt(i)));
155153
}
156154
}

0 commit comments

Comments
 (0)