Skip to content

Commit 69fa2a8

Browse files
committed
#29 - Start a Postgres database in Docker if no local database can be found.
Postgres integration tests now run either with a locally installed and started database or if no such database can be found an instance gets started in a Docker container via Testcontainers.
1 parent 6750415 commit 69fa2a8

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

src/test/java/org/springframework/data/r2dbc/testing/ExternalDatabase.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
import org.junit.AssumptionViolatedException;
2626
import org.junit.rules.ExternalResource;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
2729

2830
/**
2931
* {@link ExternalResource} wrapper to encapsulate {@link ProvidedDatabase} and
@@ -33,6 +35,8 @@
3335
*/
3436
public abstract class ExternalDatabase extends ExternalResource {
3537

38+
private static Logger LOG = LoggerFactory.getLogger(ExternalDatabase.class);
39+
3640
/**
3741
* @return the post of the database service.
3842
*/
@@ -53,16 +57,35 @@ public abstract class ExternalDatabase extends ExternalResource {
5357
*/
5458
public abstract String getUsername();
5559

60+
/**
61+
* Throws an {@link AssumptionViolatedException} if the database cannot be reached.
62+
*/
5663
@Override
5764
protected void before() {
5865

66+
if (!checkValidity()) {
67+
throw new AssumptionViolatedException(
68+
String.format("Cannot connect to %s:%d. Skipping tests.", getHostname(), getPort()));
69+
}
70+
}
71+
72+
/**
73+
* performs a test if the database can actually be reached.
74+
*
75+
* @return true, if the database could be reached.
76+
*/
77+
boolean checkValidity() {
78+
5979
try (Socket socket = new Socket()) {
80+
6081
socket.connect(new InetSocketAddress(getHostname(), getPort()), Math.toIntExact(TimeUnit.SECONDS.toMillis(5)));
82+
return true;
6183

6284
} catch (IOException e) {
63-
throw new AssumptionViolatedException(
64-
String.format("Cannot connect to %s:%d. Skipping tests.", getHostname(), getPort()));
85+
LOG.debug("external database not available.", e);
6586
}
87+
88+
return false;
6689
}
6790

6891
/**

src/test/java/org/springframework/data/r2dbc/testing/PostgresTestSupport.java

+42-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
import org.postgresql.ds.PGSimpleDataSource;
1010
import org.springframework.data.r2dbc.testing.ExternalDatabase.ProvidedDatabase;
11+
import org.testcontainers.containers.PostgreSQLContainer;
1112

1213
/**
1314
* Utility class for testing against Postgres.
1415
*
1516
* @author Mark Paluch
17+
* @author Jens Schauder
1618
*/
1719
public class PostgresTestSupport {
1820

21+
private static final PostgreSQLContainer POSTGRESQL_CONTAINER = new PostgreSQLContainer();
22+
1923
public static String CREATE_TABLE_LEGOSET = "CREATE TABLE legoset (\n" //
2024
+ " id integer CONSTRAINT id PRIMARY KEY,\n" //
2125
+ " name varchar(255) NOT NULL,\n" //
@@ -31,30 +35,60 @@ public class PostgresTestSupport {
3135
public static String INSERT_INTO_LEGOSET = "INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)";
3236

3337
/**
34-
* Returns a locally provided database at {@code postgres:@localhost:5432/postgres}.
38+
* Returns a database either hosted locally at {@code postgres:@localhost:5432/postgres} or running inside Docker.
3539
*
36-
* @return
40+
* @return information about the database. Guaranteed to be not {@literal null}.
3741
*/
3842
public static ExternalDatabase database() {
39-
return local();
43+
44+
ExternalDatabase local = local();
45+
if (local.checkValidity()) {
46+
return local;
47+
} else {
48+
return testContainer();
49+
}
4050
}
4151

4252
/**
4353
* Returns a locally provided database at {@code postgres:@localhost:5432/postgres}.
44-
*
45-
* @return
4654
*/
4755
private static ExternalDatabase local() {
48-
return ProvidedDatabase.builder().hostname("localhost").port(5432).database("postgres").username("postgres")
56+
57+
return ProvidedDatabase.builder() //
58+
.hostname("localhost") //
59+
.port(5432) //
60+
.database("postgres") //
61+
.username("postgres") //
4962
.password("").build();
5063
}
5164

65+
/**
66+
* Returns a database provided via Testcontainers.
67+
*/
68+
private static ExternalDatabase testContainer() {
69+
70+
POSTGRESQL_CONTAINER.start();
71+
72+
return ProvidedDatabase.builder() //
73+
.hostname("localhost") //
74+
.port(POSTGRESQL_CONTAINER.getFirstMappedPort()) //
75+
.database(POSTGRESQL_CONTAINER.getDatabaseName()) //
76+
.username(POSTGRESQL_CONTAINER.getUsername()) //
77+
.password(POSTGRESQL_CONTAINER.getPassword()).build();
78+
}
79+
5280
/**
5381
* Creates a new {@link ConnectionFactory} configured from the {@link ExternalDatabase}..
5482
*/
5583
public static ConnectionFactory createConnectionFactory(ExternalDatabase database) {
56-
return new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder().host(database.getHostname())
57-
.database(database.getDatabase()).username(database.getUsername()).password(database.getPassword()).build());
84+
85+
return new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder() //
86+
.host(database.getHostname()) //
87+
.database(database.getDatabase()) //
88+
.port(database.getPort()) //
89+
.username(database.getUsername()) //
90+
.password(database.getPassword()) //
91+
.build());
5892
}
5993

6094
/**

0 commit comments

Comments
 (0)