Skip to content

Commit 6fd8a9f

Browse files
committed
Speed up DB2 client tests (#1655)
This commit modernizes the DB2 client test infrastructure by: - upgrading to the community image icr.io/db2_community/db2:12.1.4.0 - eliminating the JDBC driver dependency - removing z/OS *testing* support (not possible in containerized environments) Also, a lot of NPE were logged because the DB2SocketConnection#closeHandler was always invoked even if not set. With all these changes, on my box, the DB2 client build passes in 3-4 minutes instead of 7-8 minutes. Some portions of this content were created with the assistance of IBM Bob. Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent f245c27 commit 6fd8a9f

File tree

15 files changed

+146
-358
lines changed

15 files changed

+146
-358
lines changed

.github/workflows/ci-4.x.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ jobs:
5656
module: 'vertx-mssql-client'
5757
- os: ubuntu-latest
5858
jdk: 8
59-
profile: 'DB2-11.5'
6059
module: 'vertx-db2-client'
6160
- os: ubuntu-latest
6261
jdk: 8

vertx-db2-client/pom.xml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,10 @@
5656
<!-- Testing purposes -->
5757
<dependency>
5858
<groupId>org.testcontainers</groupId>
59-
<artifactId>db2</artifactId>
59+
<artifactId>testcontainers</artifactId>
6060
<version>${testcontainers.version}</version>
6161
<scope>test</scope>
6262
</dependency>
63-
<dependency>
64-
<groupId>com.ibm.db2</groupId>
65-
<artifactId>jcc</artifactId>
66-
<version>11.1.4.4</version>
67-
<scope>test</scope>
68-
</dependency>
6963
<!-- SLF4J API for test code and Testcontainers -->
7064
<dependency>
7165
<groupId>org.slf4j</groupId>

vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2SocketConnection.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
/*
2-
* Copyright (C) 2019,2020 IBM Corporation
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
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.
78
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
1510
*/
1611
package io.vertx.db2client.impl;
1712

@@ -101,7 +96,9 @@ protected <R> void doSchedule(CommandBase<R> cmd, Handler<AsyncResult<R>> handle
10196
@Override
10297
public void handleClose(Throwable t) {
10398
super.handleClose(t);
104-
context().runOnContext(closeHandler);
99+
if (closeHandler != null) {
100+
context().runOnContext(closeHandler);
101+
}
105102
}
106103

107104
@Override

vertx-db2-client/src/test/java/io/vertx/db2client/DB2DataTypeTest.java

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
/*
2-
* Copyright (C) 2020 IBM Corporation
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
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.
78
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
1510
*/
1611
package io.vertx.db2client;
1712

@@ -32,8 +27,6 @@
3227
import java.util.List;
3328
import java.util.UUID;
3429

35-
import static org.junit.Assume.assumeTrue;
36-
3730
@RunWith(VertxUnitRunner.class)
3831
public class DB2DataTypeTest extends DB2TestBase {
3932

@@ -196,29 +189,6 @@ public void testUUID(TestContext ctx) {
196189
}));
197190
}
198191

199-
@Test
200-
public void testRowId(TestContext ctx) {
201-
assumeTrue("Only DB2/Z supports the ROWID column type", rule.isZOS());
202-
203-
final String msg = "insert data for testRowId";
204-
connect(ctx.asyncAssertSuccess(conn -> {
205-
// Insert some data
206-
conn.preparedQuery("INSERT INTO ROWTEST (message) VALUES ('" + msg + "')")
207-
.execute(ctx.asyncAssertSuccess(insertResult -> {
208-
// Find it by msg
209-
conn.preparedQuery("SELECT * FROM ROWTEST WHERE message = '" + msg + "'")
210-
.execute(ctx.asyncAssertSuccess(rows -> {
211-
RowId rowId = verifyRowId(ctx, rows, msg);
212-
// Now find it by rowid
213-
conn.preparedQuery("SELECT * FROM ROWTEST WHERE id = ?")
214-
.execute(Tuple.of(rowId), ctx.asyncAssertSuccess(rows2 -> {
215-
verifyRowId(ctx, rows2, msg);
216-
}));
217-
}));
218-
}));
219-
}));
220-
}
221-
222192
/**
223193
* Test to support using enum string values in the Row and Tuple methods.
224194
*/

