Skip to content

Commit e404485

Browse files
airwallex-dan-belltomix26
authored andcommitted
Added junit5 Extension (replaces Rule)
1 parent d745fde commit e404485

File tree

4 files changed

+212
-0
lines changed

4 files changed

+212
-0
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@
149149
<scope>provided</scope>
150150
<optional>true</optional>
151151
</dependency>
152+
<dependency>
153+
<groupId>org.junit.jupiter</groupId>
154+
<artifactId>junit-jupiter-api</artifactId>
155+
<version>5.3.2</version>
156+
<scope>provided</scope>
157+
<optional>true</optional>
158+
</dependency>
152159

153160
<dependency>
154161
<groupId>org.slf4j</groupId>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.zonky.test.db.postgres.junit5;
15+
16+
import io.zonky.test.db.postgres.embedded.DatabasePreparer;
17+
import org.junit.rules.TestRule;
18+
19+
public final class EmbeddedPostgresExtension {
20+
21+
private EmbeddedPostgresExtension() {}
22+
23+
/**
24+
* Create a vanilla Postgres cluster -- just initialized, no customizations applied.
25+
*/
26+
public static SingleInstancePostgresExtension singleInstance() {
27+
return new SingleInstancePostgresExtension();
28+
}
29+
30+
/**
31+
* Returns a {@link TestRule} to create a Postgres cluster, shared amongst all test cases in this JVM.
32+
* The rule contributes Config switches to configure each test case to get its own database.
33+
*/
34+
public static PreparedDbExtension preparedDatabase(DatabasePreparer preparer)
35+
{
36+
return new PreparedDbExtension(preparer);
37+
}
38+
39+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.zonky.test.db.postgres.junit5;
15+
16+
import io.zonky.test.db.postgres.embedded.ConnectionInfo;
17+
import io.zonky.test.db.postgres.embedded.DatabasePreparer;
18+
import io.zonky.test.db.postgres.embedded.EmbeddedPostgres;
19+
import io.zonky.test.db.postgres.embedded.PreparedDbProvider;
20+
import org.junit.jupiter.api.extension.AfterAllCallback;
21+
import org.junit.jupiter.api.extension.BeforeAllCallback;
22+
import org.junit.jupiter.api.extension.ExtensionContext;
23+
24+
import javax.sql.DataSource;
25+
import java.util.List;
26+
import java.util.concurrent.CopyOnWriteArrayList;
27+
import java.util.function.Consumer;
28+
29+
public class PreparedDbExtension implements BeforeAllCallback, AfterAllCallback {
30+
31+
private final DatabasePreparer preparer;
32+
private volatile DataSource dataSource;
33+
private volatile PreparedDbProvider provider;
34+
private volatile ConnectionInfo connectionInfo;
35+
36+
private final List<Consumer<EmbeddedPostgres.Builder>> builderCustomizers = new CopyOnWriteArrayList<>();
37+
38+
PreparedDbExtension(DatabasePreparer preparer) {
39+
if (preparer == null) {
40+
throw new IllegalStateException("null preparer");
41+
}
42+
this.preparer = preparer;
43+
}
44+
45+
public PreparedDbExtension customize(Consumer<EmbeddedPostgres.Builder> customizer) {
46+
if (dataSource != null) {
47+
throw new AssertionError("already started");
48+
}
49+
builderCustomizers.add(customizer);
50+
return this;
51+
}
52+
53+
@Override
54+
public void beforeAll(ExtensionContext extensionContext) throws Exception {
55+
provider = PreparedDbProvider.forPreparer(preparer, builderCustomizers);
56+
connectionInfo = provider.createNewDatabase();
57+
dataSource = provider.createDataSourceFromConnectionInfo(connectionInfo);
58+
}
59+
60+
@Override
61+
public void afterAll(ExtensionContext extensionContext) {
62+
dataSource = null;
63+
connectionInfo = null;
64+
provider = null;
65+
}
66+
67+
public DataSource getTestDatabase() {
68+
if (dataSource == null) {
69+
throw new AssertionError("not initialized");
70+
}
71+
return dataSource;
72+
}
73+
74+
public ConnectionInfo getConnectionInfo() {
75+
if (connectionInfo == null) {
76+
throw new AssertionError("not initialized");
77+
}
78+
return connectionInfo;
79+
}
80+
81+
public PreparedDbProvider getDbProvider() {
82+
if (provider == null) {
83+
throw new AssertionError("not initialized");
84+
}
85+
return provider;
86+
}
87+
88+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.zonky.test.db.postgres.junit5;
15+
16+
import io.zonky.test.db.postgres.embedded.EmbeddedPostgres;
17+
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
18+
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
19+
import org.junit.jupiter.api.extension.ExtensionContext;
20+
21+
import java.io.IOException;
22+
import java.sql.Connection;
23+
import java.sql.SQLException;
24+
import java.util.List;
25+
import java.util.concurrent.CopyOnWriteArrayList;
26+
import java.util.function.Consumer;
27+
28+
public class SingleInstancePostgresExtension implements AfterTestExecutionCallback, BeforeTestExecutionCallback {
29+
30+
private volatile EmbeddedPostgres epg;
31+
private volatile Connection postgresConnection;
32+
private final List<Consumer<EmbeddedPostgres.Builder>> builderCustomizers = new CopyOnWriteArrayList<>();
33+
34+
SingleInstancePostgresExtension() { }
35+
36+
@Override
37+
public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
38+
epg = pg();
39+
postgresConnection = epg.getPostgresDatabase().getConnection();
40+
}
41+
42+
private EmbeddedPostgres pg() throws IOException {
43+
final EmbeddedPostgres.Builder builder = EmbeddedPostgres.builder();
44+
builderCustomizers.forEach(c -> c.accept(builder));
45+
return builder.start();
46+
}
47+
48+
public SingleInstancePostgresExtension customize(Consumer<EmbeddedPostgres.Builder> customizer) {
49+
if (epg != null) {
50+
throw new AssertionError("already started");
51+
}
52+
builderCustomizers.add(customizer);
53+
return this;
54+
}
55+
56+
public EmbeddedPostgres getEmbeddedPostgres()
57+
{
58+
EmbeddedPostgres epg = this.epg;
59+
if (epg == null) {
60+
throw new AssertionError("JUnit test not started yet!");
61+
}
62+
return epg;
63+
}
64+
65+
@Override
66+
public void afterTestExecution(ExtensionContext extensionContext) {
67+
try {
68+
postgresConnection.close();
69+
} catch (SQLException e) {
70+
throw new AssertionError(e);
71+
}
72+
try {
73+
epg.close();
74+
} catch (IOException e) {
75+
throw new AssertionError(e);
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)