Skip to content

Commit c3f53b3

Browse files
authored
Deprecate ambiguous constructors (#2839)
Our constructors for `GenericContainer` and all the classes that inherit from it tend to be a bit inconsistent. In some places, a no-args constructor is favoured, in other places a String parameter is favoured - which can be either a full image name or a tag. This raises confusion, and in the case of an image tag being the parameter, it restricts which images people can easily use. Another problem this raises is when the container class specifies a default tag version: this frequently falls out of date. We're stuck for options: some users (and image maintainers) would like to see newer image versions being used, but this could be a breaking change for existing users. This is especially risky when a major version bump is proposed. This change aims to: - Deprecate 'ambiguous' constructors for containers - any no-args or String-arg constructor gets this treatment. - Introduce a new constructor which accepts a `DockerImageName` object. This class is preferred to a String because its meaning is unambiguous. - Enhance `DockerImageName` with a static factory method and a convenience `withTag` method so that users can easily create and derive new instances. - Update all modules to follow suit
1 parent fd823a1 commit c3f53b3

File tree

181 files changed

+1445
-565
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+1445
-565
lines changed

core/src/main/java/org/testcontainers/DockerClientFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class DockerClientFactory {
6060
TESTCONTAINERS_SESSION_ID_LABEL, SESSION_ID
6161
);
6262

63-
private static final String TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyImage();
63+
private static final String TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyDockerImageName().asCanonicalNameString();
6464
private static DockerClientFactory instance;
6565

6666
// Cached client configuration

core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ class ContainerisedDockerCompose extends GenericContainer<ContainerisedDockerCom
586586

587587
public ContainerisedDockerCompose(List<File> composeFiles, String identifier) {
588588

589-
super(TestcontainersConfiguration.getInstance().getDockerComposeContainerImage());
589+
super(TestcontainersConfiguration.getInstance().getDockerComposeDockerImageName());
590590
addEnv(ENV_PROJECT_NAME, identifier);
591591

592592
// Map the docker compose file into the container

core/src/main/java/org/testcontainers/containers/FixedHostPortGenericContainer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
* not available - which could manifest as flaky or unstable tests.</p>
1313
*/
1414
public class FixedHostPortGenericContainer<SELF extends FixedHostPortGenericContainer<SELF>> extends GenericContainer<SELF> {
15+
16+
/**
17+
* @deprecated it is highly recommended that {@link FixedHostPortGenericContainer} not be used, as it risks port conflicts.
18+
*/
19+
@Deprecated
1520
public FixedHostPortGenericContainer(@NotNull String dockerImageName) {
1621
super(dockerImageName);
1722
}

core/src/main/java/org/testcontainers/containers/GenericContainer.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import com.github.dockerjava.api.model.ContainerNetwork;
1313
import com.github.dockerjava.api.model.ExposedPort;
1414
import com.github.dockerjava.api.model.HostConfig;
15-
import com.github.dockerjava.api.model.Info;
1615
import com.github.dockerjava.api.model.Link;
1716
import com.github.dockerjava.api.model.PortBinding;
1817
import com.github.dockerjava.api.model.Volume;
@@ -55,6 +54,7 @@
5554
import org.testcontainers.lifecycle.TestDescription;
5655
import org.testcontainers.lifecycle.TestLifecycleAware;
5756
import org.testcontainers.utility.Base58;
57+
import org.testcontainers.utility.DockerImageName;
5858
import org.testcontainers.utility.DockerLoggerFactory;
5959
import org.testcontainers.utility.DockerMachineClient;
6060
import org.testcontainers.utility.MountableFile;
@@ -227,10 +227,27 @@ public class GenericContainer<SELF extends GenericContainer<SELF>>
227227
@Setter(AccessLevel.NONE)
228228
private boolean shouldBeReused = false;
229229

230+
231+
public GenericContainer(@NonNull final DockerImageName dockerImageName) {
232+
this.image = new RemoteDockerImage(dockerImageName);
233+
}
234+
235+
public GenericContainer(@NonNull final RemoteDockerImage image) {
236+
this.image = image;
237+
}
238+
239+
/**
240+
* @deprecated use {@link GenericContainer(DockerImageName)} instead
241+
*/
242+
@Deprecated
230243
public GenericContainer() {
231244
this(TestcontainersConfiguration.getInstance().getTinyImage());
232245
}
233246

247+
/**
248+
* @deprecated use {@link GenericContainer(DockerImageName)} instead
249+
*/
250+
@Deprecated
234251
public GenericContainer(@NonNull final String dockerImageName) {
235252
this.setDockerImageName(dockerImageName);
236253
}

core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
public enum PortForwardingContainer {
2020
INSTANCE;
2121

22-
private GenericContainer container;
22+
private GenericContainer<?> container;
2323

2424
private final Set<Entry<Integer, Integer>> exposedPorts = Collections.newSetFromMap(new ConcurrentHashMap<>());
2525

@@ -29,7 +29,7 @@ public enum PortForwardingContainer {
2929
@SneakyThrows
3030
private Connection createSSHSession() {
3131
String password = UUID.randomUUID().toString();
32-
container = new GenericContainer<>(TestcontainersConfiguration.getInstance().getSSHdImage())
32+
container = new GenericContainer<>(TestcontainersConfiguration.getInstance().getSSHdDockerImageName())
3333
.withExposedPorts(22)
3434
.withEnv("PASSWORD", password)
3535
.withCommand(

core/src/main/java/org/testcontainers/containers/SocatContainer.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.testcontainers.containers;
22

33
import org.testcontainers.utility.Base58;
4+
import org.testcontainers.utility.DockerImageName;
45
import org.testcontainers.utility.TestcontainersConfiguration;
56

67
import java.util.HashMap;
@@ -16,7 +17,11 @@ public class SocatContainer extends GenericContainer<SocatContainer> {
1617
private final Map<Integer, String> targets = new HashMap<>();
1718

1819
public SocatContainer() {
19-
super(TestcontainersConfiguration.getInstance().getSocatContainerImage());
20+
this(TestcontainersConfiguration.getInstance().getSocatDockerImageName());
21+
}
22+
23+
public SocatContainer(final DockerImageName dockerImageName) {
24+
super(dockerImageName);
2025
withCreateContainerCmdModifier(it -> it.withEntrypoint("/bin/sh"));
2126
withCreateContainerCmdModifier(it -> it.withName("testcontainers-socat-" + Base58.randomString(8)));
2227
}
@@ -39,4 +44,4 @@ protected void configure() {
3944
.collect(Collectors.joining(" & "))
4045
);
4146
}
42-
}
47+
}

core/src/main/java/org/testcontainers/containers/VncRecordingContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public VncRecordingContainer(@NonNull GenericContainer<?> targetContainer) {
5252
* Create a sidekick container and attach it to another container. The VNC output of that container will be recorded.
5353
*/
5454
public VncRecordingContainer(@NonNull Network network, @NonNull String targetNetworkAlias) throws IllegalStateException {
55-
super(TestcontainersConfiguration.getInstance().getVncRecordedContainerImage());
55+
super(TestcontainersConfiguration.getInstance().getVncDockerImageName());
5656

5757
this.targetNetworkAlias = targetNetworkAlias;
5858
withNetwork(network);

core/src/main/java/org/testcontainers/dockerclient/AuthDelegatingDockerClientConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public AuthConfig effectiveAuthConfig(String imageName) {
4040
}
4141

4242
// try and obtain more accurate auth config using our resolution
43-
final DockerImageName parsed = new DockerImageName(imageName);
43+
final DockerImageName parsed = DockerImageName.parse(imageName);
4444
final AuthConfig effectiveAuthConfig = RegistryAuthLocator.instance()
4545
.lookupAuthConfig(parsed, fallbackAuthConfig);
4646

core/src/main/java/org/testcontainers/images/AbstractImagePullPolicy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public abstract class AbstractImagePullPolicy implements ImagePullPolicy {
1212

1313
@Override
1414
public boolean shouldPull(DockerImageName imageName) {
15-
Logger logger = DockerLoggerFactory.getLogger(imageName.toString());
15+
Logger logger = DockerLoggerFactory.getLogger(imageName.asCanonicalNameString());
1616

1717
// Does our cache already know the image?
1818
ImageData cachedImageData = LOCAL_IMAGES_CACHE.get(imageName);

core/src/main/java/org/testcontainers/images/LocalImagesCache.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public Optional<ImageData> refreshCache(DockerImageName imageName) {
3939

4040
InspectImageResponse response = null;
4141
try {
42-
response = dockerClient.inspectImageCmd(imageName.toString()).exec();
42+
response = dockerClient.inspectImageCmd(imageName.asCanonicalNameString()).exec();
4343
} catch (NotFoundException e) {
4444
log.trace("Image {} not found", imageName, e);
4545
}

0 commit comments

Comments
 (0)