vertx-db2-client/src/test/java/io/vertx/db2client/QueryVariationsTest.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1-
package io.vertx.db2client;
2-
3-
import static org.junit.Assume.assumeFalse;
4-
5-
import java.util.Arrays;
6-
import java.util.function.Consumer;
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+
*/
711

8-
import org.junit.Test;
9-
import org.junit.runner.RunWith;
12+
package io.vertx.db2client;
1013

1114
import io.vertx.ext.unit.TestContext;
1215
import io.vertx.ext.unit.junit.VertxUnitRunner;
1316
import io.vertx.sqlclient.Row;
1417
import io.vertx.sqlclient.RowIterator;
1518
import io.vertx.sqlclient.RowSet;
1619
import io.vertx.sqlclient.Tuple;
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
23+
import java.util.Arrays;
24+
import java.util.function.Consumer;
1725

1826
/**
1927
* Tests for subqueries which are documented here:
@@ -171,8 +179,6 @@ public void testSectionReuse(TestContext ctx) {
171179
*/
172180
@Test
173181
public void testSequenceQuery(TestContext ctx) {
174-
assumeFalse("TODO: Sequences behave differently on DB2/z and need to be implemented properly", rule.isZOS());
175-
176182
connect(ctx.asyncAssertSuccess(con -> {
177183
con.query("values nextval for my_seq")
178184
.execute(ctx.asyncAssertSuccess(rowSet1 -> {
@@ -199,8 +205,6 @@ public void testSequenceQuery(TestContext ctx) {
199205
*/
200206
@Test
201207
public void testSequenceQueryPrepared(TestContext ctx) {
202-
assumeFalse("TODO: Sequences behave differently on DB2/z and need to be implemented properly", rule.isZOS());
203-
204208
connect(ctx.asyncAssertSuccess(con -> {
205209
con.preparedQuery("VALUES nextval for my_seq")
206210
.execute(ctx.asyncAssertSuccess(rowSet1 -> {
@@ -221,7 +225,7 @@ public void testSequenceQueryPrepared(TestContext ctx) {
221225
}));
222226
}));
223227
}
224-
228+
225229
/**
226230
* Test comment in query
227231
*/

vertx-db2-client/src/test/java/io/vertx/db2client/TableJoinTest.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
package io.vertx.db2client;
2-
3-
import static org.junit.Assume.assumeFalse;
4-
5-
import java.util.Arrays;
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+
*/
611

7-
import org.junit.Test;
8-
import org.junit.runner.RunWith;
12+
package io.vertx.db2client;
913

1014
import io.vertx.ext.unit.TestContext;
1115
import io.vertx.ext.unit.junit.VertxUnitRunner;
1216
import io.vertx.sqlclient.Row;
17+
import org.junit.Test;
18+
import org.junit.runner.RunWith;
19+
20+
import java.util.Arrays;
1321

1422
/**
1523
* Tests for table joins which are documented here:
@@ -80,7 +88,6 @@ public void testRightOuterJoin(TestContext ctx) {
8088

8189
@Test
8290
public void testFullOuterJoin(TestContext ctx) {
83-
assumeFalse("DB2 on Z does not support operations within ON clause for FULL OUTER JOIN", rule.isZOS());
8491
testJoin(ctx, "FULL OUTER JOIN");
8592
}
8693

vertx-db2-client/src/test/java/io/vertx/db2client/junit/DB2Resource.java

Lines changed: 52 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -10,68 +10,76 @@
1010
*/
1111
package io.vertx.db2client.junit;
1212

13+
import com.github.dockerjava.api.model.Capability;
14+
import io.netty.util.internal.PlatformDependent;
1315
import io.vertx.core.net.JksOptions;
1416
import io.vertx.db2client.DB2ConnectOptions;
1517
import org.junit.rules.ExternalResource;
1618
import org.slf4j.Logger;
1719
import org.slf4j.LoggerFactory;
18-
import org.testcontainers.containers.Db2Container;
20+
import org.testcontainers.containers.BindMode;
21+
import org.testcontainers.containers.GenericContainer;
1922
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
2023

21-
import java.nio.file.Files;
22-
import java.nio.file.Path;
23-
import java.nio.file.Paths;
24-
import java.sql.Connection;
25-
import java.sql.DriverManager;
26-
import java.sql.SQLSyntaxErrorException;
2724
import java.time.Duration;
2825
import java.util.Objects;
2926

3027
public class DB2Resource extends ExternalResource {
3128

32-
private static final Logger logger = LoggerFactory.getLogger(DB2Resource.class);
29+
private static final Logger logger = LoggerFactory.getLogger(DB2Resource.class);
3330

34-
private static final boolean CUSTOM_DB2 = get("DB2_HOST") != null;
31+
private static final boolean CUSTOM_DB2 = get("DB2_HOST") != null;
3532

36-
/**
37-
* In order for this container to be reused across test runs you need to add the line:
38-
* <code>testcontainers.reuse.enable=true</code> to your <code>~/.testcontainers.properties</code>
39-
* file (create it if it does not exist)
40-
*/
41-
public static final DB2Resource SHARED_INSTANCE = new DB2Resource();
33+
public static final DB2Resource SHARED_INSTANCE = new DB2Resource();
4234

43-
private boolean started = false;
44-
private boolean isDb2OnZ = false;
45-
private DB2ConnectOptions options;
46-
private final Db2Container instance = new Db2Container("ibmcom/db2:11.5.0.0a")
47-
.acceptLicense()
48-
.withLogConsumer(out -> logger.debug("[DB2] {}", out.getUtf8String()))
49-
.withUsername("vertx")
50-
.withPassword("vertx")
51-
.withDatabaseName("vertx")
52-
.withExposedPorts(50000, 50001)
53-
.withFileSystemBind("src/test/resources/tls/server/", "/certs/")
54-
.withFileSystemBind("src/test/resources/tls/db2_tls_setup.sh", "/var/custom/db2_tls_setup.sh")
55-
.waitingFor(new LogMessageWaitStrategy()
56-
.withRegEx(".*VERTX SSH SETUP DONE.*")
57-
.withStartupTimeout(Duration.ofMinutes(10)))
58-
.withReuse(true);
35+
private boolean started = false;
36+
private DB2ConnectOptions options;
37+
private final GenericContainer instance = new GenericContainer<>("icr.io/db2_community/db2:12.1.4.0")
38+
.withCreateContainerCmdModifier(cmd -> cmd
39+
.withCapAdd(Capability.IPC_LOCK)
40+
.withCapAdd(Capability.IPC_OWNER))
41+
.withEnv("LICENSE", "accept")
42+
.withEnv("DB2INSTANCE", "vertx")
43+
.withEnv("DB2INST1_PASSWORD", "vertx")
44+
.withEnv("DBNAME", "vertx")
45+
.withEnv("BLU", "false")
46+
.withEnv("ENABLE_ORACLE_COMPATIBILITY", "false")
47+
.withEnv("UPDATEAVAIL", "NO")
48+
.withEnv("TO_CREATE_SAMPLEDB", "false")
49+
.withEnv("REPODB", "false")
50+
.withEnv("IS_OSXFS", String.valueOf(PlatformDependent.isOsx()))
51+
.withEnv("PERSISTENT_HOME", "true")
52+
.withEnv("HADR_ENABLED", "false")
53+
.withEnv("ETCD_ENDPOINT", "")
54+
.withEnv("ETCD_USERNAME", "")
55+
.withEnv("ETCD_PASSWORD", "")
56+
.withEnv("AUTOCONFIG", "false")
57+
.withEnv("ARCHIVE_LOGS", "false")
58+
.withExposedPorts(50000, 50001)
59+
.withClasspathResourceMapping("tls/server/", "/certs/", BindMode.READ_ONLY)
60+
.withClasspathResourceMapping("tls/01-db2_tls_setup.sh", "/var/custom/01-db2_tls_setup.sh", BindMode.READ_ONLY)
61+
.withClasspathResourceMapping("init.sql", "/tmp/init.sql", BindMode.READ_ONLY)
62+
.withClasspathResourceMapping("02-init-db.sh", "/var/custom/02-init-db.sh", BindMode.READ_ONLY)
63+
.withLogConsumer(out -> logger.debug("[DB2] {}", out.getUtf8String()))
64+
.waitingFor(new LogMessageWaitStrategy()
65+
.withRegEx(".*DB2 DATABASE INITIALIZATION COMPLETE.*")
66+
.withStartupTimeout(Duration.ofMinutes(10)));
5967

60-
@Override
61-
protected void before() throws Throwable {
62-
if (started)
63-
return;
68+
@Override
69+
protected void before() throws Throwable {
70+
if (started)
71+
return;
6472

65-
if (!CUSTOM_DB2) {
66-
instance.start();
73+
if (!CUSTOM_DB2) {
74+
instance.start();
6775
options = new DB2ConnectOptions()
68-
.setHost(instance.getContainerIpAddress())
69-
.setPort(instance.getMappedPort(50000))
70-
.setDatabase(instance.getDatabaseName())
71-
.setUser(instance.getUsername())
72-
.setPassword(instance.getPassword());
76+
.setHost(instance.getHost())
77+
.setPort(instance.getMappedPort(50000))
78+
.setDatabase("vertx")
79+
.setUser("vertx")
80+
.setPassword("vertx");
7381
} else {
74-
logger.info("Using custom DB2 instance as requested via DB2_HOST={}", get("DB2_HOST"));
82+
logger.info("Using custom DB2 instance as requested via DB2_HOST={}", get("DB2_HOST"));
7583
Objects.requireNonNull(get("DB2_PORT"), "Must set DB2_PORT to a non-null value if DB2_HOST is set");
7684
Objects.requireNonNull(get("DB2_NAME"), "Must set DB2_NAME to a non-null value if DB2_HOST is set");
7785
Objects.requireNonNull(get("DB2_USER"), "Must set DB2_USER to a non-null value if DB2_HOST is set");
@@ -82,11 +90,7 @@ protected void before() throws Throwable {
8290
.setDatabase(get("DB2_NAME"))
8391
.setUser(get("DB2_USER"))
8492
.setPassword(get("DB2_PASS"));
85-
}
86-
String jdbcUrl = "jdbc:db2://" + options.getHost() + ":" + options.getPort() + "/" + options.getDatabase();
87-
logger.info("Initializing DB2 database at: {}", jdbcUrl);
88-
try (Connection con = DriverManager.getConnection(jdbcUrl, options.getUser(), options.getPassword())) {
89-
runInitSql(con);
93+
logger.info("Custom DB2 instance must be manually initialized with init.sql");
9094
}
9195
started = true;
9296
}
@@ -105,40 +109,8 @@ public DB2ConnectOptions secureOptions() {
105109
.setPassword("db2test"));
106110
}
107111

108-
public boolean isZOS() {
109-
return isDb2OnZ;
110-
}
111-
112112
private static String get(String name) {
113113
return System.getProperty(name, System.getenv(name));
114114
}
115115

116-
private void runInitSql(Connection con) throws Exception {
117-
isDb2OnZ = con.getMetaData().getDatabaseProductVersion().startsWith("DSN");
118-
String currentLine = "";
119-
Path initScript = Paths.get("src", "test", "resources", isDb2OnZ ? "init.zos.sql" : "init.sql");
120-
logger.info("Running init script at: {}", initScript);
121-
for (String sql : Files.readAllLines(initScript)) {
122-
if (sql.startsWith("--"))
123-
continue;
124-
currentLine += sql;
125-
if (sql.endsWith(";")) {
126-
logger.debug(" {}", currentLine);
127-
try {
128-
con.createStatement().execute(currentLine);
129-
} catch (SQLSyntaxErrorException e) {
130-
if (sql.startsWith("DROP ") && e.getErrorCode() == -204) {
131-
logger.debug(" ignoring syntax exception: {}", e.getMessage());
132-
} else {
133-
throw e;
134-
}
135-
}
136-
currentLine = "";
137-
}
138-
}
139-
if (!currentLine.isEmpty()) {
140-
throw new IllegalStateException("Dangling SQL on init script. Ensure all statements are terminated with ';' char. SQL: " + currentLine);
141-
}
142-
}
143-
144116
}

0 commit comments

Comments
 (0)