Skip to content

Commit fa8b95c

Browse files
committed
DATAJDBC-257 - Polishing.
Move container initialization from static initializer into createDataSource() to not trigger container start when loading the class. Add TestExecutionListener to ignore tests if the license for a container was not accepted. Add Awaitility to delay test execution until the database is ready so we avoid strange failures due to a delayed container startup. Fix generics, since tags, author tags. Reformat code. Original pull request: #213.
1 parent 4bf2b8d commit fa8b95c

File tree

11 files changed

+187
-46
lines changed

11 files changed

+187
-46
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
<degraph-check.version>0.1.4</degraph-check.version>
2727

28+
<awaitility.version>4.0.2</awaitility.version>
2829
<db2.version>11.5.0.0</db2.version>
2930
<h2.version>1.4.200</h2.version>
3031
<hsqldb.version>2.2.8</hsqldb.version>

spring-data-jdbc/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@
151151
<scope>test</scope>
152152
</dependency>
153153

154+
<dependency>
155+
<groupId>org.awaitility</groupId>
156+
<artifactId>awaitility</artifactId>
157+
<version>${awaitility.version}</version>
158+
<scope>test</scope>
159+
</dependency>
160+
154161
<dependency>
155162
<groupId>org.assertj</groupId>
156163
<artifactId>assertj-core</artifactId>
@@ -190,6 +197,7 @@
190197
<groupId>com.ibm.db2</groupId>
191198
<artifactId>jcc</artifactId>
192199
<version>11.1.4.4</version>
200+
<scope>test</scope>
193201
</dependency>
194202

195203
<dependency>

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/Db2DataSourceConfiguration.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,35 @@
1515
*/
1616
package org.springframework.data.jdbc.testing;
1717

18+
import java.sql.Connection;
19+
import java.sql.SQLException;
20+
1821
import javax.sql.DataSource;
1922

23+
import org.apache.commons.logging.Log;
24+
import org.apache.commons.logging.LogFactory;
25+
import org.awaitility.Awaitility;
26+
2027
import org.springframework.context.annotation.Configuration;
2128
import org.springframework.context.annotation.Profile;
2229
import org.springframework.jdbc.datasource.DriverManagerDataSource;
2330
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
31+
2432
import org.testcontainers.containers.Db2Container;
2533

