Skip to content

Commit 8c66d21

Browse files
committed
Add TemporaryNetwork Rule
1 parent eeb1c28 commit 8c66d21

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

core/src/test/java/org/testcontainers/containers/NetworkTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.testcontainers.DockerClientFactory;
88
import org.testcontainers.TestImages;
99
import org.testcontainers.junit.vintage.Container;
10+
import org.testcontainers.junit.vintage.TemporaryNetwork;
1011
import org.testcontainers.junit.vintage.Testcontainers;
1112

1213
import static org.assertj.core.api.Assertions.assertThat;
@@ -17,7 +18,7 @@ public class NetworkTest {
1718
public static class WithRules {
1819

1920
@Rule
20-
public Network network = Network.newNetwork();
21+
public TemporaryNetwork network = new TemporaryNetwork(Network.newNetwork());
2122

2223
@Rule
2324
public Testcontainers containers = new Testcontainers(this);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.testcontainers.junit.vintage;
2+
3+
import org.junit.rules.ExternalResource;
4+
import org.testcontainers.containers.Network;
5+
6+
/**
7+
* Integrates {@link Network} with the JUnit4 lifecycle.
8+
*/
9+
public final class TemporaryNetwork extends ExternalResource implements Network {
10+
11+
private final Network network;
12+
13+
private volatile State state = State.BEFORE_RULE;
14+
15+
/**
16+
* Creates an instance.
17+
*
18+
* <p>The passed-in network will be closed when the current test completes.
19+
*
20+
* @param network Network that the rule will delegate to.
21+
*/
22+
public TemporaryNetwork(Network network) {
23+
this.network = network;
24+
}
25+
26+
@Override
27+
public String getId() {
28+
if (state == State.AFTER_RULE) {
29+
throw new IllegalStateException("Cannot reference the network after the test completes");
30+
}
31+
return network.getId();
32+
}
33+
34+
@Override
35+
public void close() {
36+
switch (state) {
37+
case BEFORE_RULE:
38+
throw new IllegalStateException("Cannot close the network before the test starts");
39+
case INSIDE_RULE:
40+
break;
41+
case AFTER_RULE:
42+
throw new IllegalStateException("Cannot reference the network after the test completes");
43+
}
44+
network.close();
45+
}
46+
47+
@Override
48+
protected void before() throws Throwable {
49+
state = State.AFTER_RULE; // Just in case an exception is thrown below.
50+
network.getId(); // This has the side-effect of creating the network.
51+
52+
state = State.INSIDE_RULE;
53+
}
54+
55+
@Override
56+
protected void after() {
57+
state = State.AFTER_RULE;
58+
network.close();
59+
}
60+
61+
private enum State {
62+
BEFORE_RULE,
63+
INSIDE_RULE,
64+
AFTER_RULE,
65+
}
66+
}

modules/junit-vintage/src/main/java/org/testcontainers/junit/vintage/Testcontainers.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,21 @@ private List<Startable> findContainers(Description description) {
119119
if (description.getTestClass() == null) {
120120
return Collections.emptyList();
121121
}
122-
Predicate<Field> isTargetedContainer = isContainer();
122+
Predicate<Field> isTargetedContainerField = isContainerField();
123123
if (testInstance == null) {
124-
isTargetedContainer = isTargetedContainer.and(ModifierSupport::isStatic);
124+
isTargetedContainerField = isTargetedContainerField.and(ModifierSupport::isStatic);
125125
} else {
126-
isTargetedContainer = isTargetedContainer.and(ModifierSupport::isNotStatic);
126+
isTargetedContainerField = isTargetedContainerField.and(ModifierSupport::isNotStatic);
127127
}
128128

129129
return ReflectionSupport
130-
.findFields(description.getTestClass(), isTargetedContainer, HierarchyTraversalMode.TOP_DOWN)
130+
.findFields(description.getTestClass(), isTargetedContainerField, HierarchyTraversalMode.TOP_DOWN)
131131
.stream()
132132
.map(this::getContainerInstance)
133133
.collect(Collectors.toList());
134134
}
135135

136-
private static Predicate<Field> isContainer() {
136+
private static Predicate<Field> isContainerField() {
137137
return field -> {
138138
boolean isAnnotatedWithContainer = AnnotationSupport.isAnnotated(field, Container.class);
139139
if (isAnnotatedWithContainer) {

0 commit comments

Comments
 (0)