Skip to content

Commit 9cfde05

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 cf4a54b commit 9cfde05

File tree

1 file changed

+35
-37
lines changed

1 file changed

+35
-37
lines changed

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

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
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.tests.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.pgclient.PgConnectOptions;
921
import io.vertx.pgclient.PgConnection;
1022
import io.vertx.sqlclient.Cursor;
1123
import io.vertx.sqlclient.Tuple;
12-
import org.apache.commons.compress.utils.IOUtils;
1324
import org.junit.After;
1425
import org.junit.Before;
26+
import org.junit.Rule;
1527
import org.junit.Test;
1628
import org.junit.runner.RunWith;
1729
import org.testcontainers.Testcontainers;
1830
import org.testcontainers.containers.FixedHostPortGenericContainer;
1931
import org.testcontainers.containers.GenericContainer;
2032
import org.testcontainers.images.builder.ImageFromDockerfile;
21-
import org.testcontainers.images.builder.Transferable;
2233

23-
import java.io.IOException;
24-
import java.io.InputStream;
2534
import java.util.ArrayList;
2635
import java.util.Arrays;
2736
import java.util.List;
@@ -34,13 +43,17 @@
3443
@RunWith(VertxUnitRunner.class)
3544
public class PgBouncerTest {
3645

46+
@Rule
47+
public Timeout timeout = new Timeout(5, TimeUnit.MINUTES);
48+
3749
private FixedHostPortGenericContainer<?> pgContainer;
3850
private GenericContainer<?> pgBouncerContainer;
3951
private Vertx vertx;
4052
private PgConnectOptions options;
53+
private List<PgConnection> connections = new ArrayList<>();
4154

4255
@Before
43-
public void setUp() {
56+
public void setUp() throws Exception {
4457
pgContainer = new FixedHostPortGenericContainer<>("postgres:10.10")
4558
.withFixedExposedPort(5432, 5432);
4659
pgContainer.withEnv("POSTGRES_PASSWORD", "postgres");
@@ -54,8 +67,8 @@ public void setUp() {
5467
Testcontainers.exposeHostPorts(pgPort);
5568

5669
pgBouncerContainer = new GenericContainer<>(
57-
new ImageFromDockerfile()
58-
.withFileFromTransferable("Dockerfile", resourceTransferable("pgBouncer/Dockerfile")))
70+
new ImageFromDockerfile("vertx-pgclient-pg-bouncer", false)
71+
.withFileFromClasspath("Dockerfile", "pgBouncer/Dockerfile"))
5972
.withClasspathResourceMapping("pgBouncer/pgbouncer.ini", "/etc/pgbouncer/pgbouncer.ini", READ_ONLY)
6073
.withClasspathResourceMapping("pgBouncer/userlist.txt", "/etc/pgbouncer/userlist.txt", READ_ONLY)
6174
.withExposedPorts(6432);
@@ -73,68 +86,53 @@ public void setUp() {
7386
.setPipeliningLimit(1);
7487

7588
vertx = Vertx.vertx();
76-
}
7789

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

8797
@After
8898
public void tearDown() throws Exception {
99+
for (PgConnection conn : connections) {
100+
conn.close().await(20, TimeUnit.SECONDS);
101+
}
89102
Testcontainers.exposeHostPorts();
90103
pgBouncerContainer.stop();
91104
pgContainer.stop();
92-
vertx.close().toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
105+
vertx.close().await(20, TimeUnit.SECONDS);
93106
}
94107

95108
@Test
96109
public void testPreparedQuery() throws Exception {
97-
List<PgConnection> connections = new ArrayList<>();
98-
int numConn = 2;
99-
for (int i = 0;i < numConn;i++) {
100-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
101-
}
102110
CompositeFuture cf = Future.join(connections.stream()
103111
.map(conn -> conn.preparedQuery("select 1").execute().map(rows -> rows.iterator().next().getInteger(0)))
104112
.collect(Collectors.toList()));
105-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
106-
for (int i = 0;i < numConn;i++) {
113+
cf.await(20, TimeUnit.SECONDS);
114+
for (int i = 0; i < connections.size(); i++) {
107115
assertEquals(1, (cf.<Object>resultAt(i)));
108116
}
109117
}
110118

111119
@Test
112120
public void testPreparedBatch() throws Exception {
113-
List<PgConnection> connections = new ArrayList<>();
114-
int numConn = 2;
115-
for (int i = 0;i < numConn;i++) {
116-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
117-
}
118121
CompositeFuture cf = Future.join(connections.stream()
119122
.map(conn -> conn.preparedQuery("select 1")
120123
.executeBatch(Arrays.asList(Tuple.tuple(), Tuple.tuple()))
121124
.map(rows -> rows.iterator().next().getInteger(0)))
122125
.collect(Collectors.toList()));
123-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
124-
for (int i = 0;i < numConn;i++) {
126+
cf.await(20, TimeUnit.SECONDS);
127+
for (int i = 0; i < connections.size(); i++) {
125128
assertEquals(1, (cf.<Object>resultAt(i)));
126129
}
127130
}
128131

129132
@Test
130133
public void testCursor() throws Exception {
131-
List<PgConnection> connections = new ArrayList<>();
132-
int numConn = 2;
133-
for (int i = 0;i < numConn;i++) {
134-
connections.add(PgConnection.connect(vertx, new PgConnectOptions(options).setUseLayer7Proxy(true)).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS));
135-
}
136134
List<Future<?>> list = new ArrayList<>();
137-
for (int i = 0;i < numConn;i++) {
135+
for (int i = 0; i < connections.size(); i++) {
138136
int val = i;
139137
PgConnection conn = connections.get(i);
140138
list.add(conn
@@ -151,8 +149,8 @@ public void testCursor() throws Exception {
151149
}).eventually(() -> tx.commit())));
152150
}
153151
CompositeFuture cf = Future.join(list);
154-
cf.toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
155-
for (int i = 0;i < numConn;i++) {
152+
cf.await(20, TimeUnit.SECONDS);
153+
for (int i = 0; i < connections.size(); i++) {
156154
assertEquals(i, (cf.<Object>resultAt(i)));
157155
}
158156
}

0 commit comments

Comments
 (0)