2634
/**
2735
* {@link DataSource} setup for DB2.
2836
*
2937
* @author Jens Schauder
30-
* @author Oliver Gierke
38+
* @author Mark Paluch
3139
*/
3240
@Configuration
3341
@Profile("db2")
3442
class Db2DataSourceConfiguration extends DataSourceConfiguration {
3543

36-
private static final Db2Container DB_2_CONTAINER = new Db2Container();
44+
private static final Log LOG = LogFactory.getLog(Db2DataSourceConfiguration.class);
3745

38-
static {
39-
DB_2_CONTAINER.start();
40-
}
46+
private static Db2Container DB_2_CONTAINER;
4147

4248
/*
4349
* (non-Javadoc)
@@ -46,12 +52,38 @@ class Db2DataSourceConfiguration extends DataSourceConfiguration {
4652
@Override
4753
protected DataSource createDataSource() {
4854

55+
if (DB_2_CONTAINER == null) {
56+
57+
LOG.info("DB2 starting...");
58+
Db2Container container = new Db2Container();
59+
container.start();
60+
LOG.info("DB2 started");
61+
62+
DB_2_CONTAINER = container;
63+
}
64+
4965
DriverManagerDataSource dataSource = new DriverManagerDataSource(DB_2_CONTAINER.getJdbcUrl(),
5066
DB_2_CONTAINER.getUsername(), DB_2_CONTAINER.getPassword());
5167

68+
// DB2 container says its ready but it's like with a cat that denies service and still wants food although it had
69+
// its food. Therefore, we make sure that we can properly establish a connection instead of trusting the cat
70+
// ...err... DB2.
71+
Awaitility.await().ignoreException(SQLException.class).until(() -> {
72+
73+
try (Connection connection = dataSource.getConnection()) {
74+
return true;
75+
}
76+
});
77+
78+
LOG.info("DB2 connectivity verified");
79+
5280
return dataSource;
5381
}
5482

83+
/*
84+
* (non-Javadoc)
85+
* @see org.springframework.data.jdbc.testing.customizePopulator#createDataSource(org.springframework.jdbc.datasource.init.ResourceDatabasePopulator)
86+
*/
5587
@Override
5688
protected void customizePopulator(ResourceDatabasePopulator populator) {
5789
populator.setIgnoreFailedDrops(true);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
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
7+
*
8+
* https://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.
15+
*/
16+
package org.springframework.data.jdbc.testing;
17+
18+
import org.junit.AssumptionViolatedException;
19+
20+
import org.springframework.core.annotation.Order;
21+
import org.springframework.core.env.Profiles;
22+
import org.springframework.core.env.StandardEnvironment;
23+
import org.springframework.test.context.TestContext;
24+
import org.springframework.test.context.TestExecutionListener;
25+
26+
import org.testcontainers.containers.Db2Container;
27+
import org.testcontainers.containers.MSSQLServerContainer;
28+
import org.testcontainers.utility.LicenseAcceptance;
29+
30+
/**
31+
* {@link TestExecutionListener} to selectively skip tests if the license for a particular database container was not
32+
* accepted.
33+
*
34+
* @author Mark Paluch
35+
*/
36+
@Order(Integer.MIN_VALUE)
37+
public class LicenseListener implements TestExecutionListener {
38+
39+
@Override
40+
public void prepareTestInstance(TestContext testContext) {
41+
42+
StandardEnvironment environment = new StandardEnvironment();
43+
44+
if (environment.acceptsProfiles(Profiles.of("db2"))) {
45+
assumeLicenseAccepted(Db2Container.DEFAULT_DB2_IMAGE_NAME + ":" + Db2Container.DEFAULT_TAG);
46+
}
47+
48+
if (environment.acceptsProfiles(Profiles.of("mssql"))) {
49+
assumeLicenseAccepted(MSSQLServerContainer.IMAGE + ":" + MSSQLServerContainer.DEFAULT_TAG);
50+
}
51+
}
52+
53+
private static void assumeLicenseAccepted(String imageName) {
54+
55+
try {
56+
LicenseAcceptance.assertLicenseAccepted(imageName);
57+
} catch (IllegalStateException e) {
58+
throw new AssumptionViolatedException(e.getMessage());
59+
}
60+
}
61+
62+
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/MariaDBDataSourceConfiguration.java

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,32 @@
1515
*/
1616
package org.springframework.data.jdbc.testing;
1717

18+
import java.sql.Connection;
1819
import java.sql.SQLException;
1920

2021
import javax.annotation.PostConstruct;
21-
import javax.script.ScriptException;
2222
import javax.sql.DataSource;
2323

2424
import org.mariadb.jdbc.MariaDbDataSource;
25+
2526
import org.springframework.context.annotation.Configuration;
2627
import org.springframework.context.annotation.Profile;
28+
import org.springframework.core.io.ByteArrayResource;
29+
import org.springframework.jdbc.datasource.init.ScriptUtils;
30+
2731
import org.testcontainers.containers.MariaDBContainer;
28-
import org.testcontainers.jdbc.ext.ScriptUtils;
2932

3033
/**
3134
* {@link DataSource} setup for MariaDB. Starts a Docker-container with a MariaDB database, and sets up database "test".
3235
*
3336
* @author Christoph Preißner
37+
* @author Mark Paluch
3438
*/
3539
@Configuration
3640
@Profile("mariadb")
3741
class MariaDBDataSourceConfiguration extends DataSourceConfiguration {
3842

39-
private static final MariaDBContainer MARIADB_CONTAINER = new MariaDBContainer().withConfigurationOverride("");
40-
41-
static {
42-
MARIADB_CONTAINER.start();
43-
}
43+
private static MariaDBContainer<?> MARIADB_CONTAINER;
4444

4545
/*
4646
* (non-Javadoc)
@@ -49,6 +49,14 @@ class MariaDBDataSourceConfiguration extends DataSourceConfiguration {
4949
@Override
5050
protected DataSource createDataSource() {
5151

52+
if (MARIADB_CONTAINER == null) {
53+
54+
MariaDBContainer<?> container = new MariaDBContainer<>().withConfigurationOverride("");
55+
container.start();
56+
57+
MARIADB_CONTAINER = container;
58+
}
59+
5260
try {
5361

5462
MariaDbDataSource dataSource = new MariaDbDataSource();
@@ -62,7 +70,12 @@ protected DataSource createDataSource() {
6270
}
6371

6472
@PostConstruct
65-
public void initDatabase() throws SQLException, ScriptException {
66-
ScriptUtils.executeSqlScript(createDataSource().getConnection(), null, "DROP DATABASE test;CREATE DATABASE test;");
73+
public void initDatabase() throws SQLException {
74+
75+
try (Connection connection = createDataSource().getConnection()) {
76+
ScriptUtils.executeSqlScript(connection,
77+
new ByteArrayResource("DROP DATABASE test;CREATE DATABASE test;".getBytes()));
78+
}
6779
}
80+
6881
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/MsSqlDataSourceConfiguration.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
*/
1616
package org.springframework.data.jdbc.testing;
1717

18-
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
18+
import javax.sql.DataSource;
19+
1920
import org.springframework.context.annotation.Configuration;
2021
import org.springframework.context.annotation.Profile;
22+
2123
import org.testcontainers.containers.MSSQLServerContainer;
2224

23-
import javax.sql.DataSource;
25+
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
2426

2527

2628
/**
@@ -29,17 +31,14 @@
2931
* Configuration for a MSSQL Datasource.
3032
*
3133
* @author Thomas Lang
34+
* @author Mark Paluch
3235
* @see <a href="https://github.com/testcontainers/testcontainers-java/tree/master/modules/mssqlserver"></a>
3336
*/
3437
@Configuration
3538
@Profile({"mssql"})
3639
public class MsSqlDataSourceConfiguration extends DataSourceConfiguration {
3740

38-
private static final MSSQLServerContainer mssqlserver = new MSSQLServerContainer();
39-
40-
static {
41-
mssqlserver.start();
42-
}
41+
private static MSSQLServerContainer<?> MSSQL_CONTAINER;
4342

4443
/*
4544
* (non-Javadoc)
@@ -48,10 +47,18 @@ public class MsSqlDataSourceConfiguration extends DataSourceConfiguration {
4847
@Override
4948
protected DataSource createDataSource() {
5049

50+
if (MSSQL_CONTAINER == null) {
51+
52+
MSSQLServerContainer<?> container = new MSSQLServerContainer<>();
53+
container.start();
54+
55+
MSSQL_CONTAINER = container;
56+
}
57+
5158
SQLServerDataSource sqlServerDataSource = new SQLServerDataSource();
52-
sqlServerDataSource.setURL(mssqlserver.getJdbcUrl());
53-
sqlServerDataSource.setUser(mssqlserver.getUsername());
54-
sqlServerDataSource.setPassword(mssqlserver.getPassword());
59+
sqlServerDataSource.setURL(MSSQL_CONTAINER.getJdbcUrl());
60+
sqlServerDataSource.setUser(MSSQL_CONTAINER.getUsername());
61+
sqlServerDataSource.setPassword(MSSQL_CONTAINER.getPassword());
5562
return sqlServerDataSource;
5663
}
5764
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/MySqlDataSourceConfiguration.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,18 @@
1515
*/
1616
package org.springframework.data.jdbc.testing;
1717

18+
import java.sql.Connection;
1819
import java.sql.SQLException;
1920

2021
import javax.annotation.PostConstruct;
21-
import javax.script.ScriptException;
2222
import javax.sql.DataSource;
2323

24-
import org.springframework.context.annotation.Bean;
2524
import org.springframework.context.annotation.Configuration;
2625
import org.springframework.context.annotation.Profile;
27-
import org.springframework.data.relational.core.dialect.Dialect;
28-
import org.springframework.data.relational.core.dialect.MySqlDialect;
26+
import org.springframework.core.io.ByteArrayResource;
27+
import org.springframework.jdbc.datasource.init.ScriptUtils;
28+
2929
import org.testcontainers.containers.MySQLContainer;
30-
import org.testcontainers.jdbc.ext.ScriptUtils;
3130

3231
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
3332

@@ -38,16 +37,13 @@
3837
* @author Jens Schauder
3938
* @author Oliver Gierke
4039
* @author Sedat Gokcen
40+
* @author Mark Paluch
4141
*/
4242
@Configuration
4343
@Profile("mysql")
4444
class MySqlDataSourceConfiguration extends DataSourceConfiguration {
4545

46-
private static final MySQLContainer MYSQL_CONTAINER = new MySQLContainer().withConfigurationOverride("");
47-
48-
static {
49-
MYSQL_CONTAINER.start();
50-
}
46+
private static MySQLContainer<?> MYSQL_CONTAINER;
5147

5248
/*
5349
* (non-Javadoc)
@@ -56,6 +52,14 @@ class MySqlDataSourceConfiguration extends DataSourceConfiguration {
5652
@Override
5753
protected DataSource createDataSource() {
5854

55+
if (MYSQL_CONTAINER == null) {
56+
57+
MySQLContainer<?> container = new MySQLContainer<>().withConfigurationOverride("");
58+
container.start();
59+
60+
MYSQL_CONTAINER = container;
61+
}
62+
5963
MysqlDataSource dataSource = new MysqlDataSource();
6064
dataSource.setUrl(MYSQL_CONTAINER.getJdbcUrl());
6165
dataSource.setUser(MYSQL_CONTAINER.getUsername());
@@ -66,7 +70,11 @@ protected DataSource createDataSource() {
6670
}
6771

6872
@PostConstruct
69-
public void initDatabase() throws SQLException, ScriptException {
70-
ScriptUtils.executeSqlScript(createDataSource().getConnection(), null, "DROP DATABASE test;CREATE DATABASE test;");
73+
public void initDatabase() throws SQLException {
74+
75+
try (Connection connection = createDataSource().getConnection()) {
76+
ScriptUtils.executeSqlScript(connection,
77+
new ByteArrayResource("DROP DATABASE test;CREATE DATABASE test;".getBytes()));
78+
}
7179
}
7280
}

0 commit comments

Comments
 (0)